]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/cache.c
(no commit message)
[imagemagick] / MagickCore / cache.c
index d8a27b7d5c53e907f1a5d05f1ffe7286f7f4ce48..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  %
@@ -48,6 +48,7 @@
 #include "MagickCore/color-private.h"
 #include "MagickCore/colorspace-private.h"
 #include "MagickCore/composite-private.h"
+#include "MagickCore/distribute-cache-private.h"
 #include "MagickCore/exception.h"
 #include "MagickCore/exception-private.h"
 #include "MagickCore/geometry.h"
@@ -57,6 +58,7 @@
 #include "MagickCore/memory_.h"
 #include "MagickCore/memory-private.h"
 #include "MagickCore/nt-base-private.h"
+#include "MagickCore/option.h"
 #include "MagickCore/pixel.h"
 #include "MagickCore/pixel-accessor.h"
 #include "MagickCore/policy.h"
@@ -91,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.
@@ -139,19 +119,19 @@ static MagickBooleanType
   GetOneVirtualPixelFromCache(const Image *,const VirtualPixelMethod,
     const ssize_t,const ssize_t,Quantum *,ExceptionInfo *),
   OpenPixelCache(Image *,const MapMode,ExceptionInfo *),
-  ReadPixelCacheMetacontent(CacheInfo *,NexusInfo *,ExceptionInfo *),
   ReadPixelCachePixels(CacheInfo *,NexusInfo *,ExceptionInfo *),
+  ReadPixelCacheMetacontent(CacheInfo *,NexusInfo *,ExceptionInfo *),
   SyncAuthenticPixelsCache(Image *,ExceptionInfo *),
-  WritePixelCacheMetacontent(CacheInfo *,NexusInfo *,ExceptionInfo *),
-  WritePixelCachePixels(CacheInfo *,NexusInfo *,ExceptionInfo *);
+  WritePixelCachePixels(CacheInfo *,NexusInfo *,ExceptionInfo *),
+  WritePixelCacheMetacontent(CacheInfo *,NexusInfo *,ExceptionInfo *);
 
 static Quantum
   *GetAuthenticPixelsCache(Image *,const ssize_t,const ssize_t,const size_t,
     const size_t,ExceptionInfo *),
   *QueueAuthenticPixelsCache(Image *,const ssize_t,const ssize_t,const size_t,
     const size_t,ExceptionInfo *),
-  *SetPixelCacheNexusPixels(const Image *,const MapMode,const RectangleInfo *,
-    NexusInfo *,ExceptionInfo *) magick_hot_spot;
+  *SetPixelCacheNexusPixels(const CacheInfo *,const MapMode,
+    const RectangleInfo *,NexusInfo *,ExceptionInfo *) magick_hot_spot;
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }
@@ -191,7 +171,7 @@ static SemaphoreInfo
 MagickPrivate Cache AcquirePixelCache(const size_t number_threads)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   char
     *synchronize;
