From: Cristy Date: Sun, 16 Jul 2017 17:47:52 +0000 (-0400) Subject: https://github.com/ImageMagick/ImageMagick/issues/563 X-Git-Tag: 7.0.6-2~31 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=259340b1fe45d75cc41bdfaab53afeecef7eb504;p=imagemagick https://github.com/ImageMagick/ImageMagick/issues/563 --- diff --git a/MagickCore/cache-private.h b/MagickCore/cache-private.h index 5de32cacd..efcabba6a 100644 --- a/MagickCore/cache-private.h +++ b/MagickCore/cache-private.h @@ -277,7 +277,6 @@ extern MagickPrivate VirtualPixelMethod extern MagickPrivate void CacheComponentTerminus(void), ClonePixelCacheMethods(Cache,const Cache), - *GetPixelCachePixels(Image *,MagickSizeType *,ExceptionInfo *), GetPixelCacheTileSize(const Image *,size_t *,size_t *), GetPixelCacheMethods(CacheMethods *), ResetPixelCacheEpoch(void), diff --git a/MagickCore/cache.c b/MagickCore/cache.c index d70de84ee..aae0e5a4e 100644 --- a/MagickCore/cache.c +++ b/MagickCore/cache.c @@ -1681,43 +1681,6 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone, % % % % % % -% G e t I m a g e P i x e l C a c h e P i x e l s % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% GetImagePixelCachePixels() returns the pixels associated with the image -% pixel cache. -% -% The format of the GetImagePixelCachePixels() method is: -% -% CachePixels GetImagePixelCachePixels(const Image *image, -% MagickSizeType *length) -% -% A description of each parameter follows: -% -% o image: the image. -% -% o length: the length of the pixel cache in bytes. -% -*/ -MagickExport void *GetImagePixelCachePixels(const Image *image, - MagickSizeType *length) -{ - CacheInfo - *magick_restrict cache_info; - - cache_info=(CacheInfo *) image->cache; - *length=cache_info->length; - return(cache_info->pixels); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % + G e t I m a g e P i x e l C a c h e T y p e % % % % % @@ -2106,6 +2069,42 @@ MagickPrivate ColorspaceType GetPixelCacheColorspace(const Cache cache) % % % % % % ++ G e t P i x e l C a c h e F i l e n a m e % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% GetPixelCacheFilename() returns the filename associated with the pixel +% cache. +% +% The format of the GetPixelCacheFilename() method is: +% +% const char *GetPixelCacheFilename(const Image *image) +% +% A description of each parameter follows: +% +% o image: the image. +% +*/ +MagickExport const char *GetPixelCacheFilename(const Image *image) +{ + CacheInfo + *magick_restrict cache_info; + + assert(image != (const Image *) NULL); + assert(image->signature == MagickCoreSignature); + assert(image->cache != (Cache) NULL); + cache_info=(CacheInfo *) image->cache; + assert(cache_info->signature == MagickCoreSignature); + return(cache_info->cache_filename); +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % + G e t P i x e l C a c h e M e t h o d s % % % % % @@ -2213,7 +2212,7 @@ MagickPrivate MagickSizeType GetPixelCacheNexusExtent(const Cache cache, % o exception: return any errors or warnings in this structure. % */ -MagickPrivate void *GetPixelCachePixels(Image *image,MagickSizeType *length, +MagickExport void *GetPixelCachePixels(Image *image,MagickSizeType *length, ExceptionInfo *exception) { CacheInfo @@ -2227,10 +2226,9 @@ MagickPrivate void *GetPixelCachePixels(Image *image,MagickSizeType *length, assert(exception->signature == MagickCoreSignature); cache_info=(CacheInfo *) image->cache; assert(cache_info->signature == MagickCoreSignature); - *length=0; + *length=cache_info->length; if ((cache_info->type != MemoryCache) && (cache_info->type != MapCache)) return((void *) NULL); - *length=cache_info->length; return((void *) cache_info->pixels); } diff --git a/MagickCore/cache.h b/MagickCore/cache.h index 6f7cb795e..ed2f3d362 100644 --- a/MagickCore/cache.h +++ b/MagickCore/cache.h @@ -37,6 +37,9 @@ typedef enum extern MagickExport CacheType GetImagePixelCacheType(const Image *); +extern MagickExport const char + *GetPixelCacheFilename(const Image *); + extern MagickExport const Quantum *GetVirtualPixels(const Image *,const ssize_t,const ssize_t,const size_t, const size_t,ExceptionInfo *) magick_hot_spot, @@ -67,8 +70,8 @@ extern MagickExport Quantum const size_t,ExceptionInfo *) magick_hot_spot; extern MagickExport void - *GetImagePixelCachePixels(const Image *,MagickSizeType *), - *GetAuthenticMetacontent(const Image *); + *GetAuthenticMetacontent(const Image *), + *GetPixelCachePixels(Image *,MagickSizeType *,ExceptionInfo *); #if defined(__cplusplus) || defined(c_plusplus) } diff --git a/coders/mpc.c b/coders/mpc.c index 643e20cd8..b8c02dcc6 100644 --- a/coders/mpc.c +++ b/coders/mpc.c @@ -1135,19 +1135,30 @@ static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image, *property, *value; + int + destination; + MagickBooleanType status; MagickOffsetType - offset, scene; + MagickSizeType + length; + register ssize_t i; size_t depth; + ssize_t + count; + + unsigned char + *pixels; + /* Open persistent cache. */ @@ -1165,7 +1176,6 @@ static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image, (void) CopyMagickString(cache_filename,image->filename,MagickPathExtent); AppendImageFormat("cache",cache_filename); scene=0; - offset=0; do { /* @@ -1519,54 +1529,90 @@ static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image, (void) WriteBlob(image,packet_size*image->colors,colormap); colormap=(unsigned char *) RelinquishMagickMemory(colormap); } - { - int - file; - - MagickSizeType - length; - - register MagickOffsetType - i; - - ssize_t - count; - - unsigned char - *pixels; - - /* - Persistent pixel cache. - */ - pixels=(unsigned char *) GetImagePixelCachePixels(image,&length); - if (pixels == (unsigned char *) NULL) - ThrowWriterException(CacheError,"UnableToPersistPixelCache"); - if (file == -1) - ThrowWriterException(FileOpenError,"UnableToOpenFile"); - file=open_utf8(cache_filename,O_WRONLY | O_CREAT | O_BINARY,S_MODE); - if (file == -1) - ThrowWriterException(CacheError,"UnableToPersistPixelCache"); - count=0; - for (i=0; i < (MagickOffsetType) length; i+=count) + /* + Persistent pixel cache. + */ + destination=open_utf8(cache_filename,O_WRONLY | O_CREAT | O_BINARY,S_MODE); + if (destination == -1) + ThrowWriterException(CacheError,"UnableToPersistPixelCache"); + pixels=(unsigned char *) GetPixelCachePixels(image,&length,exception); + if (pixels == (unsigned char *) NULL) { -#if !defined(MAGICKCORE_HAVE_PWRITE) - count=write(file,pixels+i,(size_t) MagickMin(length-i,(size_t) - SSIZE_MAX)); -#else - count=pwrite(file,pixels+i,(size_t) MagickMin(length-i,(size_t) - SSIZE_MAX),(off_t) i); -#endif - if (count <= 0) + int + source; + + register MagickOffsetType + i; + + size_t + quantum; + + struct stat + file_stats; + + unsigned char + *buffer; + + /* + Persist disk-based pixel cache to disk. + */ + source=open_utf8(GetPixelCacheFilename(image),O_RDONLY | O_BINARY,0); + if (source == -1) + ThrowWriterException(CacheError,"UnableToPersistPixelCache"); + quantum=(size_t) MagickMaxBufferExtent; + if ((fstat(source,&file_stats) == 0) && (file_stats.st_size > 0)) + quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent); + buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer)); + if (buffer == (unsigned char *) NULL) { - count=0; - if (errno != EINTR) - break; + (void) close(source); + ThrowWriterException(CacheError,"UnableToPersistPixelCache"); } + for (i=0; (count=read(source,buffer,quantum)) > 0; ) + { + ssize_t + number_bytes; + + number_bytes=write(destination,buffer,(size_t) count); + if (number_bytes != count) + break; + i+=number_bytes; + } + buffer=(unsigned char *) RelinquishMagickMemory(buffer); + (void) close(destination); + (void) close(source); + if (i < (MagickOffsetType) length) + ThrowWriterException(CacheError,"UnableToPersistPixelCache"); + } + else + { + register MagickOffsetType + i; + + /* + Persist in-memory pixel cache to disk. + */ + count=0; + for (i=0; i < (MagickOffsetType) length; i+=count) + { +#if !defined(MAGICKCORE_HAVE_PWRITE) + count=write(destination,pixels+i,(size_t) MagickMin(length-i,(size_t) + SSIZE_MAX)); +#else + count=pwrite(destination,pixels+i,(size_t) MagickMin(length-i,(size_t) + SSIZE_MAX),(off_t) i); +#endif + if (count <= 0) + { + count=0; + if (errno != EINTR) + break; + } + } + (void) close(destination); + if (i < (MagickOffsetType) length) + ThrowWriterException(CacheError,"UnableToPersistPixelCache"); } - close(file); - if (i < (MagickOffsetType) length) - ThrowWriterException(CacheError,"UnableToPersistPixelCache"); - } if (GetNextImageInList(image) == (Image *) NULL) break; image=SyncNextImageInList(image);