]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/cache.c
(no commit message)
[imagemagick] / MagickCore / cache.c
index 1820a2ca7c2760eb3dddba78529c78fa86cbbb65..204f129f03ed9f1dddf050e671bd168ca9c14c09 100644 (file)
 %                       MagickCore Pixel Cache Methods                        %
 %                                                                             %
 %                              Software Design                                %
-%                                John Cristy                                  %
+%                                   Cristy                                    %
 %                                 July 1999                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
@@ -93,28 +93,6 @@ typedef struct _MagickModulo
     quotient,
     remainder;
 } MagickModulo;
-
-struct _NexusInfo
-{
-  MagickBooleanType
-    mapped;
-
-  RectangleInfo
-    region;
-
-  MagickSizeType
-    length;
-
-  Quantum
-    *cache,
-    *pixels;
-
-  void
-    *metacontent;
-
-  size_t
-    signature;
-};
 \f
 /*
   Forward declarations.
@@ -193,7 +171,7 @@ static SemaphoreInfo
 MagickPrivate Cache AcquirePixelCache(const size_t number_threads)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   char
     *synchronize;
@@ -223,9 +201,9 @@ MagickPrivate Cache AcquirePixelCache(const size_t number_threads)
       cache_info->synchronize=IsStringTrue(synchronize);
       synchronize=DestroyString(synchronize);
     }
-  cache_info->semaphore=AllocateSemaphoreInfo();
+  cache_info->semaphore=AcquireSemaphoreInfo();
   cache_info->reference_count=1;
-  cache_info->file_semaphore=AllocateSemaphoreInfo();
+  cache_info->file_semaphore=AcquireSemaphoreInfo();
   cache_info->debug=IsEventLogging();
   cache_info->signature=MagickSignature;
   return((Cache ) cache_info);
@@ -256,7 +234,7 @@ MagickPrivate Cache AcquirePixelCache(const size_t number_threads)
 MagickPrivate NexusInfo **AcquirePixelCacheNexus(const size_t number_threads)
 {
   NexusInfo
-    **nexus_info;
+    **restrict nexus_info;
 
   register ssize_t
     i;
@@ -310,7 +288,7 @@ MagickPrivate const void *AcquirePixelCachePixels(const Image *image,
   MagickSizeType *length,ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -346,7 +324,8 @@ MagickPrivate const void *AcquirePixelCachePixels(const Image *image,
 */
 MagickPrivate MagickBooleanType CacheComponentGenesis(void)
 {
-  AcquireSemaphoreInfo(&cache_semaphore);
+  if (cache_semaphore == (SemaphoreInfo *) NULL)
+    cache_semaphore=AcquireSemaphoreInfo();
   return(MagickTrue);
 }
 \f
@@ -371,11 +350,11 @@ MagickPrivate MagickBooleanType CacheComponentGenesis(void)
 MagickPrivate void CacheComponentTerminus(void)
 {
   if (cache_semaphore == (SemaphoreInfo *) NULL)
-    AcquireSemaphoreInfo(&cache_semaphore);
+    ActivateSemaphoreInfo(&cache_semaphore);
   LockSemaphoreInfo(cache_semaphore);
   instantiate_cache=MagickFalse;
   UnlockSemaphoreInfo(cache_semaphore);
-  DestroySemaphoreInfo(&cache_semaphore);
+  RelinquishSemaphoreInfo(&cache_semaphore);
 }
 \f
 /*
@@ -403,10 +382,10 @@ MagickPrivate void CacheComponentTerminus(void)
 MagickPrivate Cache ClonePixelCache(const Cache cache)
 {
   CacheInfo
-    *clone_info;
+    *restrict clone_info;
 
   const CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   assert(cache != NULL);
   cache_info=(const CacheInfo *) cache;
@@ -449,8 +428,8 @@ MagickPrivate Cache ClonePixelCache(const Cache cache)
 MagickPrivate void ClonePixelCacheMethods(Cache clone,const Cache cache)
 {
   CacheInfo
-    *cache_info,
-    *source_info;
+    *restrict cache_info,
+    *restrict source_info;
 
   assert(clone != (Cache) NULL);
   source_info=(CacheInfo *) clone;
@@ -492,6 +471,29 @@ MagickPrivate void ClonePixelCacheMethods(Cache clone,const Cache cache)
 %
 */
 