@@ -221,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);
@@ -254,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;
@@ -308,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);
@@ -344,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
@@ -369,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
 /*
@@ -401,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;
@@ -424,17 +405,60 @@ MagickPrivate Cache ClonePixelCache(const Cache cache)
 %                                                                             %
 %                                                                             %
 %                                                                             %
-+   C l o n e P i x e l C a c h e P i x e l s                                 %
++   C l o n e P i x e l C a c h e M e t h o d s                               %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  ClonePixelCacheMethods() clones the pixel cache methods from one cache to
+%  another.
+%
+%  The format of the ClonePixelCacheMethods() method is:
+%
+%      void ClonePixelCacheMethods(Cache clone,const Cache cache)
+%
+%  A description of each parameter follows:
+%
+%    o clone: Specifies a pointer to a Cache structure.
+%
+%    o cache: the pixel cache.
+%
+*/
+MagickPrivate void ClonePixelCacheMethods(Cache clone,const Cache cache)
+{
+  CacheInfo
+    *restrict cache_info,
+    *restrict source_info;
+
+  assert(clone != (Cache) NULL);
+  source_info=(CacheInfo *) clone;
+  assert(source_info->signature == MagickSignature);
+  if (source_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
+      source_info->filename);
+  assert(cache != (Cache) NULL);
+  cache_info=(CacheInfo *) cache;
+  assert(cache_info->signature == MagickSignature);
+  source_info->methods=cache_info->methods;
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
++   C l o n e P i x e l C a c h e R e p o s i t o r y                         %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %
-%  ClonePixelCachePixels() clones the source pixel cache to the destination
+%  ClonePixelCacheRepository() clones the source pixel cache to the destination
 %  cache.
 %
-%  The format of the ClonePixelCachePixels() method is:
+%  The format of the ClonePixelCacheRepository() method is:
 %
-%      MagickBooleanType ClonePixelCachePixels(CacheInfo *cache_info,
+%      MagickBooleanType ClonePixelCacheRepository(CacheInfo *cache_info,
 %        CacheInfo *source_info,ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
@@ -447,27 +471,27 @@ MagickPrivate Cache ClonePixelCache(const Cache cache)
 %
 */
 
-static MagickBooleanType ClosePixelCacheOnDisk(CacheInfo *cache_info)
+static inline void CopyPixels(Quantum *destination,const Quantum *source,
+  const MagickSizeType number_pixels)
 {
-  int
-    status;
-
-  status=(-1);
-  if (cache_info->file != -1)
-    {
-      status=close(cache_info->file);
-      cache_info->file=(-1);
-      RelinquishMagickResource(FileResource,1);
-    }
-  return(status == -1 ? MagickFalse : MagickTrue);
-}
+#if !defined(MAGICKCORE_OPENMP_SUPPORT) || (MAGICKCORE_QUANTUM_DEPTH <= 8)
+  (void) memcpy(destination,source,(size_t) number_pixels*sizeof(*source));
+#else
+  {
+    register MagickOffsetType
+      i;
 
-static inline MagickSizeType MagickMax(const MagickSizeType x,
-  const MagickSizeType y)
-{
-  if (x > y)
-    return(x);
-  return(y);
+    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,
@@ -478,281 +502,23 @@ static inline MagickSizeType MagickMin(const MagickSizeType x,
   return(y);
 }
 
-static MagickBooleanType OpenPixelCacheOnDisk(CacheInfo *cache_info,
-  const MapMode mode)
-{
-  int
-    file;
-
-  /*
-    Open pixel cache on disk.
-  */
-  if (cache_info->file != -1)
-    return(MagickTrue);  /* cache already open */
-  if (*cache_info->cache_filename == '\0')
-    file=AcquireUniqueFileResource(cache_info->cache_filename);
-  else
-    switch (mode)
-    {
-      case ReadMode:
-      {
-        file=open_utf8(cache_info->cache_filename,O_RDONLY | O_BINARY,0);
-        break;
-      }
-      case WriteMode:
-      {
-        file=open_utf8(cache_info->cache_filename,O_WRONLY | O_CREAT |
-          O_BINARY | O_EXCL,S_MODE);
-        if (file == -1)
-          file=open_utf8(cache_info->cache_filename,O_WRONLY | O_BINARY,S_MODE);
-        break;
-      }
-      case IOMode:
-      default:
-      {
-        file=open_utf8(cache_info->cache_filename,O_RDWR | O_CREAT | O_BINARY |
-          O_EXCL,S_MODE);
-        if (file == -1)
-          file=open_utf8(cache_info->cache_filename,O_RDWR | O_BINARY,S_MODE);
-        break;
-      }
-    }
-  if (file == -1)
-    return(MagickFalse);
-  (void) AcquireMagickResource(FileResource,1);
-  cache_info->file=file;
-  cache_info->mode=mode;
-  return(MagickTrue);
-}
-
-static inline MagickOffsetType ReadPixelCacheRegion(
-  const CacheInfo *restrict cache_info,const MagickOffsetType offset,
-  const MagickSizeType length,unsigned char *restrict buffer)
-{
-  register MagickOffsetType
-    i;
-
-  ssize_t
-    count;
-
-#if !defined(MAGICKCORE_HAVE_PREAD)
-  if (lseek(cache_info->file,offset,SEEK_SET) < 0)
-    return((MagickOffsetType) -1);
-#endif
-  count=0;
-  for (i=0; i < (MagickOffsetType) length; i+=count)
-  {
-#if !defined(MAGICKCORE_HAVE_PREAD)
-    count=read(cache_info->file,buffer+i,(size_t) MagickMin(length-i,
-      (MagickSizeType) SSIZE_MAX));
-#else
-    count=pread(cache_info->file,buffer+i,(size_t) MagickMin(length-i,
-      (MagickSizeType) SSIZE_MAX),(off_t) (offset+i));
-#endif
-    if (count <= 0)
-      {
-        count=0;
-        if (errno != EINTR)
-          break;
-      }
-  }
-  return(i);
-}
-
-static inline MagickOffsetType WritePixelCacheRegion(
-  const CacheInfo *restrict cache_info,const MagickOffsetType offset,
-  const MagickSizeType length,const unsigned char *restrict buffer)
-{
-  register MagickOffsetType
-    i;
-
-  ssize_t
-    count;
-
-#if !defined(MAGICKCORE_HAVE_PWRITE)
-  if (lseek(cache_info->file,offset,SEEK_SET) < 0)
-    return((MagickOffsetType) -1);
-#endif
-  count=0;
-  for (i=0; i < (MagickOffsetType) length; i+=count)
-  {
-#if !defined(MAGICKCORE_HAVE_PWRITE)
-    count=write(cache_info->file,buffer+i,(size_t) MagickMin(length-i,
-      (MagickSizeType) SSIZE_MAX));
-#else
-    count=pwrite(cache_info->file,buffer+i,(size_t) MagickMin(length-i,
-      (MagickSizeType) SSIZE_MAX),(off_t) (offset+i));
-#endif
-    if (count <= 0)
-      {
-        count=0;
-        if (errno != EINTR)
-          break;
-      }
-  }
-  return(i);
-}
-
-static MagickBooleanType DiskToDiskPixelCacheClone(CacheInfo *clone_info,
-  CacheInfo *cache_info,ExceptionInfo *exception)
-{
-  MagickOffsetType
-    count;
-
-  register MagickOffsetType
-    i;
-
-  size_t
-    length;
-
-  unsigned char
-    *blob;
-
-  /*
-    Clone pixel cache (both caches on disk).
-  */
-  if (cache_info->debug != MagickFalse)
-    (void) LogMagickEvent(CacheEvent,GetMagickModule(),"disk => disk");
-  blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
-    sizeof(*blob));
-  if (blob == (unsigned char *) NULL)
-    {
-      (void) ThrowMagickException(exception,GetMagickModule(),
-        ResourceLimitError,"MemoryAllocationFailed","`%s'",
-        cache_info->filename);
-      return(MagickFalse);
-    }
-  if (OpenPixelCacheOnDisk(cache_info,ReadMode) == MagickFalse)
-    {
-      blob=(unsigned char *) RelinquishMagickMemory(blob);
-      ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
-        cache_info->cache_filename);
-      return(MagickFalse);
-    }
-  if (OpenPixelCacheOnDisk(clone_info,WriteMode) == MagickFalse)
-    {
-      (void) ClosePixelCacheOnDisk(cache_info);
-      blob=(unsigned char *) RelinquishMagickMemory(blob);
-      ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
-        clone_info->cache_filename);
-      return(MagickFalse);
-    }
-  count=0;
-  for (i=0; i < (MagickOffsetType) cache_info->length; i+=count)
-  {
-    count=ReadPixelCacheRegion(cache_info,cache_info->offset+i,
-      MagickMin(cache_info->length-i,(MagickSizeType) MagickMaxBufferExtent),
-      blob);
-    if (count <= 0)
-      {
-        ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
-          cache_info->cache_filename);
-        break;
-      }
-    length=(size_t) count;
-    count=WritePixelCacheRegion(clone_info,clone_info->offset+i,length,blob);
-    if ((MagickSizeType) count != length)
-      {
-        ThrowFileException(exception,CacheError,"UnableToWritePixelCache",
-          clone_info->cache_filename);
-        break;
-      }
-  }
-  (void) ClosePixelCacheOnDisk(clone_info);
-  (void) ClosePixelCacheOnDisk(cache_info);
-  blob=(unsigned char *) RelinquishMagickMemory(blob);
-  if (i < (MagickOffsetType) cache_info->length)
-    return(MagickFalse);
-  return(MagickTrue);
-}
-
-static MagickBooleanType PixelCacheCloneOptimized(CacheInfo *clone_info,
-  CacheInfo *cache_info,ExceptionInfo *exception)
+static MagickBooleanType ClonePixelCacheRepository(
+  CacheInfo *restrict clone_info,CacheInfo *restrict cache_info,
+  ExceptionInfo *exception)
 {
-  MagickOffsetType
-    count;
-
-  if ((cache_info->type != DiskCache) && (clone_info->type != DiskCache))
-    {
-      /*
-        Clone pixel cache (both caches in memory).
-      */
-      if (cache_info->debug != MagickFalse)
-        (void) LogMagickEvent(CacheEvent,GetMagickModule(),"memory => memory");
-      (void) memcpy(clone_info->pixels,cache_info->pixels,(size_t)
-        cache_info->length);
-      return(MagickTrue);
-    }
-  if ((clone_info->type != DiskCache) && (cache_info->type == DiskCache))
-    {
-      /*
-        Clone pixel cache (one cache on disk, one in memory).
-      */
-      if (cache_info->debug != MagickFalse)
-        (void) LogMagickEvent(CacheEvent,GetMagickModule(),"disk => memory");
-      if (OpenPixelCacheOnDisk(cache_info,ReadMode) == MagickFalse)
-        {
-          ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
-            cache_info->cache_filename);
-          return(MagickFalse);
-        }
-      count=ReadPixelCacheRegion(cache_info,cache_info->offset,
-        cache_info->length,(unsigned char *) clone_info->pixels);
-      (void) ClosePixelCacheOnDisk(cache_info);
-      if ((MagickSizeType) count != cache_info->length)
-        {
-          ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
-            cache_info->cache_filename);
-          return(MagickFalse);
-        }
-      return(MagickTrue);
-    }
-  if ((clone_info->type == DiskCache) && (cache_info->type != DiskCache))
-    {
-      /*
-        Clone pixel cache (one cache on disk, one in memory).
-      */
-      if (clone_info->debug != MagickFalse)
-        (void) LogMagickEvent(CacheEvent,GetMagickModule(),"memory => disk");
-      if (OpenPixelCacheOnDisk(clone_info,WriteMode) == MagickFalse)
-        {
-          ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
-            clone_info->cache_filename);
-          return(MagickFalse);
-        }
-      count=WritePixelCacheRegion(clone_info,clone_info->offset,
-        clone_info->length,(unsigned char *) cache_info->pixels);
-      (void) ClosePixelCacheOnDisk(clone_info);
-      if ((MagickSizeType) count != clone_info->length)
-        {
-          ThrowFileException(exception,CacheError,"UnableToWritePixelCache",
-            clone_info->cache_filename);
-          return(MagickFalse);
-        }
-      return(MagickTrue);
-    }
-  /*
-    Clone pixel cache (both caches on disk).
-  */
-  return(DiskToDiskPixelCacheClone(clone_info,cache_info,exception));
-}
+#define MaxCacheThreads  2
+#define cache_threads(source,destination,chunk) \
+  num_threads((chunk) < (16*GetMagickResourceLimit(ThreadResource)) ? 1 : \
+    GetMagickResourceLimit(ThreadResource) < MaxCacheThreads ? \
+    GetMagickResourceLimit(ThreadResource) : MaxCacheThreads)
 
