]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/cache.c
(no commit message)
[imagemagick] / MagickCore / cache.c
index 89cefd4c69a557ebde806de3030c5595b80cd96d..ac76101ea9ef00ffb4d5e3a19560bd571e463dd3 100644 (file)
@@ -185,7 +185,7 @@ MagickExport Cache AcquirePixelCache(const size_t number_threads)
   CacheInfo
     *cache_info;
 
-  cache_info=(CacheInfo *) AcquireMagickMemory(sizeof(*cache_info));
+  cache_info=(CacheInfo *) AcquireAlignedMemory(1,sizeof(*cache_info));
   if (cache_info == (CacheInfo *) NULL)
     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
   (void) ResetMagickMemory(cache_info,0,sizeof(*cache_info));
@@ -254,7 +254,7 @@ MagickExport NexusInfo **AcquirePixelCacheNexus(const size_t number_threads)
   register ssize_t
     i;
 
-  nexus_info=(NexusInfo **) AcquireQuantumMemory(number_threads,
+  nexus_info=(NexusInfo **) AcquireAlignedMemory(number_threads,
     sizeof(*nexus_info));
   if (nexus_info == (NexusInfo **) NULL)
     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
@@ -782,7 +782,7 @@ static MagickBooleanType DiskToDiskPixelCacheClone(CacheInfo *clone_info,
   */
   if (cache_info->debug != MagickFalse)
     (void) LogMagickEvent(CacheEvent,GetMagickModule(),"disk => disk");
-  blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
+  blob=(unsigned char *) AcquireAlignedMemory(MagickMaxBufferExtent,
     sizeof(*blob));
   if (blob == (unsigned char *) NULL)
     {
@@ -945,10 +945,10 @@ static MagickBooleanType UnoptimizedPixelCacheClone(CacheInfo *clone_info,
          else
            (void) LogMagickEvent(CacheEvent,GetMagickModule(),"disk => disk");
     }
-  length=(size_t) MagickMax(MagickMax(cache_info->pixel_channels,
-    clone_info->pixel_channels)*sizeof(Quantum),MagickMax(
+  length=(size_t) MagickMax(MagickMax(cache_info->number_channels,
+    clone_info->number_channels)*sizeof(Quantum),MagickMax(
     cache_info->metacontent_extent,clone_info->metacontent_extent));
-  blob=(unsigned char *) AcquireQuantumMemory(length,sizeof(*blob));
+  blob=(unsigned char *) AcquireAlignedMemory(length,sizeof(*blob));
   if (blob == (unsigned char *) NULL)
     {
       (void) ThrowMagickException(exception,GetMagickModule(),
@@ -972,7 +972,13 @@ static MagickBooleanType UnoptimizedPixelCacheClone(CacheInfo *clone_info,
     }
   if (clone_info->type == DiskCache)
     {
-      if (OpenPixelCacheOnDisk(clone_info,IOMode) == MagickFalse)
+      if ((cache_info->type == DiskCache) &&
+          (strcmp(cache_info->cache_filename,clone_info->cache_filename) == 0))
+        {
+          (void) ClosePixelCacheOnDisk(clone_info);
+          *clone_info->cache_filename='\0';
+        }
+      if (OpenPixelCacheOnDisk(clone_info,WriteMode) == MagickFalse)
         {
           if (cache_info->type == DiskCache)
             (void) ClosePixelCacheOnDisk(cache_info);
@@ -994,7 +1000,7 @@ static MagickBooleanType UnoptimizedPixelCacheClone(CacheInfo *clone_info,
       /*
         Read a set of pixel channels.
       */
-      length=cache_info->pixel_channels*sizeof(Quantum);
+      length=cache_info->number_channels*sizeof(Quantum);
       if (cache_info->type != DiskCache)
         (void) memcpy(blob,(unsigned char *) cache_info->pixels+cache_offset,
           length);
@@ -1014,14 +1020,13 @@ static MagickBooleanType UnoptimizedPixelCacheClone(CacheInfo *clone_info,
           /*
             Write a set of pixel channels.
           */
-          length=clone_info->pixel_channels*sizeof(Quantum);
+          length=clone_info->number_channels*sizeof(Quantum);
           if (clone_info->type != DiskCache)
             (void) memcpy((unsigned char *) clone_info->pixels+clone_offset,
               blob,length);
           else
             {
-              count=WritePixelCacheRegion(clone_info,clone_offset,length,
-                blob);
+              count=WritePixelCacheRegion(clone_info,clone_offset,length,blob);
               if ((MagickSizeType) count != length)
                 {
                   status=MagickFalse;
@@ -1031,7 +1036,7 @@ static MagickBooleanType UnoptimizedPixelCacheClone(CacheInfo *clone_info,
           clone_offset+=length;
         }
     }
-    length=clone_info->pixel_channels*sizeof(Quantum);
+    length=clone_info->number_channels*sizeof(Quantum);
     (void) ResetMagickMemory(blob,0,length*sizeof(*blob));
     for ( ; x < (ssize_t) clone_info->columns; x++)
     {
@@ -1053,7 +1058,7 @@ static MagickBooleanType UnoptimizedPixelCacheClone(CacheInfo *clone_info,
       clone_offset+=length;
     }
   }
-  length=clone_info->pixel_channels*sizeof(Quantum);
+  length=clone_info->number_channels*sizeof(Quantum);
   (void) ResetMagickMemory(blob,0,length*sizeof(*blob));
   for ( ; y < (ssize_t) clone_info->rows; y++)
   {
@@ -1139,8 +1144,7 @@ static MagickBooleanType UnoptimizedPixelCacheClone(CacheInfo *clone_info,
               blob,length);
           else
             {
-              count=WritePixelCacheRegion(clone_info,clone_offset,length,
-                blob);
+              count=WritePixelCacheRegion(clone_info,clone_offset,length,blob);
               if ((MagickSizeType) count != length)
                 {
                   status=MagickFalse;
@@ -1190,7 +1194,7 @@ static MagickBooleanType ClonePixelCachePixels(CacheInfo *clone_info,
     return(MagickTrue);
   if ((cache_info->columns == clone_info->columns) &&
       (cache_info->rows == clone_info->rows) &&
-      (cache_info->pixel_channels == clone_info->pixel_channels) &&
+      (cache_info->number_channels == clone_info->number_channels) &&
       (cache_info->metacontent_extent == clone_info->metacontent_extent))
     return(OptimizedPixelCacheClone(clone_info,cache_info,exception));
   return(UnoptimizedPixelCacheClone(clone_info,cache_info,exception));
@@ -1478,7 +1482,7 @@ MagickExport NexusInfo **DestroyPixelCacheNexus(NexusInfo **nexus_info,
     if (nexus_info[i]->cache != (Quantum *) NULL)
       RelinquishCacheNexusPixels(nexus_info[i]);
     nexus_info[i]->signature=(~MagickSignature);
-    nexus_info[i]=(NexusInfo *) RelinquishAlignedMemory(nexus_info[i]);
+    nexus_info[i]=(NexusInfo *) RelinquishMagickMemory(nexus_info[i]);
   }
   nexus_info=(NexusInfo **) RelinquishMagickMemory(nexus_info);
   return(nexus_info);
@@ -1632,7 +1636,7 @@ static inline MagickBooleanType IsPixelAuthentic(const CacheInfo *cache_info,
   offset=(MagickOffsetType) nexus_info->region.y*cache_info->columns+
     nexus_info->region.x;
   status=nexus_info->pixels == (cache_info->pixels+offset*
-    cache_info->pixel_channels) ? MagickTrue : MagickFalse;
+    cache_info->number_channels) ? MagickTrue : MagickFalse;
   return(status);
 }
 
@@ -1953,6 +1957,7 @@ MagickExport MagickSizeType GetImageExtent(const Image *image)
 %    o exception: return any errors or warnings in this structure.
 %
 */
+
 static inline MagickBooleanType ValidatePixelCacheMorphology(const Image *image)
 {
   CacheInfo
@@ -1964,9 +1969,10 @@ static inline MagickBooleanType ValidatePixelCacheMorphology(const Image *image)
   cache_info=(CacheInfo *) image->cache;
   if ((image->storage_class != cache_info->storage_class) ||
       (image->colorspace != cache_info->colorspace) ||
+      (image->matte != cache_info->matte) ||
       (image->columns != cache_info->columns) ||
       (image->rows != cache_info->rows) ||
-      (image->pixel_channels != cache_info->pixel_channels) ||
+      (image->number_channels != cache_info->number_channels) ||
       (image->metacontent_extent != cache_info->metacontent_extent) ||
       (cache_info->nexus_info == (NexusInfo **) NULL) ||
       (cache_info->number_threads < GetOpenMPMaximumThreads()))
@@ -1990,7 +1996,7 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone,
     time_limit = 0;
 
   static time_t
-    cache_genesis = 0;
+    cache_timestamp = 0;
 
   status=MagickTrue;
   LockSemaphoreInfo(image->semaphore);
@@ -2020,10 +2026,10 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone,
         Set the exire time in seconds.
       */
       time_limit=GetMagickResourceLimit(TimeResource);
-      cache_genesis=time((time_t *) NULL);
+      cache_timestamp=time((time_t *) NULL);
     }
   if ((time_limit != MagickResourceInfinity) &&
-      ((MagickSizeType) (time((time_t *) NULL)-cache_genesis) >= time_limit))
+      ((MagickSizeType) (time((time_t *) NULL)-cache_timestamp) >= time_limit))
     ThrowFatalException(ResourceLimitFatalError,"TimeLimitExceeded");
   assert(image->cache != (Cache) NULL);
   cache_info=(CacheInfo *) image->cache;
@@ -2054,6 +2060,8 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone,
                 status=ClonePixelCachePixels(clone_info,cache_info,exception);
               if (status != MagickFalse)
                 {
+                  if (cache_info->mode == ReadMode)
+                    cache_info->nexus_info=(NexusInfo **) NULL;
                   destroy=MagickTrue;
                   image->cache=clone_image.cache;
                 }
@@ -2071,7 +2079,7 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone,
       */
       image->taint=MagickTrue;
       image->type=UndefinedType;
-      if (image->colorspace == GRAYColorspace)
+      if (1 && image->colorspace == GRAYColorspace)
         image->colorspace=RGBColorspace;
       if (ValidatePixelCacheMorphology(image) == MagickFalse)
         status=OpenPixelCache(image,IOMode,exception);
@@ -2779,9 +2787,9 @@ MagickExport void GetPixelCacheTileSize(const Image *image,size_t *width,
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   cache_info=(CacheInfo *) image->cache;
   assert(cache_info->signature == MagickSignature);
-  *width=2048UL/(cache_info->pixel_channels*sizeof(Quantum));
+  *width=2048UL/(cache_info->number_channels*sizeof(Quantum));
   if (GetPixelCacheType(image) == DiskCache)
-    *width=8192UL/(cache_info->pixel_channels*sizeof(Quantum));
+    *width=8192UL/(cache_info->number_channels*sizeof(Quantum));
   *height=(*width);
 }
 \f
@@ -2928,8 +2936,8 @@ static const void *GetVirtualMetacontentFromCache(const Image *image)
 %    o nexus_info: the cache nexus to return the meta-content.
 %
 */
-MagickExport const void *GetVirtualMetacontentFromNexus(
-  const Cache cache,NexusInfo *nexus_info)
+MagickExport const void *GetVirtualMetacontentFromNexus(const Cache cache,
+  NexusInfo *nexus_info)
 {
   CacheInfo
     *cache_info;
@@ -3099,19 +3107,19 @@ static inline ssize_t RandomY(RandomInfo *random_info,const size_t rows)
   return((ssize_t) (rows*GetPseudoRandomValue(random_info)));
 }
 
-/*
-  VirtualPixelModulo() computes the remainder of dividing offset by extent.  It
-  returns not only the quotient (tile the offset falls in) but also the positive
-  remainer within that tile such that 0 <= remainder < extent.  This method is
-  essentially a ldiv() using a floored modulo division rather than the normal
-  default truncated modulo division.
-*/
 static inline MagickModulo VirtualPixelModulo(const ssize_t offset,
   const size_t extent)
 {
   MagickModulo
     modulo;
 
+  /*
+    Compute the remainder of dividing offset by extent.  It returns not only
+    the quotient (tile the offset falls in) but also the positive remainer
+    within that tile such that 0 <= remainder < extent.  This method is
+    essentially a ldiv() using a floored modulo division rather than the
+    normal default truncated modulo division.
+  */
   modulo.quotient=offset/(ssize_t) extent;
   if (offset < 0L)
     modulo.quotient--;
@@ -3139,7 +3147,7 @@ MagickExport const Quantum *GetVirtualPixelsFromNexus(const Image *image,
 
   Quantum
     *pixels,
-    *virtual_pixel;
+    virtual_pixel[MaxPixelChannels];
 
   RectangleInfo
     region;
@@ -3154,14 +3162,17 @@ MagickExport const Quantum *GetVirtualPixelsFromNexus(const Image *image,
     *restrict q;
 
   register ssize_t
-    u,
-    v;
+    i,
+    u;
 
   register unsigned char
     *restrict s;
 
+  ssize_t
+    v;
+
   void
-    *virtual_associated_pixel;
+    *virtual_metacontent;
 
   /*
     Acquire pixels.
@@ -3222,8 +3233,9 @@ MagickExport const Quantum *GetVirtualPixelsFromNexus(const Image *image,
         "UnableToGetCacheNexus","`%s'",image->filename);
       return((const Quantum *) NULL);
     }
-  virtual_pixel=(Quantum *) NULL;
-  virtual_associated_pixel=(void *) NULL;
+  (void) ResetMagickMemory(virtual_pixel,0,cache_info->number_channels*
+    sizeof(*virtual_pixel));
+  virtual_metacontent=(void *) NULL;
   switch (virtual_pixel_method)
   {
     case BackgroundVirtualPixelMethod:
@@ -3237,68 +3249,52 @@ MagickExport const Quantum *GetVirtualPixelsFromNexus(const Image *image,
     case HorizontalTileVirtualPixelMethod:
     case VerticalTileVirtualPixelMethod:
     {
-      /*
-        Acquire virtual pixel and associated channels.
-      */
-      virtual_pixel=(Quantum *) AcquireQuantumMemory(
-        cache_info->pixel_channels,sizeof(*virtual_pixel));
-      if (virtual_pixel == (Quantum *) NULL)
-        {
-          virtual_nexus=DestroyPixelCacheNexus(virtual_nexus,1);
-          (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
-            "UnableToGetCacheNexus","`%s'",image->filename);
-          return((const Quantum *) NULL);
-        }
-      (void) ResetMagickMemory(virtual_pixel,0,cache_info->pixel_channels*
-        sizeof(*virtual_pixel));
       if (cache_info->metacontent_extent != 0)
         {
-          virtual_associated_pixel=(void *) AcquireMagickMemory(
+          /*
+            Acquire a metacontent buffer.
+          */
+          virtual_metacontent=(void *) AcquireAlignedMemory(1,
             cache_info->metacontent_extent);
-          if (virtual_associated_pixel == (void *) NULL)
+          if (virtual_metacontent == (void *) NULL)
             {
-              virtual_pixel=(Quantum *) RelinquishMagickMemory(
-                virtual_pixel);
               virtual_nexus=DestroyPixelCacheNexus(virtual_nexus,1);
               (void) ThrowMagickException(exception,GetMagickModule(),
                 CacheError,"UnableToGetCacheNexus","`%s'",image->filename);
               return((const Quantum *) NULL);
             }
-          (void) ResetMagickMemory(virtual_associated_pixel,0,
+          (void) ResetMagickMemory(virtual_metacontent,0,
             cache_info->metacontent_extent);
         }
       switch (virtual_pixel_method)
       {
         case BlackVirtualPixelMethod:
         {
-          SetPixelRed(image,0,virtual_pixel);
-          SetPixelGreen(image,0,virtual_pixel);
-          SetPixelBlue(image,0,virtual_pixel);
+          for (i=0; i < (ssize_t) cache_info->number_channels; i++)
+            SetPixelChannel(image,(PixelChannel) i,0,virtual_pixel);
           SetPixelAlpha(image,OpaqueAlpha,virtual_pixel);
           break;
         }
         case GrayVirtualPixelMethod:
         {
-          SetPixelRed(image,QuantumRange/2,virtual_pixel);
-          SetPixelGreen(image,QuantumRange/2,virtual_pixel);
-          SetPixelBlue(image,QuantumRange/2,virtual_pixel);
+          for (i=0; i < (ssize_t) cache_info->number_channels; i++)
+            SetPixelChannel(image,(PixelChannel) i,QuantumRange/2,
+              virtual_pixel);
           SetPixelAlpha(image,OpaqueAlpha,virtual_pixel);
           break;
         }
         case TransparentVirtualPixelMethod:
         {
-          SetPixelRed(image,0,virtual_pixel);
-          SetPixelGreen(image,0,virtual_pixel);
-          SetPixelBlue(image,0,virtual_pixel);
+          for (i=0; i < (ssize_t) cache_info->number_channels; i++)
+            SetPixelChannel(image,(PixelChannel) i,0,virtual_pixel);
           SetPixelAlpha(image,TransparentAlpha,virtual_pixel);
           break;
         }
         case MaskVirtualPixelMethod:
         case WhiteVirtualPixelMethod:
         {
-          SetPixelRed(image,(Quantum) QuantumRange,virtual_pixel);
-          SetPixelGreen(image,(Quantum) QuantumRange,virtual_pixel);
-          SetPixelBlue(image,(Quantum) QuantumRange,virtual_pixel);
+          for (i=0; i < (ssize_t) cache_info->number_channels; i++)
+            SetPixelChannel(image,(PixelChannel) i,QuantumRange,virtual_pixel);
           SetPixelAlpha(image,OpaqueAlpha,virtual_pixel);
           break;
         }
@@ -3307,6 +3303,8 @@ MagickExport const Quantum *GetVirtualPixelsFromNexus(const Image *image,
           SetPixelRed(image,image->background_color.red,virtual_pixel);
           SetPixelGreen(image,image->background_color.green,virtual_pixel);
           SetPixelBlue(image,image->background_color.blue,virtual_pixel);
+          if (image->colorspace == CMYKColorspace)
+            SetPixelBlack(image,image->background_color.black,virtual_pixel);
           SetPixelAlpha(image,image->background_color.alpha,virtual_pixel);
           break;
         }
@@ -3414,7 +3412,7 @@ MagickExport const Quantum *GetVirtualPixelsFromNexus(const Image *image,
             case WhiteVirtualPixelMethod:
             {
               p=virtual_pixel;
-              r=virtual_associated_pixel;
+              r=virtual_metacontent;
               break;
             }
             case EdgeVirtualPixelMethod:
@@ -3425,7 +3423,7 @@ MagickExport const Quantum *GetVirtualPixelsFromNexus(const Image *image,
               if (((x_modulo.quotient ^ y_modulo.quotient) & 0x01) != 0L)
                 {
                   p=virtual_pixel;
-                  r=virtual_associated_pixel;
+                  r=virtual_metacontent;
                   break;
                 }
               p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,
@@ -3439,7 +3437,7 @@ MagickExport const Quantum *GetVirtualPixelsFromNexus(const Image *image,
               if (((y+v) < 0) || ((y+v) >= (ssize_t) cache_info->rows))
                 {
                   p=virtual_pixel;
-                  r=virtual_associated_pixel;
+                  r=virtual_metacontent;
                   break;
                 }
               x_modulo=VirtualPixelModulo(x+u,cache_info->columns);
@@ -3455,7 +3453,7 @@ MagickExport const Quantum *GetVirtualPixelsFromNexus(const Image *image,
               if (((x+u) < 0) || ((x+u) >= (ssize_t) cache_info->columns))
                 {
                   p=virtual_pixel;
-                  r=virtual_associated_pixel;
+                  r=virtual_metacontent;
                   break;
                 }
               x_modulo=VirtualPixelModulo(x+u,cache_info->columns);
@@ -3469,11 +3467,10 @@ MagickExport const Quantum *GetVirtualPixelsFromNexus(const Image *image,
           }
           if (p == (const Quantum *) NULL)
             break;
-          (void) memcpy(q,p,(size_t) length*cache_info->pixel_channels*
+          (void) memcpy(q,p,(size_t) length*cache_info->number_channels*
             sizeof(*p));
-          q+=cache_info->pixel_channels;
-          if ((s != (void *) NULL) &&
-              (r != (const void *) NULL))
+          q+=cache_info->number_channels;
+          if ((s != (void *) NULL) && (r != (const void *) NULL))
             {
               (void) memcpy(s,r,(size_t) cache_info->metacontent_extent);
               s+=cache_info->metacontent_extent;
@@ -3488,9 +3485,9 @@ MagickExport const Quantum *GetVirtualPixelsFromNexus(const Image *image,
       if (p == (const Quantum *) NULL)
         break;
       r=GetVirtualMetacontentFromNexus(cache_info,*virtual_nexus);
-      (void) memcpy(q,p,(size_t) length*cache_info->pixel_channels*sizeof(*p));
-      q+=length*cache_info->pixel_channels;
-      if ((s != (void *) NULL) && (r != (const void *) NULL))
+      (void) memcpy(q,p,(size_t) length*cache_info->number_channels*sizeof(*p));
+      q+=length*cache_info->number_channels;
+      if ((r != (void *) NULL) && (s != (const void *) NULL))
         {
           (void) memcpy(s,r,(size_t) length);
           s+=length*cache_info->metacontent_extent;
@@ -3500,11 +3497,8 @@ MagickExport const Quantum *GetVirtualPixelsFromNexus(const Image *image,
   /*
     Free resources.
   */
-  if (virtual_associated_pixel != (void *) NULL)
-    virtual_associated_pixel=(void *) RelinquishMagickMemory(
-      virtual_associated_pixel);
-  if (virtual_pixel != (Quantum *) NULL)
-    virtual_pixel=(Quantum *) RelinquishMagickMemory(virtual_pixel);
+  if (virtual_metacontent != (void *) NULL)
+    virtual_metacontent=(void *) RelinquishMagickMemory(virtual_metacontent);
   virtual_nexus=DestroyPixelCacheNexus(virtual_nexus,1);
   return(pixels);
 }
@@ -3929,7 +3923,7 @@ static MagickBooleanType MaskPixelCacheNexus(Image *image,NexusInfo *nexus_info,
 static inline void AllocatePixelCachePixels(CacheInfo *cache_info)
 {
   cache_info->mapped=MagickFalse;
-  cache_info->pixels=(Quantum *) AcquireMagickMemory((size_t)
+  cache_info->pixels=(Quantum *) AcquireAlignedMemory(1,(size_t)
     cache_info->length);
   if (cache_info->pixels == (Quantum *) NULL)
     {
@@ -4003,7 +3997,6 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   if ((image->columns == 0) || (image->rows == 0))
     ThrowBinaryException(CacheError,"NoPixelsDefinedInCache",image->filename);
-  DefinePixelComponentMap(image);
   cache_info=(CacheInfo *) image->cache;
   assert(cache_info->signature == MagickSignature);
   source_info=(*cache_info);
@@ -4012,11 +4005,13 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
     image->filename,(double) GetImageIndexInList(image));
   cache_info->storage_class=image->storage_class;
   cache_info->colorspace=image->colorspace;
-  cache_info->mode=mode;
+  cache_info->matte=image->matte;
   cache_info->rows=image->rows;
   cache_info->columns=image->columns;
-  cache_info->pixel_channels=GetPixelChannels(image);
+  InitializePixelChannelMap(image);
+  cache_info->number_channels=GetPixelChannels(image);
   cache_info->metacontent_extent=image->metacontent_extent;
+  cache_info->mode=mode;
   if (image->ping != MagickFalse)
     {
       cache_info->type=PingCache;
@@ -4026,7 +4021,7 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
       return(MagickTrue);
     }
   number_pixels=(MagickSizeType) cache_info->columns*cache_info->rows;
-  packet_size=cache_info->pixel_channels*sizeof(Quantum);
+  packet_size=cache_info->number_channels*sizeof(Quantum);
   if (image->metacontent_extent != 0)
     packet_size+=cache_info->metacontent_extent;
   length=number_pixels*packet_size;
@@ -4038,7 +4033,7 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
   if ((cache_info->type != UndefinedCache) &&
       (cache_info->columns <= source_info.columns) &&
       (cache_info->rows <= source_info.rows) &&
-      (cache_info->pixel_channels <= source_info.pixel_channels) &&
+      (cache_info->number_channels <= source_info.number_channels) &&
       (cache_info->metacontent_extent <= source_info.metacontent_extent))
     {
       /*
@@ -4046,13 +4041,13 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
       */
       if ((cache_info->columns == source_info.columns) &&
           (cache_info->rows == source_info.rows) &&
-          (cache_info->pixel_channels == source_info.pixel_channels) &&
+          (cache_info->number_channels == source_info.number_channels) &&
           (cache_info->metacontent_extent == source_info.metacontent_extent))
         return(MagickTrue);
       return(ClonePixelCachePixels(cache_info,&source_info,exception));
     }
   status=AcquireMagickResource(AreaResource,cache_info->length);
-  length=number_pixels*(cache_info->pixel_channels*sizeof(Quantum)+
+  length=number_pixels*(cache_info->number_channels*sizeof(Quantum)+
     cache_info->metacontent_extent);
   if ((status != MagickFalse) && (length == (MagickSizeType) ((size_t) length)))
     {
@@ -4077,7 +4072,7 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
                     "open %s (%s memory, %.20gx%.20gx%.20g %s)",
                     cache_info->filename,cache_info->mapped != MagickFalse ?
                     "anonymous" : "heap",(double) cache_info->columns,(double)
-                    cache_info->rows,(double) cache_info->pixel_channels,
+                    cache_info->rows,(double) cache_info->number_channels,
                     format);
                   (void) LogMagickEvent(CacheEvent,GetMagickModule(),"%s",
                     message);
@@ -4086,7 +4081,7 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
               cache_info->metacontent=(void *) NULL;
               if (cache_info->metacontent_extent != 0)
                 cache_info->metacontent=(void *) (cache_info->pixels+
-                  number_pixels*cache_info->pixel_channels);
+                  number_pixels*cache_info->number_channels);
               if (source_info.storage_class != UndefinedClass)
                 {
                   status=ClonePixelCachePixels(cache_info,&source_info,
@@ -4108,12 +4103,6 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
         "CacheResourcesExhausted","`%s'",image->filename);
       return(MagickFalse);
     }
-  if (cache_info->type == DiskCache)
-    {
-      (void) ClosePixelCacheOnDisk(cache_info);
-      *cache_info->cache_filename='\0';
-      status=DiskToDiskPixelCacheClone(cache_info,&source_info,exception);
-    }
   if (OpenPixelCacheOnDisk(cache_info,mode) == MagickFalse)
     {
       RelinquishMagickResource(DiskResource,cache_info->length);
@@ -4129,7 +4118,7 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
         image->filename);
       return(MagickFalse);
     }
-  length=number_pixels*(cache_info->pixel_channels*sizeof(Quantum)+
+  length=number_pixels*(cache_info->number_channels*sizeof(Quantum)+
     cache_info->metacontent_extent);
   status=AcquireMagickResource(AreaResource,cache_info->length);
   if ((status == MagickFalse) || (length != (MagickSizeType) ((size_t) length)))
@@ -4161,7 +4150,7 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
               cache_info->metacontent=(void *) NULL;
               if (cache_info->metacontent_extent != 0)
                 cache_info->metacontent=(void *) (cache_info->pixels+
-                  number_pixels*cache_info->pixel_channels);
+                  number_pixels*cache_info->number_channels);
               if (source_info.storage_class != UndefinedClass)
                 {
                   status=ClonePixelCachePixels(cache_info,&source_info,
@@ -4176,7 +4165,7 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
                     "open %s (%s[%d], memory-mapped, %.20gx%.20gx%.20g %s)",
                     cache_info->filename,cache_info->cache_filename,
                     cache_info->file,(double) cache_info->columns,(double)
-                    cache_info->rows,(double) cache_info->pixel_channels,
+                    cache_info->rows,(double) cache_info->number_channels,
                     format);
                   (void) LogMagickEvent(CacheEvent,GetMagickModule(),"%s",
                     message);
@@ -4199,7 +4188,7 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
         "open %s (%s[%d], disk, %.20gx%.20gx%.20g %s)",cache_info->filename,
         cache_info->cache_filename,cache_info->file,(double)
         cache_info->columns,(double) cache_info->rows,(double)
-        cache_info->pixel_channels,format);
+        cache_info->number_channels,format);
       (void) LogMagickEvent(CacheEvent,GetMagickModule(),"%s",message);
     }
   return(status);
@@ -4290,8 +4279,7 @@ MagickExport MagickBooleanType PersistPixelCache(Image *image,
       (cache_info->reference_count == 1))
     {
       LockSemaphoreInfo(cache_info->semaphore);
-      if ((cache_info->mode != ReadMode) &&
-          (cache_info->type != MemoryCache) &&
+      if ((cache_info->mode != ReadMode) && (cache_info->type != MemoryCache) &&
           (cache_info->reference_count == 1))
         {
           int
@@ -4678,7 +4666,7 @@ static MagickBooleanType ReadPixelCacheMetacontent(CacheInfo *cache_info,
       for (y=0; y < (ssize_t) rows; y++)
       {
         count=ReadPixelCacheRegion(cache_info,cache_info->offset+extent*
-          cache_info->pixel_channels*sizeof(Quantum)+offset*
+          cache_info->number_channels*sizeof(Quantum)+offset*
           cache_info->metacontent_extent,length,(unsigned char *) q);
         if ((MagickSizeType) count != length)
           break;
@@ -4757,7 +4745,7 @@ static MagickBooleanType ReadPixelCachePixels(CacheInfo *cache_info,
     return(MagickTrue);
   offset=(MagickOffsetType) nexus_info->region.y*cache_info->columns+
     nexus_info->region.x;
-  length=(MagickSizeType) nexus_info->region.width*cache_info->pixel_channels*
+  length=(MagickSizeType) nexus_info->region.width*cache_info->number_channels*
     sizeof(Quantum);
   rows=nexus_info->region.height;
   extent=length*rows;
@@ -4779,12 +4767,12 @@ static MagickBooleanType ReadPixelCachePixels(CacheInfo *cache_info,
           length=extent;
           rows=1UL;
         }
-      p=cache_info->pixels+offset*cache_info->pixel_channels;
+      p=cache_info->pixels+offset*cache_info->number_channels;
       for (y=0; y < (ssize_t) rows; y++)
       {
         (void) memcpy(q,p,(size_t) length);
-        p+=cache_info->pixel_channels*cache_info->columns;
-        q+=cache_info->pixel_channels*nexus_info->region.width;
+        p+=cache_info->number_channels*cache_info->columns;
+        q+=cache_info->number_channels*nexus_info->region.width;
       }
       break;
     }
@@ -4808,11 +4796,11 @@ static MagickBooleanType ReadPixelCachePixels(CacheInfo *cache_info,
       for (y=0; y < (ssize_t) rows; y++)
       {
         count=ReadPixelCacheRegion(cache_info,cache_info->offset+offset*
-          cache_info->pixel_channels*sizeof(*q),length,(unsigned char *) q);
+          cache_info->number_channels*sizeof(*q),length,(unsigned char *) q);
         if ((MagickSizeType) count != length)
           break;
         offset+=cache_info->columns;
-        q+=cache_info->pixel_channels*nexus_info->region.width;
+        q+=cache_info->number_channels*nexus_info->region.width;
       }
       if (y < (ssize_t) rows)
         {
@@ -4999,7 +4987,7 @@ static inline MagickBooleanType AcquireCacheNexusPixels(CacheInfo *cache_info,
   if (nexus_info->length != (MagickSizeType) ((size_t) nexus_info->length))
     return(MagickFalse);
   nexus_info->mapped=MagickFalse;
-  nexus_info->cache=(Quantum *) AcquireMagickMemory((size_t)
+  nexus_info->cache=(Quantum *) AcquireAlignedMemory(1,(size_t)
     nexus_info->length);
   if (nexus_info->cache == (Quantum *) NULL)
     {
@@ -5058,7 +5046,7 @@ static Quantum *SetPixelCacheNexusPixels(const Image *image,
           */
           offset=(MagickOffsetType) nexus_info->region.y*cache_info->columns+
             nexus_info->region.x;
-          nexus_info->pixels=cache_info->pixels+cache_info->pixel_channels*
+          nexus_info->pixels=cache_info->pixels+cache_info->number_channels*
             offset;
           nexus_info->metacontent=(void *) NULL;
           if (cache_info->metacontent_extent != 0)
@@ -5072,7 +5060,7 @@ static Quantum *SetPixelCacheNexusPixels(const Image *image,
   */
   number_pixels=(MagickSizeType) nexus_info->region.width*
     nexus_info->region.height;
-  length=number_pixels*cache_info->pixel_channels*sizeof(Quantum);
+  length=number_pixels*cache_info->number_channels*sizeof(Quantum);
   if (cache_info->metacontent_extent != 0)
     length+=number_pixels*cache_info->metacontent_extent;
   if (nexus_info->cache == (Quantum *) NULL)
@@ -5101,7 +5089,7 @@ static Quantum *SetPixelCacheNexusPixels(const Image *image,
   nexus_info->metacontent=(void *) NULL;
   if (cache_info->metacontent_extent != 0)
     nexus_info->metacontent=(void *) (nexus_info->pixels+number_pixels*
-      cache_info->pixel_channels);
+      cache_info->number_channels);
   return(nexus_info->pixels);
 }
 \f
@@ -5330,6 +5318,45 @@ MagickExport MagickBooleanType SyncAuthenticPixels(Image *image,
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%   S y n c I m a g e P i x e l C a c h e                                     %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  SyncImagePixelCache() saves the image pixels to the in-memory or disk cache.
+%  The method returns MagickTrue if the pixel region is flushed, otherwise
+%  MagickFalse.
+%
+%  The format of the SyncImagePixelCache() method is:
+%
+%      MagickBooleanType SyncImagePixelCache(Image *image,
+%        ExceptionInfo *exception)
+%
+%  A description of each parameter follows:
+%
+%    o image: the image.
+%
+%    o exception: return any errors or warnings in this structure.
+%
+*/
+MagickExport MagickBooleanType SyncImagePixelCache(Image *image,
+  ExceptionInfo *exception)
+{
+  CacheInfo
+    *cache_info;
+
+  assert(image != (Image *) NULL);
+  assert(exception != (ExceptionInfo *) NULL);
+  cache_info=(CacheInfo *) GetImagePixelCache(image,MagickTrue,exception);
+  return(cache_info == (CacheInfo *) NULL ? MagickFalse : MagickTrue);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 +   W r i t e P i x e l C a c h e M e t a c o n t e n t                       %
 %                                                                             %
 %                                                                             %
@@ -5432,7 +5459,7 @@ static MagickBooleanType WritePixelCacheMetacontent(CacheInfo *cache_info,
       for (y=0; y < (ssize_t) rows; y++)
       {
         count=WritePixelCacheRegion(cache_info,cache_info->offset+extent*
-          cache_info->pixel_channels*sizeof(Quantum)+offset*
+          cache_info->number_channels*sizeof(Quantum)+offset*
           cache_info->metacontent_extent,length,(const unsigned char *) p);
         if ((MagickSizeType) count != length)
           break;
@@ -5511,7 +5538,7 @@ static MagickBooleanType WritePixelCachePixels(CacheInfo *cache_info,
     return(MagickTrue);
   offset=(MagickOffsetType) nexus_info->region.y*cache_info->columns+
     nexus_info->region.x;
-  length=(MagickSizeType) nexus_info->region.width*cache_info->pixel_channels*
+  length=(MagickSizeType) nexus_info->region.width*cache_info->number_channels*
     sizeof(Quantum);
   rows=nexus_info->region.height;
   extent=length*rows;
@@ -5533,12 +5560,12 @@ static MagickBooleanType WritePixelCachePixels(CacheInfo *cache_info,
           length=extent;
           rows=1UL;
         }
-      q=cache_info->pixels+offset*cache_info->pixel_channels;
+      q=cache_info->pixels+offset*cache_info->number_channels;
       for (y=0; y < (ssize_t) rows; y++)
       {
         (void) memcpy(q,p,(size_t) length);
-        p+=nexus_info->region.width*cache_info->pixel_channels;
-        q+=cache_info->columns*cache_info->pixel_channels;
+        p+=nexus_info->region.width*cache_info->number_channels;
+        q+=cache_info->columns*cache_info->number_channels;
       }
       break;
     }
@@ -5562,11 +5589,11 @@ static MagickBooleanType WritePixelCachePixels(CacheInfo *cache_info,
       for (y=0; y < (ssize_t) rows; y++)
       {
         count=WritePixelCacheRegion(cache_info,cache_info->offset+offset*
-          cache_info->pixel_channels*sizeof(*p),length,(const unsigned char *)
+          cache_info->number_channels*sizeof(*p),length,(const unsigned char *)
           p);
         if ((MagickSizeType) count != length)
           break;
-        p+=nexus_info->region.width*cache_info->pixel_channels;
+        p+=nexus_info->region.width*cache_info->number_channels;
         offset+=cache_info->columns;
       }
       if (y < (ssize_t) rows)