+static inline void CopyPixels(Quantum *destination,const Quantum *source,
+  const MagickSizeType number_pixels)
+{
+#if !defined(MAGICKCORE_OPENMP_SUPPORT) || (MAGICKCORE_QUANTUM_DEPTH <= 8)
+  (void) memcpy(destination,source,(size_t) number_pixels*sizeof(*source));
+#else
+  {
+    register MagickOffsetType
+      i;
+
+    if ((number_pixels*sizeof(*source)) < MagickMaxBufferExtent)
+      {
+        (void) memcpy(destination,source,(size_t) number_pixels*
+          sizeof(*source));
+        return;
+      }
+    #pragma omp parallel for
+    for (i=0; i < (MagickOffsetType) number_pixels; i++)
+      destination[i]=source[i];
+  }
+#endif
+}
+
 static inline MagickSizeType MagickMin(const MagickSizeType x,
   const MagickSizeType y)
 {
@@ -500,8 +502,9 @@ static inline MagickSizeType MagickMin(const MagickSizeType x,
   return(y);
 }
 
-static MagickBooleanType ClonePixelCacheRepository(CacheInfo *clone_info,
-  CacheInfo *cache_info,ExceptionInfo *exception)
+static MagickBooleanType ClonePixelCacheRepository(
+  CacheInfo *restrict clone_info,CacheInfo *restrict cache_info,
+  ExceptionInfo *exception)
 {
 #define MaxCacheThreads  2
 #define cache_threads(source,destination,chunk) \
@@ -514,8 +517,8 @@ static MagickBooleanType ClonePixelCacheRepository(CacheInfo *clone_info,
     status;
 
   NexusInfo
-    **cache_nexus,
-    **clone_nexus;
+    **restrict cache_nexus,
+    **restrict clone_nexus;
 
   size_t
     length;
@@ -537,16 +540,12 @@ static MagickBooleanType ClonePixelCacheRepository(CacheInfo *clone_info,
       (memcmp(cache_info->channel_map,clone_info->channel_map,length) == 0) &&
       (cache_info->metacontent_extent == clone_info->metacontent_extent))
     {
-      /*
-        Identical pixel cache morphology.
-      */
-      (void) memcpy(clone_info->pixels,cache_info->pixels,cache_info->columns*
-        cache_info->number_channels*cache_info->rows*
-        sizeof(*cache_info->pixels));
+      CopyPixels(clone_info->pixels,cache_info->pixels,cache_info->columns*
+        cache_info->number_channels*cache_info->rows);
       if (cache_info->metacontent_extent != 0)
         (void) memcpy(clone_info->metacontent,cache_info->metacontent,
           cache_info->columns*cache_info->rows*clone_info->metacontent_extent*
-          sizeof(*cache_info->metacontent));
+          sizeof(cache_info->metacontent));
       return(MagickTrue);
     }
   /*
@@ -602,6 +601,7 @@ static MagickBooleanType ClonePixelCacheRepository(CacheInfo *clone_info,
       clone_nexus[id],exception);
     if (pixels == (Quantum *) NULL)
       continue;
+    (void) ResetMagickMemory(clone_nexus[id]->pixels,0,clone_nexus[id]->length);
     if (optimize != MagickFalse)
       (void) memcpy(clone_nexus[id]->pixels,cache_nexus[id]->pixels,length*
         sizeof(Quantum));
@@ -688,8 +688,10 @@ static MagickBooleanType ClonePixelCacheRepository(CacheInfo *clone_info,
           clone_nexus[id],exception);
         if (pixels == (Quantum *) NULL)
           continue;
-        (void) memcpy(clone_nexus[id]->metacontent,cache_nexus[id]->metacontent,
-          length*sizeof(*cache_nexus[id]->metacontent));
+        if (clone_nexus[id]->metacontent != (void *) NULL)
+          (void) memcpy(clone_nexus[id]->metacontent,
+            cache_nexus[id]->metacontent,length*
+            sizeof(cache_nexus[id]->metacontent));
         status=WritePixelCacheMetacontent(clone_info,clone_nexus[id],exception);
       }
     }
@@ -766,7 +768,7 @@ static void DestroyImagePixelCache(Image *image)
 MagickExport void DestroyImagePixels(Image *image)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -831,15 +833,17 @@ static inline void RelinquishPixelCachePixels(CacheInfo *cache_info)
         cache_info->pixels=(Quantum *) RelinquishAlignedMemory(
           cache_info->pixels);
       else
-        cache_info->pixels=(Quantum *) UnmapBlob(cache_info->pixels,
-          (size_t) cache_info->length);
+        {
+          (void) UnmapBlob(cache_info->pixels,(size_t) cache_info->length);
+          cache_info->pixels=(Quantum *) NULL;
+        }
       RelinquishMagickResource(MemoryResource,cache_info->length);
       break;
     }
     case MapCache:
     {
-      cache_info->pixels=(Quantum *) UnmapBlob(cache_info->pixels,(size_t)
-        cache_info->length);
+      (void) UnmapBlob(cache_info->pixels,(size_t) cache_info->length);
+      cache_info->pixels=(Quantum *) NULL;
       if (cache_info->mode != ReadMode)
         (void) RelinquishUniqueFileResource(cache_info->cache_filename);
       *cache_info->cache_filename='\0';
@@ -858,7 +862,8 @@ static inline void RelinquishPixelCachePixels(CacheInfo *cache_info)
     case DistributedCache:
     {
       *cache_info->cache_filename='\0';
-      (void) RelinquishDistributePixelCache(cache_info->server_info);
+      (void) RelinquishDistributePixelCache((DistributeCacheInfo *)
+        cache_info->server_info);
       break;
     }
     default:
@@ -872,7 +877,7 @@ static inline void RelinquishPixelCachePixels(CacheInfo *cache_info)
 MagickPrivate Cache DestroyPixelCache(Cache cache)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   assert(cache != (Cache) NULL);
   cache_info=(CacheInfo *) cache;
@@ -899,16 +904,17 @@ MagickPrivate Cache DestroyPixelCache(Cache cache)
     }
   RelinquishPixelCachePixels(cache_info);
   if (cache_info->server_info != (DistributeCacheInfo *) NULL)
-    cache_info->server_info=DestroyDistributeCacheInfo(cache_info->server_info);
+    cache_info->server_info=DestroyDistributeCacheInfo((DistributeCacheInfo *)
+      cache_info->server_info);
   if (cache_info->nexus_info != (NexusInfo **) NULL)
     cache_info->nexus_info=DestroyPixelCacheNexus(cache_info->nexus_info,
       cache_info->number_threads);
   if (cache_info->random_info != (RandomInfo *) NULL)
     cache_info->random_info=DestroyRandomInfo(cache_info->random_info);
   if (cache_info->file_semaphore != (SemaphoreInfo *) NULL)
-    DestroySemaphoreInfo(&cache_info->file_semaphore);
+    RelinquishSemaphoreInfo(&cache_info->file_semaphore);
   if (cache_info->semaphore != (SemaphoreInfo *) NULL)
-    DestroySemaphoreInfo(&cache_info->semaphore);
+    RelinquishSemaphoreInfo(&cache_info->semaphore);
   cache_info->signature=(~MagickSignature);
   cache_info=(CacheInfo *) RelinquishMagickMemory(cache_info);
   cache=(Cache) NULL;
@@ -999,14 +1005,11 @@ MagickPrivate NexusInfo **DestroyPixelCacheNexus(NexusInfo **nexus_info,
 MagickExport void *GetAuthenticMetacontent(const Image *image)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
 
-  void
-    *metacontent;
-
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
   assert(image->cache != (Cache) NULL);
@@ -1015,14 +1018,15 @@ MagickExport void *GetAuthenticMetacontent(const Image *image)
   if (cache_info->methods.get_authentic_metacontent_from_handler !=
       (GetAuthenticMetacontentFromHandler) NULL)
     {
+      void
+        *metacontent;
+
       metacontent=cache_info->methods.
         get_authentic_metacontent_from_handler(image);
       return(metacontent);
     }
   assert(id < (int) cache_info->number_threads);
-  metacontent=GetPixelCacheNexusMetacontent(cache_info,
-    cache_info->nexus_info[id]);
-  return(metacontent);
+  return(cache_info->nexus_info[id]->metacontent);
 }
 \f
 /*
@@ -1052,23 +1056,18 @@ MagickExport void *GetAuthenticMetacontent(const Image *image)
 static void *GetAuthenticMetacontentFromCache(const Image *image)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
 
-  void
-    *metacontent;
-
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
   assert(image->cache != (Cache) NULL);
   cache_info=(CacheInfo *) image->cache;
   assert(cache_info->signature == MagickSignature);
   assert(id < (int) cache_info->number_threads);
-  metacontent=GetPixelCacheNexusMetacontent(image->cache,
-    cache_info->nexus_info[id]);
-  return(metacontent);
+  return(cache_info->nexus_info[id]->metacontent);
 }
 \f
 /*
@@ -1106,53 +1105,35 @@ static void *GetAuthenticMetacontentFromCache(const Image *image)
 %
 */
 
-static inline MagickBooleanType IsPixelAuthentic(
-  const CacheInfo *restrict cache_info,const NexusInfo *restrict nexus_info)
-{
-  MagickBooleanType
-    status;
-
-  MagickOffsetType
-    offset;
-
-  if (cache_info->type == PingCache)
-    return(MagickTrue);
-  offset=(MagickOffsetType) nexus_info->region.y*cache_info->columns+
-    nexus_info->region.x;
-  status=nexus_info->pixels == (cache_info->pixels+offset*
-    cache_info->number_channels) ? MagickTrue : MagickFalse;
-  return(status);
-}
-
-MagickPrivate Quantum *GetAuthenticPixelCacheNexus(Image *image,
-  const ssize_t x,const ssize_t y,const size_t columns,const size_t rows,
-  NexusInfo *nexus_info,ExceptionInfo *exception)
+MagickPrivate Quantum *GetAuthenticPixelCacheNexus(Image *image,const ssize_t x,
+  const ssize_t y,const size_t columns,const size_t rows,NexusInfo *nexus_info,
+  ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   Quantum
-    *q;
+    *restrict pixels;
 
   /*
     Transfer pixels from the cache.
   */
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
-  q=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickTrue,nexus_info,
-    exception);
-  if (q == (Quantum *) NULL)
+  pixels=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickTrue,
+    nexus_info,exception);
+  if (pixels == (Quantum *) NULL)
     return((Quantum *) NULL);
   cache_info=(CacheInfo *) image->cache;
   assert(cache_info->signature == MagickSignature);
-  if (IsPixelAuthentic(cache_info,nexus_info) != MagickFalse)
-    return(q);
+  if (nexus_info->authentic_pixel_cache != MagickFalse)
+    return(pixels);
   if (ReadPixelCachePixels(cache_info,nexus_info,exception) == MagickFalse)
     return((Quantum *) NULL);
   if (cache_info->metacontent_extent != 0)
     if (ReadPixelCacheMetacontent(cache_info,nexus_info,exception) == MagickFalse)
       return((Quantum *) NULL);
-  return(q);
+  return(pixels);
 }
 \f
 /*
@@ -1181,7 +1162,7 @@ MagickPrivate Quantum *GetAuthenticPixelCacheNexus(Image *image,
 static Quantum *GetAuthenticPixelsFromCache(const Image *image)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
@@ -1192,7 +1173,7 @@ static Quantum *GetAuthenticPixelsFromCache(const Image *image)
   cache_info=(CacheInfo *) image->cache;
   assert(cache_info->signature == MagickSignature);
   assert(id < (int) cache_info->number_threads);
-  return(GetPixelCacheNexusPixels(image->cache,cache_info->nexus_info[id]));
+  return(cache_info->nexus_info[id]->pixels);
 }
 \f
 /*
@@ -1222,7 +1203,7 @@ static Quantum *GetAuthenticPixelsFromCache(const Image *image)
 MagickExport Quantum *GetAuthenticPixelQueue(const Image *image)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
@@ -1236,7 +1217,7 @@ MagickExport Quantum *GetAuthenticPixelQueue(const Image *image)
        (GetAuthenticPixelsFromHandler) NULL)
     return(cache_info->methods.get_authentic_pixels_from_handler(image));
   assert(id < (int) cache_info->number_threads);
-  return(GetPixelCacheNexusPixels(cache_info,cache_info->nexus_info[id]));
+  return(cache_info->nexus_info[id]->pixels);
 }
 \f
 /*
@@ -1288,13 +1269,13 @@ MagickExport Quantum *GetAuthenticPixels(Image *image,const ssize_t x,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
 
   Quantum
-    *q;
+    *pixels;
 
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -1304,14 +1285,14 @@ MagickExport Quantum *GetAuthenticPixels(Image *image,const ssize_t x,
   if (cache_info->methods.get_authentic_pixels_handler !=
       (GetAuthenticPixelsHandler) NULL)
     {
-      q=cache_info->methods.get_authentic_pixels_handler(image,x,y,columns,rows,
-        exception);
-      return(q);
+      pixels=cache_info->methods.get_authentic_pixels_handler(image,x,y,columns,
+        rows,exception);
+      return(pixels);
     }
   assert(id < (int) cache_info->number_threads);
-  q=GetAuthenticPixelCacheNexus(image,x,y,columns,rows,
+  pixels=GetAuthenticPixelCacheNexus(image,x,y,columns,rows,
     cache_info->nexus_info[id],exception);
-  return(q);
+  return(pixels);
 }
 \f
 /*
@@ -1350,13 +1331,13 @@ static Quantum *GetAuthenticPixelsCache(Image *image,const ssize_t x,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
 
   Quantum
-    *q;
+    *restrict pixels;
 
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -1366,9 +1347,9 @@ static Quantum *GetAuthenticPixelsCache(Image *image,const ssize_t x,
     return((Quantum *) NULL);
   assert(cache_info->signature == MagickSignature);
   assert(id < (int) cache_info->number_threads);
-  q=GetAuthenticPixelCacheNexus(image,x,y,columns,rows,
+  pixels=GetAuthenticPixelCacheNexus(image,x,y,columns,rows,
     cache_info->nexus_info[id],exception);
-  return(q);
+  return(pixels);
 }
 \f
 /*
@@ -1397,7 +1378,7 @@ static Quantum *GetAuthenticPixelsCache(Image *image,const ssize_t x,
 MagickExport MagickSizeType GetImageExtent(const Image *image)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
@@ -1462,7 +1443,8 @@ static inline MagickBooleanType ValidatePixelCacheMorphology(
   if ((image->storage_class != cache_info->storage_class) ||
       (image->colorspace != cache_info->colorspace) ||
       (image->alpha_trait != cache_info->alpha_trait) ||
-      (image->mask != cache_info->mask) ||
+      (image->read_mask != cache_info->read_mask) ||
+      (image->write_mask != cache_info->write_mask) ||
       (image->columns != cache_info->columns) ||
       (image->rows != cache_info->rows) ||
       (image->number_channels != cache_info->number_channels) ||
@@ -1477,7 +1459,7 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   MagickBooleanType
     destroy,
@@ -1507,7 +1489,12 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone,
     }
   if ((time_limit != MagickResourceInfinity) &&
       ((MagickSizeType) (time((time_t *) NULL)-cache_timestamp) >= time_limit))
-    ThrowFatalException(ResourceLimitFatalError,"TimeLimitExceeded");
+     {
+#if defined(ECANCELED)
+       errno=ECANCELED;
+#endif
+       ThrowFatalException(ResourceLimitFatalError,"TimeLimitExceeded");
+     }
   assert(image->cache != (Cache) NULL);
   cache_info=(CacheInfo *) image->cache;
   destroy=MagickFalse;
@@ -1526,7 +1513,7 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone,
             Clone pixel cache.
           */
           clone_image=(*image);