-static MagickBooleanType PixelCacheCloneUnoptimized(CacheInfo *clone_info,
-  CacheInfo *cache_info,ExceptionInfo *exception)
-{
   MagickBooleanType
+    optimize,
     status;
 
-  MagickOffsetType
-    cache_offset,
-    clone_offset,
-    count;
-
-  register ssize_t
-    x;
-
-  register unsigned char
-    *p;
+  NexusInfo
+    **restrict cache_nexus,
+    **restrict clone_nexus;
 
   size_t
     length;
@@ -760,346 +526,188 @@ static MagickBooleanType PixelCacheCloneUnoptimized(CacheInfo *clone_info,
   ssize_t
     y;
 
-  unsigned char
-    *blob;
-
-  /*
-    Clone pixel cache (unoptimized).
-  */
-  if (cache_info->debug != MagickFalse)
-    {
-      if ((cache_info->type != DiskCache) && (clone_info->type != DiskCache))
-        (void) LogMagickEvent(CacheEvent,GetMagickModule(),"memory => memory");
-      else
-       if ((clone_info->type != DiskCache) && (cache_info->type == DiskCache))
-         (void) LogMagickEvent(CacheEvent,GetMagickModule(),"disk => memory");
-       else
-         if ((clone_info->type == DiskCache) && (cache_info->type != DiskCache))
-           (void) LogMagickEvent(CacheEvent,GetMagickModule(),"memory => disk");
-         else
-           (void) LogMagickEvent(CacheEvent,GetMagickModule(),"disk => disk");
-    }
-  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));
-  if (blob == (unsigned char *) NULL)
-    {
-      (void) ThrowMagickException(exception,GetMagickModule(),
-        ResourceLimitError,"MemoryAllocationFailed","`%s'",
-        cache_info->filename);
-      return(MagickFalse);
-    }
-  (void) ResetMagickMemory(blob,0,length*sizeof(*blob));
-  cache_offset=0;
-  clone_offset=0;
-  if (cache_info->type == DiskCache)
-    {
-      if (OpenPixelCacheOnDisk(cache_info,ReadMode) == MagickFalse)
-        {
-          blob=(unsigned char *) RelinquishMagickMemory(blob);
-          ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
-            cache_info->cache_filename);
-          return(MagickFalse);
-        }
-      cache_offset=cache_info->offset;
-    }
-  if (clone_info->type == DiskCache)
+  assert(cache_info != (CacheInfo *) NULL);
+  assert(clone_info != (CacheInfo *) NULL);
+  assert(exception != (ExceptionInfo *) NULL);
+  if (cache_info->type == PingCache)
+    return(MagickTrue);
+  length=cache_info->number_channels*sizeof(*cache_info->channel_map);
+  if (((cache_info->type == MemoryCache) || (cache_info->type == MapCache)) &&
+      ((clone_info->type == MemoryCache) || (clone_info->type == MapCache)) &&
+      (cache_info->columns == clone_info->columns) &&
+      (cache_info->rows == clone_info->rows) &&
+      (cache_info->number_channels == clone_info->number_channels) &&
+      (memcmp(cache_info->channel_map,clone_info->channel_map,length) == 0) &&
+      (cache_info->metacontent_extent == clone_info->metacontent_extent))
     {
-      if (OpenPixelCacheOnDisk(clone_info,WriteMode) == MagickFalse)
-        {
-          blob=(unsigned char *) RelinquishMagickMemory(blob);
-          ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
-            clone_info->cache_filename);
-          return(MagickFalse);
-        }
-      clone_offset=clone_info->offset;
+      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));
+      return(MagickTrue);
     }
   /*
-    Clone pixel channels.
+    Mismatched pixel cache morphology.
   */
+  cache_nexus=AcquirePixelCacheNexus(MaxCacheThreads);
+  clone_nexus=AcquirePixelCacheNexus(MaxCacheThreads);
+  if ((cache_nexus == (NexusInfo **) NULL) ||
+      (clone_nexus == (NexusInfo **) NULL))
+    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
+  length=cache_info->number_channels*sizeof(*cache_info->channel_map);
+  optimize=(cache_info->number_channels == clone_info->number_channels) &&
+    (memcmp(cache_info->channel_map,clone_info->channel_map,length) == 0) ?
+    MagickTrue : MagickFalse;
+  length=(size_t) MagickMin(cache_info->columns*cache_info->number_channels,
+    clone_info->columns*clone_info->number_channels);
   status=MagickTrue;
-  p=blob;
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+  #pragma omp parallel for schedule(static,4) shared(status) \
+    cache_threads(cache_info,clone_info,cache_info->rows)
+#endif
   for (y=0; y < (ssize_t) cache_info->rows; y++)
   {
-    for (x=0; x < (ssize_t) cache_info->columns; x++)
-    {
-      register ssize_t
-        i;
+    const int
+      id = GetOpenMPThreadId();
 
-      /*
-        Read a set of pixel channels.
-      */
-      length=cache_info->number_channels*sizeof(Quantum);
-      if (cache_info->type != DiskCache)
-        p=(unsigned char *) cache_info->pixels+cache_offset;
-      else
-        {
-          count=ReadPixelCacheRegion(cache_info,cache_offset,length,p);
-          if ((MagickSizeType) count != length)
-            {
-              status=MagickFalse;
-              break;
-            }
-        }
-      cache_offset+=length;
-      if ((y < (ssize_t) clone_info->rows) &&
-          (x < (ssize_t) clone_info->columns))
-        for (i=0; i < (ssize_t) clone_info->number_channels; i++)
-        {
-          PixelChannel
-            channel;
+    Quantum
+      *pixels;
 
-          PixelTrait
-            traits;
+    RectangleInfo
+      region;
 
-          ssize_t
-            offset;
+    register ssize_t
+      x;
 
-          /*
-            Write a set of pixel channels.
-          */
-          channel=clone_info->channel_map[i].channel;
-          traits=cache_info->channel_map[channel].traits;
-          if (traits == UndefinedPixelTrait)
-            {
-              clone_offset+=sizeof(Quantum);
-              continue;
-            }
-          offset=cache_info->channel_map[channel].offset;
-          if (clone_info->type != DiskCache)
-            (void) memcpy((unsigned char *) clone_info->pixels+clone_offset,p+
-              offset*sizeof(Quantum),sizeof(Quantum));
-          else
-            {
-              count=WritePixelCacheRegion(clone_info,clone_offset,
-                sizeof(Quantum),p+offset*sizeof(Quantum));
-              if ((MagickSizeType) count != sizeof(Quantum))
-                {
-                  status=MagickFalse;
-                  break;
-                }
-            }
-          clone_offset+=sizeof(Quantum);
-        }
-    }
-    if (y < (ssize_t) clone_info->rows)
+    if (status == MagickFalse)
+      continue;
+    if (y >= (ssize_t) clone_info->rows)
+      continue;
+    region.width=cache_info->columns;
+    region.height=1;
+    region.x=0;
+    region.y=y;
+    pixels=SetPixelCacheNexusPixels(cache_info,ReadMode,&region,cache_nexus[id],
+      exception);
+    if (pixels == (Quantum *) NULL)
+      continue;
+    status=ReadPixelCachePixels(cache_info,cache_nexus[id],exception);
+    if (status == MagickFalse)
+      continue;
+    region.width=clone_info->columns;
+    pixels=SetPixelCacheNexusPixels(clone_info,WriteMode,&region,
+      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));
+    else
       {
+        register const Quantum
+          *restrict p;
+
+        register Quantum
+          *restrict q;
+
         /*
-          Set remaining columns as undefined.
+          Mismatched pixel channel map.
         */
-        length=clone_info->number_channels*sizeof(Quantum);
-        (void) ResetMagickMemory(blob,0,length*sizeof(*blob));
-        for ( ; x < (ssize_t) clone_info->columns; x++)
+        p=cache_nexus[id]->pixels;
+        q=clone_nexus[id]->pixels;
+        for (x=0; x < (ssize_t) cache_info->columns; x++)
         {
-          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);
-              if ((MagickSizeType) count != length)
-                {
-                  status=MagickFalse;
-                  break;
-              }
-            }
-          clone_offset+=length;
+          register ssize_t
+            i;
+
+          if (x == (ssize_t) clone_info->columns)
+            break;
+          for (i=0; i < (ssize_t) clone_info->number_channels; i++)
+          {
+            PixelChannel
+              channel;
+
+            PixelTrait
+              traits;
+
+            channel=clone_info->channel_map[i].channel;
+            traits=cache_info->channel_map[channel].traits;
+            if (traits != UndefinedPixelTrait)
+              (void) memcpy(q,p+cache_info->channel_map[channel].offset,
+                sizeof(Quantum));
+            q++;
+          }
+          p+=cache_info->number_channels;
         }
       }
+    status=WritePixelCachePixels(clone_info,clone_nexus[id],exception);
   }
