]> granicus.if.org Git - imagemagick/commitdiff
https://github.com/ImageMagick/ImageMagick/issues/563
authorCristy <urban-warrior@imagemagick.org>
Sun, 16 Jul 2017 17:47:52 +0000 (13:47 -0400)
committerCristy <urban-warrior@imagemagick.org>
Sun, 16 Jul 2017 17:47:52 +0000 (13:47 -0400)
MagickCore/cache-private.h
MagickCore/cache.c
MagickCore/cache.h
coders/mpc.c

index 5de32cacd69e102250573c84bb5fb2ce8e8f0393..efcabba6a0033fc3107b9459eafa84a5e00252fd 100644 (file)
@@ -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),
index d70de84ee9d2e90b51eac77a88cfea9ee68c049a..aae0e5a4efb63641713aa1b7b2ccc232bd4e6ae6 100644 (file)
@@ -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);
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%                                                                             %
-%                                                                             %
-%                                                                             %
 +   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);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 +   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);
 }
 \f
index 6f7cb795e20a34abd8de9935f65658b30d36159b..ed2f3d3621203419345ff6bfea4ff685dbd8b37c 100644 (file)
@@ -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)
 }
index 643e20cd831e091d925122ea03704c69460c5dc0..b8c02dcc6c0f37feb89166a111b7756d981728e5 100644 (file)
@@ -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);