-          clone_image.semaphore=AllocateSemaphoreInfo();
+          clone_image.semaphore=AcquireSemaphoreInfo();
           clone_image.reference_count=1;
           clone_image.cache=ClonePixelCache(cache_info);
           clone_info=(CacheInfo *) clone_image.cache;
@@ -1544,7 +1531,7 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone,
                   image->cache=clone_image.cache;
                 }
             }
-          DestroySemaphoreInfo(&clone_image.semaphore);
+          RelinquishSemaphoreInfo(&clone_image.semaphore);
         }
       UnlockSemaphoreInfo(cache_info->semaphore);
     }
@@ -1597,7 +1584,7 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone,
 MagickExport CacheType GetImagePixelCacheType(const Image *image)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -1641,7 +1628,7 @@ MagickExport MagickBooleanType GetOneAuthenticPixel(Image *image,
   const ssize_t x,const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   register Quantum
     *restrict q;
@@ -1671,10 +1658,7 @@ MagickExport MagickBooleanType GetOneAuthenticPixel(Image *image,
     }
   for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
   {
-    PixelChannel
-      channel;
-
-    channel=GetPixelChannelChannel(image,i);
+    PixelChannel channel=GetPixelChannelChannel(image,i);
     pixel[channel]=q[i];
   }
   return(MagickTrue);
@@ -1715,7 +1699,7 @@ static MagickBooleanType GetOneAuthenticPixelFromCache(Image *image,
   const ssize_t x,const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
@@ -1746,10 +1730,7 @@ static MagickBooleanType GetOneAuthenticPixelFromCache(Image *image,
     }
   for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
   {
-    PixelChannel
-      channel;
-
-    channel=GetPixelChannelChannel(image,i);
+    PixelChannel channel=GetPixelChannelChannel(image,i);
     pixel[channel]=q[i];
   }
   return(MagickTrue);
@@ -1790,7 +1771,7 @@ MagickExport MagickBooleanType GetOneVirtualPixel(const Image *image,
   const ssize_t x,const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
@@ -1825,10 +1806,7 @@ MagickExport MagickBooleanType GetOneVirtualPixel(const Image *image,
     }
   for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
   {
-    PixelChannel
-      channel;
-
-    channel=GetPixelChannelChannel(image,i);
+    PixelChannel channel=GetPixelChannelChannel(image,i);
     pixel[channel]=p[i];
   }
   return(MagickTrue);
@@ -1873,7 +1851,7 @@ static MagickBooleanType GetOneVirtualPixelFromCache(const Image *image,
   Quantum *pixel,ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
@@ -1904,10 +1882,7 @@ static MagickBooleanType GetOneVirtualPixelFromCache(const Image *image,
     }
   for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
   {
-    PixelChannel
-      channel;
-
-    channel=GetPixelChannelChannel(image,i);
+    PixelChannel channel=GetPixelChannelChannel(image,i);
     pixel[channel]=p[i];
   }
   return(MagickTrue);
@@ -1952,13 +1927,13 @@ MagickExport MagickBooleanType GetOneVirtualPixelInfo(const Image *image,
   PixelInfo *pixel,ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
 
   register const Quantum
-    *p;
+    *restrict p;
 
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -2000,7 +1975,7 @@ MagickExport MagickBooleanType GetOneVirtualPixelInfo(const Image *image,
 MagickPrivate ColorspaceType GetPixelCacheColorspace(const Cache cache)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   assert(cache != (Cache) NULL);
   cache_info=(CacheInfo *) cache;
@@ -2079,10 +2054,10 @@ MagickPrivate void GetPixelCacheMethods(CacheMethods *cache_methods)
 %
 */
 MagickPrivate MagickSizeType GetPixelCacheNexusExtent(const Cache cache,
-  NexusInfo *nexus_info)
+  NexusInfo *restrict nexus_info)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   MagickSizeType
     extent;
@@ -2101,86 +2076,6 @@ MagickPrivate MagickSizeType GetPixelCacheNexusExtent(const Cache cache,
 %                                                                             %
 %                                                                             %
 %                                                                             %
-+   G e t P i x e l C a c h e N e x u s M e t a c o n t e n t                 %
-%                                                                             %
-%                                                                             %
-%                                                                             %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%  GetPixelCacheNexusMetacontent() returns the meta-content for the specified
-%  cache nexus.
-%
-%  The format of the GetPixelCacheNexusMetacontent() method is:
-%
-%      void *GetPixelCacheNexusMetacontent(const Cache cache,
-%        NexusInfo *nexus_info)
-%
-%  A description of each parameter follows:
-%
-%    o cache: the pixel cache.
-%
-%    o nexus_info: the cache nexus to return the meta-content.
-%
-*/
-MagickPrivate void *GetPixelCacheNexusMetacontent(const Cache cache,
-  NexusInfo *nexus_info)
-{
-  CacheInfo
-    *cache_info;
-
-  assert(cache != NULL);
-  cache_info=(CacheInfo *) cache;
-  assert(cache_info->signature == MagickSignature);
-  if (cache_info->storage_class == UndefinedClass)
-    return((void *) NULL);
-  return(nexus_info->metacontent);
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%                                                                             %
-%                                                                             %
-%                                                                             %
-+   G e t P i x e l C a c h e N e x u s P i x e l s                           %
-%                                                                             %
-%                                                                             %
-%                                                                             %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%  GetPixelCacheNexusPixels() returns the pixels associated with the specified
-%  cache nexus.
-%
-%  The format of the GetPixelCacheNexusPixels() method is:
-%
-%      Quantum *GetPixelCacheNexusPixels(const Cache cache,
-%        NexusInfo *nexus_info)
-%
-%  A description of each parameter follows:
-%
-%    o cache: the pixel cache.
-%
-%    o nexus_info: the cache nexus to return the pixels.
-%
-*/
-MagickPrivate Quantum *GetPixelCacheNexusPixels(const Cache cache,
-  NexusInfo *nexus_info)
-{
-  CacheInfo
-    *cache_info;
-
-  assert(cache != NULL);
-  cache_info=(CacheInfo *) cache;
-  assert(cache_info->signature == MagickSignature);
-  if (cache_info->storage_class == UndefinedClass)
-    return((Quantum *) NULL);
-  return(nexus_info->pixels);
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%                                                                             %
-%                                                                             %
-%                                                                             %
 +   G e t P i x e l C a c h e P i x e l s                                     %
 %                                                                             %
 %                                                                             %
@@ -2207,7 +2102,7 @@ MagickPrivate void *GetPixelCachePixels(Image *image,MagickSizeType *length,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -2251,7 +2146,7 @@ MagickPrivate void *GetPixelCachePixels(Image *image,MagickSizeType *length,
 MagickPrivate ClassType GetPixelCacheStorageClass(const Cache cache)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   assert(cache != (Cache) NULL);
   cache_info=(CacheInfo *) cache;
@@ -2293,7 +2188,7 @@ MagickPrivate void GetPixelCacheTileSize(const Image *image,size_t *width,
   size_t *height)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -2334,7 +2229,7 @@ MagickPrivate void GetPixelCacheTileSize(const Image *image,size_t *width,
 MagickPrivate VirtualPixelMethod GetPixelCacheVirtualMethod(const Image *image)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -2370,13 +2265,13 @@ MagickPrivate VirtualPixelMethod GetPixelCacheVirtualMethod(const Image *image)
 static const void *GetVirtualMetacontentFromCache(const Image *image)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
 
   const void
-    *metacontent;
+    *restrict metacontent;
 
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -2416,10 +2311,10 @@ static const void *GetVirtualMetacontentFromCache(const Image *image)
 %
 */
 MagickPrivate const void *GetVirtualMetacontentFromNexus(const Cache cache,
-  NexusInfo *nexus_info)
+  NexusInfo *restrict nexus_info)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   assert(cache != (Cache) NULL);
   cache_info=(CacheInfo *) cache;
@@ -2456,13 +2351,13 @@ MagickPrivate const void *GetVirtualMetacontentFromNexus(const Cache cache,
 MagickExport const void *GetVirtualMetacontent(const Image *image)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
 
   const void
-    *metacontent;
+    *restrict metacontent;
 
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -2608,7 +2503,7 @@ MagickPrivate const Quantum *GetVirtualPixelsFromNexus(const Image *image,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   MagickOffsetType
     offset;
@@ -2618,11 +2513,11 @@ MagickPrivate const Quantum *GetVirtualPixelsFromNexus(const Image *image,
     number_pixels;
 
   NexusInfo
-    **virtual_nexus;
+    **restrict virtual_nexus;
 
   Quantum
-    *pixels,
-    virtual_pixel[CompositePixelChannel];
+    *restrict pixels,
+    virtual_pixel[MaxPixelChannels];
 
   RectangleInfo
     region;
@@ -2647,7 +2542,7 @@ MagickPrivate const Quantum *GetVirtualPixelsFromNexus(const Image *image,
     v;
 
   void
-    *virtual_metacontent;
+    *restrict virtual_metacontent;
 
   /*
     Acquire pixels.
@@ -2683,7 +2578,7 @@ MagickPrivate const Quantum *GetVirtualPixelsFromNexus(const Image *image,
         /*
           Pixel request is inside cache extents.
         */
-        if (IsPixelAuthentic(cache_info,nexus_info) != MagickFalse)
+        if (nexus_info->authentic_pixel_cache != MagickFalse)
           return(q);
         status=ReadPixelCachePixels(cache_info,nexus_info,exception);
         if (status == MagickFalse)
@@ -2699,7 +2594,7 @@ MagickPrivate const Quantum *GetVirtualPixelsFromNexus(const Image *image,
   /*
     Pixel request is outside cache extents.
   */
-  s=(unsigned char *) GetPixelCacheNexusMetacontent(cache_info,nexus_info);
+  s=(unsigned char *) nexus_info->metacontent;
   virtual_nexus=AcquirePixelCacheNexus(1);
   if (virtual_nexus == (NexusInfo **) NULL)
     {
@@ -2796,11 +2691,22 @@ MagickPrivate const Quantum *GetVirtualPixelsFromNexus(const Image *image,
   }
   for (v=0; v < (ssize_t) rows; v++)
   {
+    ssize_t
+      y_offset;
+
+    y_offset=y+v;
+    if ((virtual_pixel_method == EdgeVirtualPixelMethod) ||
+        (virtual_pixel_method == UndefinedVirtualPixelMethod))
+      y_offset=EdgeY(y_offset,cache_info->rows);
     for (u=0; u < (ssize_t) columns; u+=length)
     {
-      length=(MagickSizeType) MagickMin(cache_info->columns-(x+u),columns-u);
-      if ((((x+u) < 0) || ((x+u) >= (ssize_t) cache_info->columns)) ||
-          (((y+v) < 0) || ((y+v) >= (ssize_t) cache_info->rows)) ||
+      ssize_t
+        x_offset;
+
+      x_offset=x+u;
+      length=(MagickSizeType) MagickMin(cache_info->columns-x_offset,columns-u);
+      if (((x_offset < 0) || (x_offset >= (ssize_t) cache_info->columns)) ||
+          ((y_offset < 0) || (y_offset >= (ssize_t) cache_info->rows)) ||
           (length == 0))
         {
           MagickModulo
@@ -2813,11 +2719,13 @@ MagickPrivate const Quantum *GetVirtualPixelsFromNexus(const Image *image,
           length=(MagickSizeType) 1;
           switch (virtual_pixel_method)
           {
+            case EdgeVirtualPixelMethod:
             default:
             {
               p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,
-                EdgeX(x+u,cache_info->columns),EdgeY(y+v,cache_info->rows),
-                1UL,1UL,*virtual_nexus,exception);
+                EdgeX(x_offset,cache_info->columns),
+                EdgeY(y_offset,cache_info->rows),1UL,1UL,*virtual_nexus,
+                exception);
               r=GetVirtualMetacontentFromNexus(cache_info,*virtual_nexus);
               break;
             }
@@ -2835,15 +2743,16 @@ MagickPrivate const Quantum *GetVirtualPixelsFromNexus(const Image *image,
             case DitherVirtualPixelMethod:
             {
               p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,
-                DitherX(x+u,cache_info->columns),DitherY(y+v,cache_info->rows),
-                1UL,1UL,*virtual_nexus,exception);
+                DitherX(x_offset,cache_info->columns),
+                DitherY(y_offset,cache_info->rows),1UL,1UL,*virtual_nexus,
+                exception);
               r=GetVirtualMetacontentFromNexus(cache_info,*virtual_nexus);
               break;
             }
             case TileVirtualPixelMethod:
             {
-              x_modulo=VirtualPixelModulo(x+u,cache_info->columns);
-              y_modulo=VirtualPixelModulo(y+v,cache_info->rows);
+              x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
+              y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
               p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,
                 x_modulo.remainder,y_modulo.remainder,1UL,1UL,*virtual_nexus,
                 exception);
@@ -2852,11 +2761,11 @@ MagickPrivate const Quantum *GetVirtualPixelsFromNexus(const Image *image,
             }
             case MirrorVirtualPixelMethod:
             {
-              x_modulo=VirtualPixelModulo(x+u,cache_info->columns);
+              x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
               if ((x_modulo.quotient & 0x01) == 1L)
                 x_modulo.remainder=(ssize_t) cache_info->columns-
                   x_modulo.remainder-1L;
-              y_modulo=VirtualPixelModulo(y+v,cache_info->rows);
+              y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
               if ((y_modulo.quotient & 0x01) == 1L)
                 y_modulo.remainder=(ssize_t) cache_info->rows-
                   y_modulo.remainder-1L;
@@ -2868,18 +2777,18 @@ MagickPrivate const Quantum *GetVirtualPixelsFromNexus(const Image *image,
             }
             case HorizontalTileEdgeVirtualPixelMethod:
             {
-              x_modulo=VirtualPixelModulo(x+u,cache_info->columns);
+              x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
               p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,
-                x_modulo.remainder,EdgeY(y+v,cache_info->rows),1UL,1UL,
+                x_modulo.remainder,EdgeY(y_offset,cache_info->rows),1UL,1UL,
                 *virtual_nexus,exception);
               r=GetVirtualMetacontentFromNexus(cache_info,*virtual_nexus);
               break;
             }
             case VerticalTileEdgeVirtualPixelMethod:
             {
-              y_modulo=VirtualPixelModulo(y+v,cache_info->rows);
+              y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
               p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,
-                EdgeX(x+u,cache_info->columns),y_modulo.remainder,1UL,1UL,
+                EdgeX(x_offset,cache_info->columns),y_modulo.remainder,1UL,1UL,
                 *virtual_nexus,exception);
               r=GetVirtualMetacontentFromNexus(cache_info,*virtual_nexus);
               break;
@@ -2895,11 +2804,10 @@ MagickPrivate const Quantum *GetVirtualPixelsFromNexus(const Image *image,
               r=virtual_metacontent;
               break;
             }
-            case EdgeVirtualPixelMethod:
             case CheckerTileVirtualPixelMethod:
             {
-              x_modulo=VirtualPixelModulo(x+u,cache_info->columns);
-              y_modulo=VirtualPixelModulo(y+v,cache_info->rows);
+              x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
+              y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
               if (((x_modulo.quotient ^ y_modulo.quotient) & 0x01) != 0L)
                 {
                   p=virtual_pixel;
@@ -2914,14 +2822,14 @@ MagickPrivate const Quantum *GetVirtualPixelsFromNexus(const Image *image,
             }
             case HorizontalTileVirtualPixelMethod:
             {
-              if (((y+v) < 0) || ((y+v) >= (ssize_t) cache_info->rows))
+              if ((y_offset < 0) || (y_offset >= (ssize_t) cache_info->rows))
                 {
                   p=virtual_pixel;
                   r=virtual_metacontent;
                   break;
                 }
-              x_modulo=VirtualPixelModulo(x+u,cache_info->columns);
-              y_modulo=VirtualPixelModulo(y+v,cache_info->rows);
+              x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
+              y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
               p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,
                 x_modulo.remainder,y_modulo.remainder,1UL,1UL,*virtual_nexus,
                 exception);
@@ -2930,14 +2838,14 @@ MagickPrivate const Quantum *GetVirtualPixelsFromNexus(const Image *image,
             }
             case VerticalTileVirtualPixelMethod:
             {
-              if (((x+u) < 0) || ((x+u) >= (ssize_t) cache_info->columns))
+              if ((x_offset < 0) || (x_offset >= (ssize_t) cache_info->columns))
                 {
                   p=virtual_pixel;
                   r=virtual_metacontent;
                   break;
                 }
-              x_modulo=VirtualPixelModulo(x+u,cache_info->columns);
-              y_modulo=VirtualPixelModulo(y+v,cache_info->rows);
+              x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
+              y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
               p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,
                 x_modulo.remainder,y_modulo.remainder,1UL,1UL,*virtual_nexus,
                 exception);
@@ -2960,8 +2868,8 @@ MagickPrivate const Quantum *GetVirtualPixelsFromNexus(const Image *image,
       /*
         Transfer a run of pixels.
       */
-      p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,x+u,y+v,(size_t)
-        length,1UL,*virtual_nexus,exception);
+      p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,x_offset,y_offset,
+        (size_t) length,1UL,*virtual_nexus,exception);
       if (p == (const Quantum *) NULL)
         break;
       r=GetVirtualMetacontentFromNexus(cache_info,*virtual_nexus);
@@ -3022,13 +2930,13 @@ static const Quantum *GetVirtualPixelCache(const Image *image,
   const size_t columns,const size_t rows,ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
 
   const Quantum
-    *p;
+    *restrict p;
 
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -3067,7 +2975,7 @@ static const Quantum *GetVirtualPixelCache(const Image *image,
 MagickExport const Quantum *GetVirtualPixelQueue(const Image *image)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
@@ -3137,13 +3045,13 @@ MagickExport const Quantum *GetVirtualPixels(const Image *image,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
 
   const Quantum
-    *p;
+    *restrict p;
 
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -3186,7 +3094,7 @@ MagickExport const Quantum *GetVirtualPixels(const Image *image,
 static const Quantum *GetVirtualPixelsCache(const Image *image)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
@@ -3227,10 +3135,10 @@ static const Quantum *GetVirtualPixelsCache(const Image *image)
 %
 */
 MagickPrivate const Quantum *GetVirtualPixelsNexus(const Cache cache,
-  NexusInfo *nexus_info)
+  NexusInfo *restrict nexus_info)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   assert(cache != (Cache) NULL);
   cache_info=(CacheInfo *) cache;
@@ -3284,6 +3192,21 @@ static inline void AllocatePixelCachePixels(CacheInfo *cache_info)
     }
 }
 
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#if defined(SIGBUS)
+static void CacheSignalHandler(int status)
+{
+  ThrowFatalException(CacheFatalError,"UnableToExtendPixelCache");
+}
+#endif
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
 static MagickBooleanType OpenPixelCacheOnDisk(CacheInfo *cache_info,
   const MapMode mode)
 {
@@ -3368,7 +3291,7 @@ static inline MagickOffsetType WritePixelCacheRegion(
 static MagickBooleanType SetPixelCacheExtent(Image *image,MagickSizeType length)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   MagickOffsetType
     count,
@@ -3407,6 +3330,9 @@ static MagickBooleanType SetPixelCacheExtent(Image *image,MagickSizeType length)
       if (status != 0)
         return(MagickFalse);
     }
+#endif
+#if defined(SIGBUS)
+  (void) signal(SIGBUS,CacheSignalHandler);
 #endif
   return(count != (MagickOffsetType) 1 ? MagickFalse : MagickTrue);
 }
@@ -3415,7 +3341,7 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info,
+    *restrict cache_info,
     source_info;
 
   char
@@ -3452,7 +3378,8 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
   cache_info->storage_class=image->storage_class;
   cache_info->colorspace=image->colorspace;
   cache_info->alpha_trait=image->alpha_trait;
-  cache_info->mask=image->mask;
+  cache_info->read_mask=image->read_mask;
+  cache_info->write_mask=image->write_mask;
   cache_info->rows=image->rows;
   cache_info->columns=image->columns;
   InitializePixelChannelMap(image);
@@ -3557,9 +3484,10 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
               cache_info->type=DistributedCache;
               cache_info->server_info=server_info;
               (void) FormatLocaleString(cache_info->cache_filename,
-                MaxTextExtent,"%s:%d",
-                GetDistributeCacheHostname(cache_info->server_info),
-                GetDistributeCachePort(cache_info->server_info));
+                MaxTextExtent,"%s:%d",GetDistributeCacheHostname(
+                (DistributeCacheInfo *) cache_info->server_info),
+                GetDistributeCachePort((DistributeCacheInfo *)
+                cache_info->server_info));
               if ((source_info.storage_class != UndefinedClass) &&
                   (mode != ReadMode))
                 {
@@ -3576,15 +3504,17 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
                   (void) FormatLocaleString(message,MaxTextExtent,
                     "open %s (%s[%d], %s, %.20gx%.20gx%.20g %s)",
                     cache_info->filename,cache_info->cache_filename,
-                    GetDistributeCacheFile(cache_info->server_info),type,
-                    (double) cache_info->columns,(double) cache_info->rows,
-                    (double) cache_info->number_channels,format);
+                    GetDistributeCacheFile((DistributeCacheInfo *)
+                    cache_info->server_info),type,(double) cache_info->columns,
+                    (double) cache_info->rows,(double)
+                    cache_info->number_channels,format);
                   (void) LogMagickEvent(CacheEvent,GetMagickModule(),"%s",
                     message);
                 }
               return(MagickTrue);
             }
         }
+      RelinquishMagickResource(DiskResource,cache_info->length);
       (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
         "CacheResourcesExhausted","`%s'",image->filename);
       return(MagickFalse);
@@ -3730,8 +3660,8 @@ MagickExport MagickBooleanType PersistPixelCache(Image *image,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info,
-    *clone_info;
+    *restrict cache_info,
+    *restrict clone_info;
 
   Image
     clone_image;
@@ -3863,7 +3793,7 @@ MagickPrivate Quantum *QueueAuthenticPixelCacheNexus(Image *image,
   const MagickBooleanType clone,NexusInfo *nexus_info,ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   MagickOffsetType
     offset;
@@ -3872,7 +3802,7 @@ MagickPrivate Quantum *QueueAuthenticPixelCacheNexus(Image *image,
     number_pixels;
 
   Quantum
-    *pixels;
+    *restrict pixels;
 
   RectangleInfo
     region;
@@ -3887,13 +3817,8 @@ MagickPrivate Quantum *QueueAuthenticPixelCacheNexus(Image *image,
   if (cache_info == (Cache) NULL)
     return((Quantum *) NULL);
   assert(cache_info->signature == MagickSignature);
-  if ((cache_info->columns == 0) && (cache_info->rows == 0))
-    {
-      (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
-        "NoPixelsDefinedInCache","`%s'",image->filename);
-      return((Quantum *) NULL);
-    }
-  if ((x < 0) || (y < 0) || (x >= (ssize_t) cache_info->columns) ||
+  if ((cache_info->columns == 0) || (cache_info->rows == 0) || (x < 0) ||
+      (y < 0) || (x >= (ssize_t) cache_info->columns) ||
       (y >= (ssize_t) cache_info->rows))
     {
       (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
@@ -3957,13 +3882,13 @@ static Quantum *QueueAuthenticPixelsCache(Image *image,const ssize_t x,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
 
   Quantum
-    *q;
+    *restrict pixels;
 
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -3971,9 +3896,9 @@ static Quantum *QueueAuthenticPixelsCache(Image *image,const ssize_t x,
   cache_info=(CacheInfo *) image->cache;
   assert(cache_info->signature == MagickSignature);
   assert(id < (int) cache_info->number_threads);
-  q=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickFalse,
+  pixels=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickFalse,
     cache_info->nexus_info[id],exception);
-  return(q);
+  return(pixels);
 }
 \f
 /*
@@ -4037,13 +3962,13 @@ MagickExport Quantum *QueueAuthenticPixels(Image *image,const ssize_t x,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
 
   Quantum
-    *q;
+    *restrict pixels;
 
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -4053,14 +3978,14 @@ MagickExport Quantum *QueueAuthenticPixels(Image *image,const ssize_t x,
   if (cache_info->methods.queue_authentic_pixels_handler !=
       (QueueAuthenticPixelsHandler) NULL)
     {
-      q=cache_info->methods.queue_authentic_pixels_handler(image,x,y,columns,
-        rows,exception);
-      return(q);
+      pixels=cache_info->methods.queue_authentic_pixels_handler(image,x,y,
+        columns,rows,exception);
+      return(pixels);
     }
   assert(id < (int) cache_info->number_threads);
-  q=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickFalse,
+  pixels=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickFalse,
     cache_info->nexus_info[id],exception);
-  return(q);
+  return(pixels);
 }
 \f
 /*
@@ -4126,8 +4051,9 @@ static inline MagickOffsetType ReadPixelCacheRegion(
   return(i);
 }
 
-static MagickBooleanType ReadPixelCacheMetacontent(CacheInfo *cache_info,
-  NexusInfo *nexus_info,ExceptionInfo *exception)
+static MagickBooleanType ReadPixelCacheMetacontent(
+  CacheInfo *restrict cache_info,NexusInfo *restrict nexus_info,
+  ExceptionInfo *exception)
 {
   MagickOffsetType
     count,
@@ -4148,7 +4074,7 @@ static MagickBooleanType ReadPixelCacheMetacontent(CacheInfo *cache_info,
 
   if (cache_info->metacontent_extent == 0)
     return(MagickFalse);
-  if (IsPixelAuthentic(cache_info,nexus_info) != MagickFalse)
+  if (nexus_info->authentic_pixel_cache != MagickFalse)
     return(MagickTrue);
   offset=(MagickOffsetType) nexus_info->region.y*cache_info->columns+
     nexus_info->region.x;
@@ -4240,8 +4166,8 @@ static MagickBooleanType ReadPixelCacheMetacontent(CacheInfo *cache_info,
         }
       for (y=0; y < (ssize_t) rows; y++)
       {
-        count=ReadDistributePixelCacheMetacontent(cache_info->server_info,
-          &region,length,(unsigned char *) q);
+        count=ReadDistributePixelCacheMetacontent((DistributeCacheInfo *)
+          cache_info->server_info,&region,length,(unsigned char *) q);
         if (count != (MagickOffsetType) length)
           break;
         q+=cache_info->metacontent_extent*nexus_info->region.width;
@@ -4296,8 +4222,8 @@ static MagickBooleanType ReadPixelCacheMetacontent(CacheInfo *cache_info,
 %    o exception: return any errors or warnings in this structure.
 %
 */
-static MagickBooleanType ReadPixelCachePixels(CacheInfo *cache_info,
-  NexusInfo *nexus_info,ExceptionInfo *exception)
+static MagickBooleanType ReadPixelCachePixels(CacheInfo *restrict cache_info,
+  NexusInfo *restrict nexus_info,ExceptionInfo *exception)
 {
   MagickOffsetType
     count,
@@ -4316,7 +4242,7 @@ static MagickBooleanType ReadPixelCachePixels(CacheInfo *cache_info,
   size_t
     rows;
 
-  if (IsPixelAuthentic(cache_info,nexus_info) != MagickFalse)
+  if (nexus_info->authentic_pixel_cache != MagickFalse)
     return(MagickTrue);
   offset=(MagickOffsetType) nexus_info->region.y*cache_info->columns+
     nexus_info->region.x;
@@ -4405,8 +4331,8 @@ static MagickBooleanType ReadPixelCachePixels(CacheInfo *cache_info,
         }
       for (y=0; y < (ssize_t) rows; y++)
       {
-        count=ReadDistributePixelCachePixels(cache_info->server_info,&region,
-          length,(unsigned char *) q);
+        count=ReadDistributePixelCachePixels((DistributeCacheInfo *)
+          cache_info->server_info,&region,length,(unsigned char *) q);
         if (count != (MagickOffsetType) length)
           break;
         q+=cache_info->number_channels*nexus_info->region.width;
@@ -4459,7 +4385,7 @@ static MagickBooleanType ReadPixelCachePixels(CacheInfo *cache_info,
 MagickPrivate Cache ReferencePixelCache(Cache cache)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   assert(cache != (Cache *) NULL);
   cache_info=(CacheInfo *) cache;
@@ -4497,7 +4423,7 @@ MagickPrivate Cache ReferencePixelCache(Cache cache)
 MagickPrivate void SetPixelCacheMethods(Cache cache,CacheMethods *cache_methods)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   GetOneAuthenticPixelFromHandler
     get_one_authentic_pixel_from_handler;
@@ -4619,6 +4545,27 @@ static inline MagickBooleanType AcquireCacheNexusPixels(
   return(MagickTrue);
 }
 
+static inline MagickBooleanType IsPixelCacheAuthentic(
+  const CacheInfo *restrict cache_info,const NexusInfo *restrict nexus_info)
+{
+  MagickBooleanType
+    status;
+
+  MagickOffsetType
+    offset;
+
+  /*
+    Does nexus pixels point directly to in-core cache pixels or is it buffered?
+  */
+  if (cache_info->type == PingCache)
+    return(MagickTrue);
+  offset=(MagickOffsetType) nexus_info->region.y*cache_info->columns+
+    nexus_info->region.x;
+  status=nexus_info->pixels == (cache_info->pixels+offset*
+    cache_info->number_channels) ? MagickTrue : MagickFalse;
+  return(status);
+}
+
 static inline void PrefetchPixelCacheNexusPixels(const NexusInfo *nexus_info,
   const MapMode mode)
 {
@@ -4675,11 +4622,13 @@ static Quantum *SetPixelCacheNexusPixels(const CacheInfo *cache_info,
             nexus_info->metacontent=(unsigned char *) cache_info->metacontent+
               offset*cache_info->metacontent_extent;
           PrefetchPixelCacheNexusPixels(nexus_info,mode);
+          nexus_info->authentic_pixel_cache=IsPixelCacheAuthentic(cache_info,
+            nexus_info);
           return(nexus_info->pixels);
         }
     }
   /*
-    Pixels are stored in a cache region until they are synced to the cache.
+    Pixels are stored in a staging region until they are synced to the cache.
   */
   number_pixels=(MagickSizeType) nexus_info->region.width*
     nexus_info->region.height;
@@ -4697,7 +4646,7 @@ static Quantum *SetPixelCacheNexusPixels(const CacheInfo *cache_info,
         }
     }
   else
-    if (nexus_info->length != length)
+    if (nexus_info->length < length)
       {
         RelinquishCacheNexusPixels(nexus_info);
         nexus_info->length=length;
@@ -4714,6 +4663,8 @@ static Quantum *SetPixelCacheNexusPixels(const CacheInfo *cache_info,
     nexus_info->metacontent=(void *) (nexus_info->pixels+number_pixels*
       cache_info->number_channels);
   PrefetchPixelCacheNexusPixels(nexus_info,mode);
+  nexus_info->authentic_pixel_cache=IsPixelCacheAuthentic(cache_info,
+    nexus_info);
   return(nexus_info->pixels);
 }
 \f
@@ -4751,10 +4702,10 @@ static MagickBooleanType SetCacheAlphaChannel(Image *image,const Quantum alpha,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   CacheView
-    *image_view;
+    *restrict image_view;
 
   MagickBooleanType
     status;
@@ -4807,7 +4758,7 @@ MagickPrivate VirtualPixelMethod SetPixelCacheVirtualMethod(Image *image,
   const VirtualPixelMethod virtual_pixel_method,ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   VirtualPixelMethod
     method;
@@ -4831,7 +4782,7 @@ MagickPrivate VirtualPixelMethod SetPixelCacheVirtualMethod(Image *image,
           (void) SetCacheAlphaChannel(image,OpaqueAlpha,exception);
         if ((IsPixelInfoGray(&image->background_color) == MagickFalse) &&
             (IsGrayColorspace(image->colorspace) != MagickFalse))
-          (void) TransformImageColorspace(image,RGBColorspace,exception);
+          (void) SetImageColorspace(image,sRGBColorspace,exception);
         break;
       }
       case TransparentVirtualPixelMethod:
@@ -4876,10 +4827,10 @@ MagickPrivate VirtualPixelMethod SetPixelCacheVirtualMethod(Image *image,
 %
 */
 MagickPrivate MagickBooleanType SyncAuthenticPixelCacheNexus(Image *image,
-  NexusInfo *nexus_info,ExceptionInfo *exception)
+  NexusInfo *restrict nexus_info,ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   MagickBooleanType
     status;
@@ -4895,7 +4846,7 @@ MagickPrivate MagickBooleanType SyncAuthenticPixelCacheNexus(Image *image,
   assert(cache_info->signature == MagickSignature);
   if (cache_info->type == UndefinedCache)
     return(MagickFalse);
-  if (IsPixelAuthentic(cache_info,nexus_info) != MagickFalse)
+  if (nexus_info->authentic_pixel_cache != MagickFalse)
     return(MagickTrue);
   assert(cache_info->signature == MagickSignature);
   status=WritePixelCachePixels(cache_info,nexus_info,exception);
@@ -4936,7 +4887,7 @@ static MagickBooleanType SyncAuthenticPixelsCache(Image *image,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
@@ -4986,7 +4937,7 @@ MagickExport MagickBooleanType SyncAuthenticPixels(Image *image,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
@@ -5043,7 +4994,7 @@ MagickPrivate MagickBooleanType SyncImagePixelCache(Image *image,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   assert(image != (Image *) NULL);
   assert(exception != (ExceptionInfo *) NULL);
@@ -5080,7 +5031,7 @@ MagickPrivate MagickBooleanType SyncImagePixelCache(Image *image,
 %
 */
 static MagickBooleanType WritePixelCacheMetacontent(CacheInfo *cache_info,
-  NexusInfo *nexus_info,ExceptionInfo *exception)
+  NexusInfo *restrict nexus_info,ExceptionInfo *exception)
 {
   MagickOffsetType
     count,
@@ -5101,7 +5052,7 @@ static MagickBooleanType WritePixelCacheMetacontent(CacheInfo *cache_info,
 
   if (cache_info->metacontent_extent == 0)
     return(MagickFalse);
-  if (IsPixelAuthentic(cache_info,nexus_info) != MagickFalse)
+  if (nexus_info->authentic_pixel_cache != MagickFalse)
     return(MagickTrue);
   offset=(MagickOffsetType) nexus_info->region.y*cache_info->columns+
     nexus_info->region.x;
@@ -5193,8 +5144,8 @@ static MagickBooleanType WritePixelCacheMetacontent(CacheInfo *cache_info,
         }
       for (y=0; y < (ssize_t) rows; y++)
       {
-        count=WriteDistributePixelCacheMetacontent(cache_info->server_info,
-          &region,length,(const unsigned char *) p);
+        count=WriteDistributePixelCacheMetacontent((DistributeCacheInfo *)
+          cache_info->server_info,&region,length,(const unsigned char *) p);
         if (count != (MagickOffsetType) length)
           break;
         p+=cache_info->metacontent_extent*nexus_info->region.width;
@@ -5249,8 +5200,8 @@ static MagickBooleanType WritePixelCacheMetacontent(CacheInfo *cache_info,
 %    o exception: return any errors or warnings in this structure.
 %
 */
-static MagickBooleanType WritePixelCachePixels(CacheInfo *cache_info,
-  NexusInfo *nexus_info,ExceptionInfo *exception)
+static MagickBooleanType WritePixelCachePixels(CacheInfo *restrict cache_info,
+  NexusInfo *restrict nexus_info,ExceptionInfo *exception)
 {
   MagickOffsetType
     count,
@@ -5269,7 +5220,7 @@ static MagickBooleanType WritePixelCachePixels(CacheInfo *cache_info,
   size_t
     rows;
 
-  if (IsPixelAuthentic(cache_info,nexus_info) != MagickFalse)
+  if (nexus_info->authentic_pixel_cache != MagickFalse)
     return(MagickTrue);
   offset=(MagickOffsetType) nexus_info->region.y*cache_info->columns+
     nexus_info->region.x;
@@ -5359,8 +5310,8 @@ static MagickBooleanType WritePixelCachePixels(CacheInfo *cache_info,
         }
       for (y=0; y < (ssize_t) rows; y++)
       {
-        count=WriteDistributePixelCachePixels(cache_info->server_info,&region,
-          length,(const unsigned char *) p);
+        count=WriteDistributePixelCachePixels((DistributeCacheInfo *)
+          cache_info->server_info,&region,length,(const unsigned char *) p);
         if (count != (MagickOffsetType) length)
           break;
         p+=cache_info->number_channels*nexus_info->region.width;