-  length=clone_info->number_channels*sizeof(Quantum);
-  (void) ResetMagickMemory(blob,0,length*sizeof(*blob));
-  for ( ; y < (ssize_t) clone_info->rows; y++)
-  {
-    /*
-      Set remaining rows as undefined.
-    */
-    for (x=0; x < (ssize_t) clone_info->columns; x++)
-    {
-      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);
-          if ((MagickSizeType) count != length)
-            {
-              status=MagickFalse;
-              break;
-            }
-        }
-      clone_offset+=length;
-    }
-  }
-  if ((cache_info->metacontent_extent != 0) ||
+  if ((cache_info->metacontent_extent != 0) &&
       (clone_info->metacontent_extent != 0))
     {
       /*
         Clone metacontent.
       */
+      length=(size_t) MagickMin(cache_info->metacontent_extent,
+        clone_info->metacontent_extent);
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        cache_threads(cache_info,clone_info,cache_info->rows)
+#endif
       for (y=0; y < (ssize_t) cache_info->rows; y++)
       {
-        for (x=0; x < (ssize_t) cache_info->columns; x++)
-        {
-          /*
-            Read a set of metacontent.
-          */
-          length=cache_info->metacontent_extent;
-          if (cache_info->type != DiskCache)
-            p=(unsigned char *) cache_info->pixels+cache_offset;
-          else
-            {
-              count=ReadPixelCacheRegion(cache_info,cache_offset,length,p);
-              if ((MagickSizeType) count != length)
-                {
-                  status=MagickFalse;
-                  break;
-                }
-            }
-          cache_offset+=length;
-          if ((y < (ssize_t) clone_info->rows) &&
-              (x < (ssize_t) clone_info->columns))
-            {
-              /*
-                Write a set of metacontent.
-              */
-              length=clone_info->metacontent_extent;
-              if (clone_info->type != DiskCache)
-                (void) memcpy((unsigned char *) clone_info->pixels+clone_offset,
-                  p,length);
-              else
-                {
-                  count=WritePixelCacheRegion(clone_info,clone_offset,length,p);
-                  if ((MagickSizeType) count != length)
-                    {
-                      status=MagickFalse;
-                      break;
-                    }
-                }
-              clone_offset+=length;
-            }
-        }
-        length=clone_info->metacontent_extent;
-        (void) ResetMagickMemory(blob,0,length*sizeof(*blob));
-        for ( ; x < (ssize_t) clone_info->columns; x++)
-        {
-          /*
-            Set remaining columns as undefined.
-          */
-          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);
-              if ((MagickSizeType) count != length)
-                {
-                  status=MagickFalse;
-                  break;
-                }
-            }
-          clone_offset+=length;
-        }
-      }
-      if (y < (ssize_t) clone_info->rows)
-        {
-          /*
-            Set remaining rows as undefined.
-          */
-          length=clone_info->metacontent_extent;
-          (void) ResetMagickMemory(blob,0,length*sizeof(*blob));
-          for ( ; y < (ssize_t) clone_info->rows; y++)
-          {
-            for (x=0; x < (ssize_t) clone_info->columns; x++)
-            {
-              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);
-                  if ((MagickSizeType) count != length)
-                    {
-                      status=MagickFalse;
-                      break;
-                    }
-                }
-              clone_offset+=length;
-            }
-          }
-        }
-    }
-  if (clone_info->type == DiskCache)
-    (void) ClosePixelCacheOnDisk(clone_info);
-  if (cache_info->type == DiskCache)
-    (void) ClosePixelCacheOnDisk(cache_info);
-  blob=(unsigned char *) RelinquishMagickMemory(blob);
-  return(status);
-}
+        const int
+          id = GetOpenMPThreadId();
 
-static MagickBooleanType ClonePixelCachePixels(CacheInfo *clone_info,
-  CacheInfo *cache_info,ExceptionInfo *exception)
-{
-  PixelChannelMap
-    *p,
-    *q;
+        Quantum
+          *pixels;
 
-  if (cache_info->type == PingCache)
-    return(MagickTrue);
-  p=cache_info->channel_map;
-  q=clone_info->channel_map;
-  if ((cache_info->columns == clone_info->columns) &&
-      (cache_info->rows == clone_info->rows) &&
-      (cache_info->number_channels == clone_info->number_channels) &&
-      (memcmp(p,q,cache_info->number_channels*sizeof(*p)) == 0) &&
-      (cache_info->metacontent_extent == clone_info->metacontent_extent))
-    return(PixelCacheCloneOptimized(clone_info,cache_info,exception));
-  return(PixelCacheCloneUnoptimized(clone_info,cache_info,exception));
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%                                                                             %
-%                                                                             %
-%                                                                             %
-+   C l o n e P i x e l C a c h e M e t h o d s                               %
-%                                                                             %
-%                                                                             %
-%                                                                             %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%  ClonePixelCacheMethods() clones the pixel cache methods from one cache to
-%  another.
-%
-%  The format of the ClonePixelCacheMethods() method is:
-%
-%      void ClonePixelCacheMethods(Cache clone,const Cache cache)
-%
-%  A description of each parameter follows:
-%
-%    o clone: Specifies a pointer to a Cache structure.
-%
-%    o cache: the pixel cache.
-%
-*/
-MagickPrivate void ClonePixelCacheMethods(Cache clone,const Cache cache)
-{
-  CacheInfo
-    *cache_info,
-    *source_info;
+        RectangleInfo
+          region;
 
-  assert(clone != (Cache) NULL);
-  source_info=(CacheInfo *) clone;
-  assert(source_info->signature == MagickSignature);
-  if (source_info->debug != MagickFalse)
-    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
-      source_info->filename);
-  assert(cache != (Cache) NULL);
-  cache_info=(CacheInfo *) cache;
-  assert(cache_info->signature == MagickSignature);
-  source_info->methods=cache_info->methods;
+        if (status == MagickFalse)
+          continue;
+        if (y >= (ssize_t) clone_info->rows)
+          continue;
+        region.width=cache_info->columns;
+        region.height=1;
+        region.x=0;
+        region.y=y;
+        pixels=SetPixelCacheNexusPixels(cache_info,ReadMode,&region,
+          cache_nexus[id],exception);
+        if (pixels == (Quantum *) NULL)
+          continue;
+        status=ReadPixelCacheMetacontent(cache_info,cache_nexus[id],exception);
+        if (status == MagickFalse)
+          continue;
+        region.width=clone_info->columns;
+        pixels=SetPixelCacheNexusPixels(clone_info,WriteMode,&region,
+          clone_nexus[id],exception);
+        if (pixels == (Quantum *) NULL)
+          continue;
+        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);
+      }
+    }
+  cache_nexus=DestroyPixelCacheNexus(cache_nexus,MaxCacheThreads);
+  clone_nexus=DestroyPixelCacheNexus(clone_nexus,MaxCacheThreads);
+  if (cache_info->debug != MagickFalse)
+    {
+      char
+        message[MaxTextExtent];
+
+      (void) FormatLocaleString(message,MaxTextExtent,"%s => %s",
+        CommandOptionToMnemonic(MagickCacheOptions,(ssize_t) cache_info->type),
+        CommandOptionToMnemonic(MagickCacheOptions,(ssize_t) clone_info->type));
+      (void) LogMagickEvent(CacheEvent,GetMagickModule(),"%s",message);
+    }
+  return(status);
 }
 \f
 /*
@@ -1160,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);
@@ -1200,6 +808,21 @@ MagickExport void DestroyImagePixels(Image *image)
 %
 */
 
+static MagickBooleanType ClosePixelCacheOnDisk(CacheInfo *cache_info)
+{
+  int
+    status;
+
+  status=(-1);
+  if (cache_info->file != -1)
+    {
+      status=close(cache_info->file);
+      cache_info->file=(-1);
+      RelinquishMagickResource(FileResource,1);
+    }
+  return(status == -1 ? MagickFalse : MagickTrue);
+}
+
 static inline void RelinquishPixelCachePixels(CacheInfo *cache_info)
 {
   switch (cache_info->type)
@@ -1210,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';
@@ -1236,7 +861,9 @@ static inline void RelinquishPixelCachePixels(CacheInfo *cache_info)
     }
     case DistributedCache:
     {
-      abort();
+      *cache_info->cache_filename='\0';
+      (void) RelinquishDistributePixelCache((DistributeCacheInfo *)
+        cache_info->server_info);
       break;
     }
     default:
@@ -1250,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;
@@ -1276,18 +903,18 @@ MagickPrivate Cache DestroyPixelCache(Cache cache)
       (void) LogMagickEvent(CacheEvent,GetMagickModule(),"%s",message);
     }
   RelinquishPixelCachePixels(cache_info);
-  if (cache_info->distribute_cache_info != (DistributeCacheInfo *) NULL)
-    cache_info->distribute_cache_info=
-      DestroyDistributeCacheInfo(cache_info->distribute_cache_info);
+  if (cache_info->server_info != (DistributeCacheInfo *) NULL)
+    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;
@@ -1378,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);
@@ -1394,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
 /*
@@ -1431,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
 /*
@@ -1485,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
 /*
@@ -1560,7 +1162,7 @@ MagickPrivate Quantum *GetAuthenticPixelCacheNexus(Image *image,
 static Quantum *GetAuthenticPixelsFromCache(const Image *image)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
@@ -1571,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
 /*
@@ -1601,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();
@@ -1615,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
 /*
@@ -1667,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);
@@ -1683,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
 /*
@@ -1729,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);
@@ -1745,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
 /*
@@ -1776,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();
@@ -1841,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) ||
@@ -1856,7 +1459,7 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   MagickBooleanType
     destroy,
@@ -1873,23 +1476,7 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone,
   status=MagickTrue;
   LockSemaphoreInfo(image->semaphore);
   if (cpu_throttle == 0)
-    {
-      char
-        *limit;
-
-      /*
-        Set CPU throttle in milleseconds.
-      */
-      cpu_throttle=MagickResourceInfinity;
-      limit=GetEnvironmentValue("MAGICK_THROTTLE");
-      if (limit == (char *) NULL)
-        limit=GetPolicyValue("throttle");
-      if (limit != (char *) NULL)
-        {
-          cpu_throttle=(MagickSizeType) StringToInteger(limit);
-          limit=DestroyString(limit);
-        }
-    }
+    cpu_throttle=GetMagickResourceLimit(ThrottleResource);
   if ((cpu_throttle != MagickResourceInfinity) && ((cycles++ % 32) == 0))
     MagickDelay(cpu_throttle);
   if (time_limit == 0)
@@ -1902,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;
@@ -1921,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;
@@ -1929,7 +1521,8 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone,
           if (status != MagickFalse)
             {
               if (clone != MagickFalse)
-                status=ClonePixelCachePixels(clone_info,cache_info,exception);
+                status=ClonePixelCacheRepository(clone_info,cache_info,
+                   exception);
               if (status != MagickFalse)
                 {
                   if (cache_info->reference_count == 1)
@@ -1938,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);
     }
@@ -1991,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);
@@ -2035,10 +1628,10 @@ 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
-    *q;
+    *restrict q;
 
   register ssize_t
     i;
@@ -2065,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);
@@ -2109,13 +1699,13 @@ 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();
 
   register Quantum
-    *q;
+    *restrict q;
 
   register ssize_t
     i;
@@ -2140,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);
@@ -2184,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();
@@ -2219,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);
@@ -2267,7 +1851,7 @@ static MagickBooleanType GetOneVirtualPixelFromCache(const Image *image,
   Quantum *pixel,ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
@@ -2298,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);
@@ -2346,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);
@@ -2394,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;
@@ -2473,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;
@@ -2495,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                                     %
 %                                                                             %
 %                                                                             %
@@ -2601,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);
@@ -2645,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;
@@ -2687,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);
@@ -2728,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);
@@ -2764,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);
@@ -2810,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;
@@ -2850,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);
@@ -3002,7 +2503,7 @@ MagickPrivate const Quantum *GetVirtualPixelsFromNexus(const Image *image,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   MagickOffsetType
     offset;
@@ -3012,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;
@@ -3041,7 +2542,7 @@ MagickPrivate const Quantum *GetVirtualPixelsFromNexus(const Image *image,
     v;
 
   void
-    *virtual_metacontent;
+    *restrict virtual_metacontent;
 
   /*
     Acquire pixels.
@@ -3057,7 +2558,8 @@ MagickPrivate const Quantum *GetVirtualPixelsFromNexus(const Image *image,
   region.y=y;
   region.width=columns;
   region.height=rows;
-  pixels=SetPixelCacheNexusPixels(image,ReadMode,&region,nexus_info,exception);
+  pixels=SetPixelCacheNexusPixels(cache_info,ReadMode,&region,nexus_info,
+    exception);
   if (pixels == (Quantum *) NULL)
     return((const Quantum *) NULL);
   q=pixels;
@@ -3076,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)
@@ -3092,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)
     {
@@ -3189,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
@@ -3206,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;
             }
@@ -3228,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);
@@ -3245,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;
@@ -3261,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;
@@ -3288,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;
@@ -3307,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);
@@ -3323,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);
@@ -3353,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);
@@ -3415,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);
@@ -3460,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();
@@ -3530,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);
@@ -3579,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();
@@ -3620,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;
@@ -3664,23 +3179,119 @@ MagickPrivate const Quantum *GetVirtualPixelsNexus(const Cache cache,
 %
 */
 
-static inline void AllocatePixelCachePixels(CacheInfo *cache_info)
+static inline void AllocatePixelCachePixels(CacheInfo *cache_info)
+{
+  cache_info->mapped=MagickFalse;
+  cache_info->pixels=(Quantum *) MagickAssumeAligned(AcquireAlignedMemory(1,
+    (size_t) cache_info->length));
+  if (cache_info->pixels == (Quantum *) NULL)
+    {
+      cache_info->mapped=MagickTrue;
+      cache_info->pixels=(Quantum *) MapBlob(-1,IOMode,0,(size_t)
+        cache_info->length);
+    }
+}
+
+#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)
+{
+  int
+    file;
+
+  /*
+    Open pixel cache on disk.
+  */
+  if (cache_info->file != -1)
+    return(MagickTrue);  /* cache already open */
+  if (*cache_info->cache_filename == '\0')
+    file=AcquireUniqueFileResource(cache_info->cache_filename);
+  else
+    switch (mode)
+    {
+      case ReadMode:
+      {
+        file=open_utf8(cache_info->cache_filename,O_RDONLY | O_BINARY,0);
+        break;
+      }
+      case WriteMode:
+      {
+        file=open_utf8(cache_info->cache_filename,O_WRONLY | O_CREAT |
+          O_BINARY | O_EXCL,S_MODE);
+        if (file == -1)
+          file=open_utf8(cache_info->cache_filename,O_WRONLY | O_BINARY,S_MODE);
+        break;
+      }
+      case IOMode:
+      default:
+      {
+        file=open_utf8(cache_info->cache_filename,O_RDWR | O_CREAT | O_BINARY |
+          O_EXCL,S_MODE);
+        if (file == -1)
+          file=open_utf8(cache_info->cache_filename,O_RDWR | O_BINARY,S_MODE);
+        break;
+      }
+    }
+  if (file == -1)
+    return(MagickFalse);
+  (void) AcquireMagickResource(FileResource,1);
+  cache_info->file=file;
+  cache_info->mode=mode;
+  return(MagickTrue);
+}
+
+static inline MagickOffsetType WritePixelCacheRegion(
+  const CacheInfo *restrict cache_info,const MagickOffsetType offset,
+  const MagickSizeType length,const unsigned char *restrict buffer)
 {
-  cache_info->mapped=MagickFalse;
-  cache_info->pixels=(Quantum *) MagickAssumeAligned(AcquireAlignedMemory(1,
-    (size_t) cache_info->length));
-  if (cache_info->pixels == (Quantum *) NULL)
-    {
-      cache_info->mapped=MagickTrue;
-      cache_info->pixels=(Quantum *) MapBlob(-1,IOMode,0,(size_t)
-        cache_info->length);
-    }
+  register MagickOffsetType
+    i;
+
+  ssize_t
+    count;
+
+#if !defined(MAGICKCORE_HAVE_PWRITE)
+  if (lseek(cache_info->file,offset,SEEK_SET) < 0)
+    return((MagickOffsetType) -1);
+#endif
+  count=0;
+  for (i=0; i < (MagickOffsetType) length; i+=count)
+  {
+#if !defined(MAGICKCORE_HAVE_PWRITE)
+    count=write(cache_info->file,buffer+i,(size_t) MagickMin(length-i,
+      (MagickSizeType) SSIZE_MAX));
+#else
+    count=pwrite(cache_info->file,buffer+i,(size_t) MagickMin(length-i,
+      (MagickSizeType) SSIZE_MAX),(off_t) (offset+i));
+#endif
+    if (count <= 0)
+      {
+        count=0;
+        if (errno != EINTR)
+          break;
+      }
+  }
+  return(i);
 }
 
 static MagickBooleanType SetPixelCacheExtent(Image *image,MagickSizeType length)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   MagickOffsetType
     count,
@@ -3719,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);
 }
@@ -3727,13 +3341,16 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info,
+    *restrict cache_info,
     source_info;
 
   char
     format[MaxTextExtent],
     message[MaxTextExtent];
 
+  const char
+    *type;
+
   MagickBooleanType
     status;
 
@@ -3761,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);
@@ -3814,19 +3432,21 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
               if ((source_info.storage_class != UndefinedClass) &&
                   (mode != ReadMode))
                 {
-                  status=ClonePixelCachePixels(cache_info,&source_info,
+                  status=ClonePixelCacheRepository(cache_info,&source_info,
                     exception);
                   RelinquishPixelCachePixels(&source_info);
                 }
               if (image->debug != MagickFalse)
                 {
                   (void) FormatMagickSize(cache_info->length,MagickTrue,format);
+                  type=CommandOptionToMnemonic(MagickCacheOptions,(ssize_t)
+                    cache_info->type);
                   (void) FormatLocaleString(message,MaxTextExtent,
-                    "open %s (%s memory, %.20gx%.20gx%.20g %s)",
+                    "open %s (%s %s, %.20gx%.20gx%.20g %s)",
                     cache_info->filename,cache_info->mapped != MagickFalse ?
-                    "anonymous" : "heap",(double) cache_info->columns,(double)
-                    cache_info->rows,(double) cache_info->number_channels,
-                    format);
+                    "Anonymous" : "Heap",type,(double) cache_info->columns,
+                    (double) cache_info->rows,(double)
+                    cache_info->number_channels,format);
                   (void) LogMagickEvent(CacheEvent,GetMagickModule(),"%s",
                     message);
                 }
@@ -3839,11 +3459,62 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
     Create pixel cache on disk.
   */
   status=AcquireMagickResource(DiskResource,cache_info->length);
-  if (status == MagickFalse)
+  if ((status == MagickFalse) || (cache_info->type == DistributedCache))
     {
-      cache_info->distribute_cache_info=AcquireDistributeCacheInfo(exception);
-      if (cache_info->distribute_cache_info != (DistributeCacheInfo *) NULL)
-        return(MagickTrue);
+      DistributeCacheInfo
+        *server_info;
+
+      if (cache_info->type == DistributedCache)
+        RelinquishMagickResource(DiskResource,cache_info->length);
+      server_info=AcquireDistributeCacheInfo(exception);
+      if (server_info != (DistributeCacheInfo *) NULL)
+        {
+          status=OpenDistributePixelCache(server_info,image);
+          if (status == MagickFalse)
+            {
+              ThrowFileException(exception,CacheError,"UnableToOpenPixelCache",
+                GetDistributeCacheHostname(server_info));
+              server_info=DestroyDistributeCacheInfo(server_info);
+            }
+          else
+            {
+              /*
+                Create a distributed pixel cache.
+              */
+              cache_info->type=DistributedCache;
+              cache_info->server_info=server_info;
+              (void) FormatLocaleString(cache_info->cache_filename,
+                MaxTextExtent,"%s:%d",GetDistributeCacheHostname(
+                (DistributeCacheInfo *) cache_info->server_info),
+                GetDistributeCachePort((DistributeCacheInfo *)
+                cache_info->server_info));
+              if ((source_info.storage_class != UndefinedClass) &&
+                  (mode != ReadMode))
+                {
+                  status=ClonePixelCacheRepository(cache_info,&source_info,
+                    exception);
+                  RelinquishPixelCachePixels(&source_info);
+                }
+              if (image->debug != MagickFalse)
+                {
+                  (void) FormatMagickSize(cache_info->length,MagickFalse,
+                    format);
+                  type=CommandOptionToMnemonic(MagickCacheOptions,(ssize_t)
+                    cache_info->type);
+                  (void) FormatLocaleString(message,MaxTextExtent,
+                    "open %s (%s[%d], %s, %.20gx%.20gx%.20g %s)",
+                    cache_info->filename,cache_info->cache_filename,
+                    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);
@@ -3903,17 +3574,19 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
               if ((source_info.storage_class != UndefinedClass) &&
                   (mode != ReadMode))
                 {
-                  status=ClonePixelCachePixels(cache_info,&source_info,
+                  status=ClonePixelCacheRepository(cache_info,&source_info,
                     exception);
                   RelinquishPixelCachePixels(&source_info);
                 }
               if (image->debug != MagickFalse)
                 {
                   (void) FormatMagickSize(cache_info->length,MagickTrue,format);
+                  type=CommandOptionToMnemonic(MagickCacheOptions,(ssize_t)
+                    cache_info->type);
                   (void) FormatLocaleString(message,MaxTextExtent,
-                    "open %s (%s[%d], memory-mapped, %.20gx%.20gx%.20g %s)",
+                    "open %s (%s[%d], %s, %.20gx%.20gx%.20g %s)",
                     cache_info->filename,cache_info->cache_filename,
-                    cache_info->file,(double) cache_info->columns,(double)
+                    cache_info->file,type,(double) cache_info->columns,(double)
                     cache_info->rows,(double) cache_info->number_channels,
                     format);
                   (void) LogMagickEvent(CacheEvent,GetMagickModule(),"%s",
@@ -3927,15 +3600,17 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
   status=MagickTrue;
   if ((source_info.storage_class != UndefinedClass) && (mode != ReadMode))
     {
-      status=ClonePixelCachePixels(cache_info,&source_info,exception);
+      status=ClonePixelCacheRepository(cache_info,&source_info,exception);
       RelinquishPixelCachePixels(&source_info);
     }
   if (image->debug != MagickFalse)
     {
       (void) FormatMagickSize(cache_info->length,MagickFalse,format);
+      type=CommandOptionToMnemonic(MagickCacheOptions,(ssize_t)
+        cache_info->type);
       (void) FormatLocaleString(message,MaxTextExtent,
-        "open %s (%s[%d], disk, %.20gx%.20gx%.20g %s)",cache_info->filename,
-        cache_info->cache_filename,cache_info->file,(double)
+        "open %s (%s[%d], %s, %.20gx%.20gx%.20g %s)",cache_info->filename,
+        cache_info->cache_filename,cache_info->file,type,(double)
         cache_info->columns,(double) cache_info->rows,(double)
         cache_info->number_channels,format);
       (void) LogMagickEvent(CacheEvent,GetMagickModule(),"%s",message);
@@ -3985,8 +3660,8 @@ MagickExport MagickBooleanType PersistPixelCache(Image *image,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info,
-    *clone_info;
+    *restrict cache_info,
+    *restrict clone_info;
 
   Image
     clone_image;
@@ -4024,11 +3699,13 @@ MagickExport MagickBooleanType PersistPixelCache(Image *image,
       *offset+=cache_info->length+page_size-(cache_info->length % page_size);
       return(MagickTrue);
     }
-  if ((cache_info->mode != ReadMode) && (cache_info->type != MemoryCache) &&
+  if ((cache_info->mode != ReadMode) &&
+      ((cache_info->type == DiskCache) || (cache_info->type == MapCache)) &&
       (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 == DiskCache) || (cache_info->type == MapCache)) &&
           (cache_info->reference_count == 1))
         {
           int
@@ -4067,7 +3744,7 @@ MagickExport MagickBooleanType PersistPixelCache(Image *image,
   cache_info=(CacheInfo *) image->cache;
   status=OpenPixelCache(image,IOMode,exception);
   if (status != MagickFalse)
-    status=ClonePixelCachePixels(cache_info,clone_info,exception);
+    status=ClonePixelCacheRepository(cache_info,clone_info,exception);
   *offset+=cache_info->length+page_size-(cache_info->length % page_size);
   clone_info=(CacheInfo *) DestroyPixelCache(clone_info);
   return(status);
@@ -4116,7 +3793,7 @@ MagickPrivate Quantum *QueueAuthenticPixelCacheNexus(Image *image,
   const MagickBooleanType clone,NexusInfo *nexus_info,ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   MagickOffsetType
     offset;
@@ -4124,6 +3801,9 @@ MagickPrivate Quantum *QueueAuthenticPixelCacheNexus(Image *image,
   MagickSizeType
     number_pixels;
 
+  Quantum
+    *restrict pixels;
+
   RectangleInfo
     region;
 
@@ -4137,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,
@@ -4164,7 +3839,9 @@ MagickPrivate Quantum *QueueAuthenticPixelCacheNexus(Image *image,
   region.y=y;
   region.width=columns;
   region.height=rows;
-  return(SetPixelCacheNexusPixels(image,WriteMode,&region,nexus_info,exception));
+  pixels=SetPixelCacheNexusPixels(cache_info,WriteMode,&region,nexus_info,
+    exception);
+  return(pixels);
 }
 \f
 /*
@@ -4205,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);
@@ -4219,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
 /*
@@ -4285,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);
@@ -4301,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
 /*
@@ -4339,8 +4016,44 @@ MagickExport Quantum *QueueAuthenticPixels(Image *image,const ssize_t x,
 %    o exception: return any errors or warnings in this structure.
 %
 */
-static MagickBooleanType ReadPixelCacheMetacontent(CacheInfo *cache_info,
-  NexusInfo *nexus_info,ExceptionInfo *exception)
+
+static inline MagickOffsetType ReadPixelCacheRegion(
+  const CacheInfo *restrict cache_info,const MagickOffsetType offset,
+  const MagickSizeType length,unsigned char *restrict buffer)
+{
+  register MagickOffsetType
+    i;
+
+  ssize_t
+    count;
+
+#if !defined(MAGICKCORE_HAVE_PREAD)
+  if (lseek(cache_info->file,offset,SEEK_SET) < 0)
+    return((MagickOffsetType) -1);
+#endif
+  count=0;
+  for (i=0; i < (MagickOffsetType) length; i+=count)
+  {
+#if !defined(MAGICKCORE_HAVE_PREAD)
+    count=read(cache_info->file,buffer+i,(size_t) MagickMin(length-i,
+      (MagickSizeType) SSIZE_MAX));
+#else
+    count=pread(cache_info->file,buffer+i,(size_t) MagickMin(length-i,
+      (MagickSizeType) SSIZE_MAX),(off_t) (offset+i));
+#endif
+    if (count <= 0)
+      {
+        count=0;
+        if (errno != EINTR)
+          break;
+      }
+  }
+  return(i);
+}
+
+static MagickBooleanType ReadPixelCacheMetacontent(
+  CacheInfo *restrict cache_info,NexusInfo *restrict nexus_info,
+  ExceptionInfo *exception)
 {
   MagickOffsetType
     count,
@@ -4361,14 +4074,15 @@ 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;
   length=(MagickSizeType) nexus_info->region.width*
     cache_info->metacontent_extent;
+  extent=length*nexus_info->region.height;
   rows=nexus_info->region.height;
-  extent=length*rows;
+  y=0;
   q=(unsigned char *) nexus_info->metacontent;
   switch (cache_info->type)
   {
@@ -4422,7 +4136,7 @@ static MagickBooleanType ReadPixelCacheMetacontent(CacheInfo *cache_info,
         count=ReadPixelCacheRegion(cache_info,cache_info->offset+extent*
           cache_info->number_channels*sizeof(Quantum)+offset*
           cache_info->metacontent_extent,length,(unsigned char *) q);
-        if ((MagickSizeType) count != length)
+        if (count != (MagickOffsetType) length)
           break;
         offset+=cache_info->columns;
         q+=cache_info->metacontent_extent*nexus_info->region.width;
@@ -4430,22 +4144,47 @@ static MagickBooleanType ReadPixelCacheMetacontent(CacheInfo *cache_info,
       if (IsFileDescriptorLimitExceeded() != MagickFalse)
         (void) ClosePixelCacheOnDisk(cache_info);
       UnlockSemaphoreInfo(cache_info->file_semaphore);
-      if (y < (ssize_t) rows)
-        {
-          ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
-            cache_info->cache_filename);
-          return(MagickFalse);
-        }
       break;
     }
     case DistributedCache:
     {
-      abort();
+      RectangleInfo
+        region;
+
+      /*
+        Read metacontent from distributed cache.
+      */
+      LockSemaphoreInfo(cache_info->file_semaphore);
+      region=nexus_info->region;
+      if ((cache_info->columns != nexus_info->region.width) ||
+          (extent > MagickMaxBufferExtent))
+        region.height=1UL;
+      else
+        {
+          length=extent;
+          rows=1UL;
+        }
+      for (y=0; y < (ssize_t) rows; y++)
+      {
+        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;
+        region.y++;
+      }
+      UnlockSemaphoreInfo(cache_info->file_semaphore);
       break;
     }
     default:
       break;
   }
+  if (y < (ssize_t) rows)
+    {
+      ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
+        cache_info->cache_filename);
+      return(MagickFalse);
+    }
   if ((cache_info->debug != MagickFalse) &&
       (CacheTick(nexus_info->region.y,cache_info->rows) != MagickFalse))
     (void) LogMagickEvent(CacheEvent,GetMagickModule(),
@@ -4483,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,
@@ -4503,14 +4242,15 @@ 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;
-  length=(MagickSizeType) nexus_info->region.width*cache_info->number_channels*
+  length=(MagickSizeType) cache_info->number_channels*nexus_info->region.width*
     sizeof(Quantum);
+  extent=length*nexus_info->region.height;
   rows=nexus_info->region.height;
-  extent=length*rows;
+  y=0;
   q=nexus_info->pixels;
   switch (cache_info->type)
   {
@@ -4561,7 +4301,7 @@ static MagickBooleanType ReadPixelCachePixels(CacheInfo *cache_info,
       {
         count=ReadPixelCacheRegion(cache_info,cache_info->offset+offset*
           cache_info->number_channels*sizeof(*q),length,(unsigned char *) q);
-        if ((MagickSizeType) count != length)
+        if (count != (MagickOffsetType) length)
           break;
         offset+=cache_info->columns;
         q+=cache_info->number_channels*nexus_info->region.width;
@@ -4569,22 +4309,47 @@ static MagickBooleanType ReadPixelCachePixels(CacheInfo *cache_info,
       if (IsFileDescriptorLimitExceeded() != MagickFalse)
         (void) ClosePixelCacheOnDisk(cache_info);
       UnlockSemaphoreInfo(cache_info->file_semaphore);
-      if (y < (ssize_t) rows)
-        {
-          ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
-            cache_info->cache_filename);
-          return(MagickFalse);
-        }
       break;
     }
     case DistributedCache:
     {
-      abort();
+      RectangleInfo
+        region;
+
+      /*
+        Read pixels from distributed cache.
+      */
+      LockSemaphoreInfo(cache_info->file_semaphore);
+      region=nexus_info->region;
+      if ((cache_info->columns != nexus_info->region.width) ||
+          (extent > MagickMaxBufferExtent))
+        region.height=1UL;
+      else
+        {
+          length=extent;
+          rows=1UL;
+        }
+      for (y=0; y < (ssize_t) rows; y++)
+      {
+        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;
+        region.y++;
+      }
+      UnlockSemaphoreInfo(cache_info->file_semaphore);
       break;
     }
     default:
       break;
   }
+  if (y < (ssize_t) rows)
+    {
+      ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
+        cache_info->cache_filename);
+      return(MagickFalse);
+    }
   if ((cache_info->debug != MagickFalse) &&
       (CacheTick(nexus_info->region.y,cache_info->rows) != MagickFalse))
     (void) LogMagickEvent(CacheEvent,GetMagickModule(),
@@ -4620,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;
@@ -4658,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;
@@ -4736,13 +4501,13 @@ MagickPrivate void SetPixelCacheMethods(Cache cache,CacheMethods *cache_methods)
 %
 %  The format of the SetPixelCacheNexusPixels() method is:
 %
-%      Quantum SetPixelCacheNexusPixels(const Image *image,const MapMode mode,
-%        const RectangleInfo *region,NexusInfo *nexus_info,
+%      Quantum SetPixelCacheNexusPixels(const CacheInfo *cache_info,
+%        const MapMode mode,const RectangleInfo *region,NexusInfo *nexus_info,
 %        ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
-%    o image: the image.
+%    o cache_info: the pixel cache.
 %
 %    o mode: ReadMode, WriteMode, or IOMode.
 %
@@ -4780,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)
 {
@@ -4791,12 +4577,10 @@ static inline void PrefetchPixelCacheNexusPixels(const NexusInfo *nexus_info,
   MagickCachePrefetch((unsigned char *) nexus_info->pixels,1,1);
 }
 
-static Quantum *SetPixelCacheNexusPixels(const Image *image,const MapMode mode,
-  const RectangleInfo *region,NexusInfo *nexus_info,ExceptionInfo *exception)
+static Quantum *SetPixelCacheNexusPixels(const CacheInfo *cache_info,
+  const MapMode mode,const RectangleInfo *region,NexusInfo *nexus_info,
+  ExceptionInfo *exception)
 {
-  CacheInfo
-    *cache_info;
-
   MagickBooleanType
     status;
 
@@ -4804,12 +4588,12 @@ static Quantum *SetPixelCacheNexusPixels(const Image *image,const MapMode mode,
     length,
     number_pixels;
 
-  cache_info=(CacheInfo *) image->cache;
+  assert(cache_info != (const CacheInfo *) NULL);
   assert(cache_info->signature == MagickSignature);
   if (cache_info->type == UndefinedCache)
     return((Quantum *) NULL);
   nexus_info->region=(*region);
-  if ((cache_info->type != DiskCache) && (cache_info->type != PingCache))
+  if ((cache_info->type == MemoryCache) || (cache_info->type == MapCache))
     {
       ssize_t
         x,
@@ -4838,11 +4622,13 @@ static Quantum *SetPixelCacheNexusPixels(const Image *image,const MapMode mode,
             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;
@@ -4860,7 +4646,7 @@ static Quantum *SetPixelCacheNexusPixels(const Image *image,const MapMode mode,
         }
     }
   else
-    if (nexus_info->length != length)
+    if (nexus_info->length < length)
       {
         RelinquishCacheNexusPixels(nexus_info);
         nexus_info->length=length;
@@ -4877,6 +4663,8 @@ static Quantum *SetPixelCacheNexusPixels(const Image *image,const MapMode mode,
     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
@@ -4914,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;
@@ -4970,7 +4758,7 @@ MagickPrivate VirtualPixelMethod SetPixelCacheVirtualMethod(Image *image,
   const VirtualPixelMethod virtual_pixel_method,ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   VirtualPixelMethod
     method;
@@ -4994,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:
@@ -5039,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;
@@ -5058,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);
@@ -5099,7 +4887,7 @@ static MagickBooleanType SyncAuthenticPixelsCache(Image *image,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
@@ -5149,7 +4937,7 @@ MagickExport MagickBooleanType SyncAuthenticPixels(Image *image,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   const int
     id = GetOpenMPThreadId();
@@ -5206,7 +4994,7 @@ MagickPrivate MagickBooleanType SyncImagePixelCache(Image *image,
   ExceptionInfo *exception)
 {
   CacheInfo
-    *cache_info;
+    *restrict cache_info;
 
   assert(image != (Image *) NULL);
   assert(exception != (ExceptionInfo *) NULL);
@@ -5243,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,
@@ -5264,14 +5052,15 @@ 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;
   length=(MagickSizeType) nexus_info->region.width*
     cache_info->metacontent_extent;
+  extent=(MagickSizeType) length*nexus_info->region.height;
   rows=nexus_info->region.height;
-  extent=(MagickSizeType) length*rows;
+  y=0;
   p=(unsigned char *) nexus_info->metacontent;
   switch (cache_info->type)
   {
@@ -5325,30 +5114,55 @@ static MagickBooleanType WritePixelCacheMetacontent(CacheInfo *cache_info,
         count=WritePixelCacheRegion(cache_info,cache_info->offset+extent*
           cache_info->number_channels*sizeof(Quantum)+offset*
           cache_info->metacontent_extent,length,(const unsigned char *) p);
-        if ((MagickSizeType) count != length)
+        if (count != (MagickOffsetType) length)
           break;
-        p+=nexus_info->region.width*cache_info->metacontent_extent;
+        p+=cache_info->metacontent_extent*nexus_info->region.width;
         offset+=cache_info->columns;
       }
       if (IsFileDescriptorLimitExceeded() != MagickFalse)
         (void) ClosePixelCacheOnDisk(cache_info);
       UnlockSemaphoreInfo(cache_info->file_semaphore);
-      if (y < (ssize_t) rows)
-        {
-          ThrowFileException(exception,CacheError,"UnableToWritePixelCache",
-            cache_info->cache_filename);
-          return(MagickFalse);
-        }
       break;
     }
     case DistributedCache:
     {
-      abort();
+      RectangleInfo
+        region;
+
+      /*
+        Write metacontent to distributed cache.
+      */
+      LockSemaphoreInfo(cache_info->file_semaphore);
+      region=nexus_info->region;
+      if ((cache_info->columns != nexus_info->region.width) ||
+          (extent > MagickMaxBufferExtent))
+        region.height=1UL;
+      else
+        {
+          length=extent;
+          rows=1UL;
+        }
+      for (y=0; y < (ssize_t) rows; y++)
+      {
+        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;
+        region.y++;
+      }
+      UnlockSemaphoreInfo(cache_info->file_semaphore);
       break;
     }
     default:
       break;
   }
+  if (y < (ssize_t) rows)
+    {
+      ThrowFileException(exception,CacheError,"UnableToWritePixelCache",
+        cache_info->cache_filename);
+      return(MagickFalse);
+    }
   if ((cache_info->debug != MagickFalse) &&
       (CacheTick(nexus_info->region.y,cache_info->rows) != MagickFalse))
     (void) LogMagickEvent(CacheEvent,GetMagickModule(),
@@ -5386,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,
@@ -5406,14 +5220,15 @@ 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;
-  length=(MagickSizeType) nexus_info->region.width*cache_info->number_channels*
+  length=(MagickSizeType) cache_info->number_channels*nexus_info->region.width*
     sizeof(Quantum);
+  extent=length*nexus_info->region.height;
   rows=nexus_info->region.height;
-  extent=length*rows;
+  y=0;
   p=nexus_info->pixels;
   switch (cache_info->type)
   {
@@ -5436,7 +5251,7 @@ static MagickBooleanType WritePixelCachePixels(CacheInfo *cache_info,
       for (y=0; y < (ssize_t) rows; y++)
       {
         (void) memcpy(q,p,(size_t) length);
-        p+=nexus_info->region.width*cache_info->number_channels;
+        p+=cache_info->number_channels*nexus_info->region.width;
         q+=cache_info->columns*cache_info->number_channels;
       }
       break;
@@ -5465,30 +5280,55 @@ static MagickBooleanType WritePixelCachePixels(CacheInfo *cache_info,
         count=WritePixelCacheRegion(cache_info,cache_info->offset+offset*
           cache_info->number_channels*sizeof(*p),length,(const unsigned char *)
           p);
-        if ((MagickSizeType) count != length)
+        if (count != (MagickOffsetType) length)
           break;
-        p+=nexus_info->region.width*cache_info->number_channels;
+        p+=cache_info->number_channels*nexus_info->region.width;
         offset+=cache_info->columns;
       }
       if (IsFileDescriptorLimitExceeded() != MagickFalse)
         (void) ClosePixelCacheOnDisk(cache_info);
       UnlockSemaphoreInfo(cache_info->file_semaphore);
-      if (y < (ssize_t) rows)
-        {
-          ThrowFileException(exception,CacheError,"UnableToWritePixelCache",
-            cache_info->cache_filename);
-          return(MagickFalse);
-        }
       break;
     }
     case DistributedCache:
     {
-      abort();
+      RectangleInfo
+        region;
+
+      /*
+        Write pixels to distributed cache.
+      */
+      LockSemaphoreInfo(cache_info->file_semaphore);
+      region=nexus_info->region;
+      if ((cache_info->columns != nexus_info->region.width) ||
+          (extent > MagickMaxBufferExtent))
+        region.height=1UL;
+      else
+        {
+          length=extent;
+          rows=1UL;
+        }
+      for (y=0; y < (ssize_t) rows; y++)
+      {
+        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;
+        region.y++;
+      }
+      UnlockSemaphoreInfo(cache_info->file_semaphore);
       break;
     }
     default:
       break;
   }
+  if (y < (ssize_t) rows)
+    {
+      ThrowFileException(exception,CacheError,"UnableToWritePixelCache",
+        cache_info->cache_filename);
+      return(MagickFalse);
+    }
   if ((cache_info->debug != MagickFalse) &&
       (CacheTick(nexus_info->region.y,cache_info->rows) != MagickFalse))
     (void) LogMagickEvent(CacheEvent,GetMagickModule(),