43#include "MagickCore/studio.h" 
   44#include "MagickCore/blob.h" 
   45#include "MagickCore/blob-private.h" 
   46#include "MagickCore/cache.h" 
   47#include "MagickCore/cache-private.h" 
   48#include "MagickCore/color-private.h" 
   49#include "MagickCore/colorspace-private.h" 
   50#include "MagickCore/composite-private.h" 
   51#include "MagickCore/distribute-cache-private.h" 
   52#include "MagickCore/exception.h" 
   53#include "MagickCore/exception-private.h" 
   54#include "MagickCore/geometry.h" 
   55#include "MagickCore/list.h" 
   56#include "MagickCore/log.h" 
   57#include "MagickCore/magick.h" 
   58#include "MagickCore/memory_.h" 
   59#include "MagickCore/memory-private.h" 
   60#include "MagickCore/nt-base-private.h" 
   61#include "MagickCore/option.h" 
   62#include "MagickCore/pixel.h" 
   63#include "MagickCore/pixel-accessor.h" 
   64#include "MagickCore/pixel-private.h" 
   65#include "MagickCore/policy.h" 
   66#include "MagickCore/quantum.h" 
   67#include "MagickCore/random_.h" 
   68#include "MagickCore/registry.h" 
   69#include "MagickCore/resource_.h" 
   70#include "MagickCore/semaphore.h" 
   71#include "MagickCore/splay-tree.h" 
   72#include "MagickCore/string_.h" 
   73#include "MagickCore/string-private.h" 
   74#include "MagickCore/timer-private.h" 
   75#include "MagickCore/thread-private.h" 
   76#include "MagickCore/utility.h" 
   77#include "MagickCore/utility-private.h" 
   78#if defined(MAGICKCORE_HAVE_SYS_LOADAVG_H) 
   79#  include <sys/loadavg.h> 
   81#if defined(MAGICKCORE_ZLIB_DELEGATE) 
   88#define CacheTick(offset,extent)  QuantumTick((MagickOffsetType) offset,extent) 
   89#define IsFileDescriptorLimitExceeded() (GetMagickResource(FileResource) > \ 
   90  GetMagickResourceLimit(FileResource) ? MagickTrue : MagickFalse) 
  105#if defined(__cplusplus) || defined(c_plusplus) 
  110  GetImagePixelCache(Image *,
const MagickBooleanType,ExceptionInfo *)
 
  114  *GetVirtualPixelCache(
const Image *,
const VirtualPixelMethod,
const ssize_t,
 
  115    const ssize_t,
const size_t,
const size_t,ExceptionInfo *),
 
  116  *GetVirtualPixelsCache(
const Image *);
 
  119  *GetVirtualMetacontentFromCache(
const Image *);
 
  121static MagickBooleanType
 
  122  GetOneAuthenticPixelFromCache(Image *,
const ssize_t,
const ssize_t,Quantum *,
 
  124  GetOneVirtualPixelFromCache(
const Image *,
const VirtualPixelMethod,
 
  125    const ssize_t,
const ssize_t,Quantum *,ExceptionInfo *),
 
  126  OpenPixelCache(Image *,
const MapMode,ExceptionInfo *),
 
  127  OpenPixelCacheOnDisk(CacheInfo *,
const MapMode),
 
  128  ReadPixelCachePixels(CacheInfo *magick_restrict,NexusInfo *magick_restrict,
 
  130  ReadPixelCacheMetacontent(CacheInfo *magick_restrict,
 
  131    NexusInfo *magick_restrict,ExceptionInfo *),
 
  132  SyncAuthenticPixelsCache(Image *,ExceptionInfo *),
 
  133  WritePixelCachePixels(CacheInfo *magick_restrict,NexusInfo *magick_restrict,
 
  135  WritePixelCacheMetacontent(CacheInfo *,NexusInfo *magick_restrict,
 
  139  *GetAuthenticPixelsCache(Image *,
const ssize_t,
const ssize_t,
const size_t,
 
  140    const size_t,ExceptionInfo *),
 
  141  *QueueAuthenticPixelsCache(Image *,
const ssize_t,
const ssize_t,
const size_t,
 
  142    const size_t,ExceptionInfo *),
 
  143  *SetPixelCacheNexusPixels(
const CacheInfo *magick_restrict,
const MapMode,
 
  144    const ssize_t,
const ssize_t,
const size_t,
const size_t,
 
  145    const MagickBooleanType,NexusInfo *magick_restrict,ExceptionInfo *)
 
  148#if defined(MAGICKCORE_OPENCL_SUPPORT) 
  150  CopyOpenCLBuffer(CacheInfo *magick_restrict);
 
  153#if defined(__cplusplus) || defined(c_plusplus) 
  164  cache_anonymous_memory = (-1);
 
  188MagickPrivate Cache AcquirePixelCache(
const size_t number_threads)
 
  191    *magick_restrict cache_info;
 
  196  cache_info=(CacheInfo *) AcquireAlignedMemory(1,
sizeof(*cache_info));
 
  197  if (cache_info == (CacheInfo *) NULL)
 
  198    ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
 
  199  (void) memset(cache_info,0,
sizeof(*cache_info));
 
  200  cache_info->type=UndefinedCache;
 
  201  cache_info->mode=IOMode;
 
  202  cache_info->disk_mode=IOMode;
 
  203  cache_info->colorspace=sRGBColorspace;
 
  204  cache_info->file=(-1);
 
  205  cache_info->id=GetMagickThreadId();
 
  206  cache_info->number_threads=number_threads;
 
  207  if (GetOpenMPMaximumThreads() > cache_info->number_threads)
 
  208    cache_info->number_threads=GetOpenMPMaximumThreads();
 
  209  if (cache_info->number_threads == 0)
 
  210    cache_info->number_threads=1;
 
  211  cache_info->nexus_info=AcquirePixelCacheNexus(cache_info->number_threads);
 
  212  value=GetEnvironmentValue(
"MAGICK_SYNCHRONIZE");
 
  213  if (value != (
const char *) NULL)
 
  215      cache_info->synchronize=IsStringTrue(value);
 
  216      value=DestroyString(value);
 
  218  value=GetPolicyValue(
"cache:synchronize");
 
  219  if (value != (
const char *) NULL)
 
  221      cache_info->synchronize=IsStringTrue(value);
 
  222      value=DestroyString(value);
 
  224  cache_info->width_limit=MagickMin(GetMagickResourceLimit(WidthResource),
 
  225    (MagickSizeType) MAGICK_SSIZE_MAX);
 
  226  cache_info->height_limit=MagickMin(GetMagickResourceLimit(HeightResource),
 
  227    (MagickSizeType) MAGICK_SSIZE_MAX);
 
  228  cache_info->semaphore=AcquireSemaphoreInfo();
 
  229  cache_info->reference_count=1;
 
  230  cache_info->file_semaphore=AcquireSemaphoreInfo();
 
  231  cache_info->debug=(GetLogEventMask() & CacheEvent) != 0 ? MagickTrue :
 
  233  cache_info->signature=MagickCoreSignature;
 
  234  return((Cache ) cache_info);
 
  259MagickPrivate NexusInfo **AcquirePixelCacheNexus(
const size_t number_threads)
 
  262    **magick_restrict nexus_info;
 
  267  nexus_info=(NexusInfo **) MagickAssumeAligned(AcquireAlignedMemory(2*
 
  268    number_threads,
sizeof(*nexus_info)));
 
  269  if (nexus_info == (NexusInfo **) NULL)
 
  270    ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
 
  271  *nexus_info=(NexusInfo *) AcquireQuantumMemory(number_threads,
 
  272    2*
sizeof(**nexus_info));
 
  273  if (*nexus_info == (NexusInfo *) NULL)
 
  274    ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
 
  275  (void) memset(*nexus_info,0,2*number_threads*
sizeof(**nexus_info));
 
  276  for (i=0; i < (ssize_t) (2*number_threads); i++)
 
  278    nexus_info[i]=(*nexus_info+i);
 
  279    if (i < (ssize_t) number_threads)
 
  280      nexus_info[i]->virtual_nexus=(*nexus_info+number_threads+i);
 
  281    nexus_info[i]->signature=MagickCoreSignature;
 
  314MagickExport 
void *AcquirePixelCachePixels(
const Image *image,
size_t *length,
 
  315  ExceptionInfo *exception)
 
  318    *magick_restrict cache_info;
 
  320  assert(image != (
const Image *) NULL);
 
  321  assert(image->signature == MagickCoreSignature);
 
  322  assert(exception != (ExceptionInfo *) NULL);
 
  323  assert(exception->signature == MagickCoreSignature);
 
  324  assert(image->cache != (Cache) NULL);
 
  326  cache_info=(CacheInfo *) image->cache;
 
  327  assert(cache_info->signature == MagickCoreSignature);
 
  329  if ((cache_info->type != MemoryCache) && (cache_info->type != MapCache))
 
  330    return((
void *) NULL);
 
  331  *length=(size_t) cache_info->length;
 
  332  return(cache_info->pixels);
 
  353MagickPrivate MagickBooleanType CacheComponentGenesis(
void)
 
  356    cache_semaphore=AcquireSemaphoreInfo();
 
  378MagickPrivate 
void CacheComponentTerminus(
void)
 
  381    ActivateSemaphoreInfo(&cache_semaphore);
 
  383  RelinquishSemaphoreInfo(&cache_semaphore);
 
  415static MagickBooleanType ClipPixelCacheNexus(Image *image,
 
  416  NexusInfo *nexus_info,ExceptionInfo *exception)
 
  419    *magick_restrict cache_info;
 
  431  if (IsEventLogging() != MagickFalse)
 
  432    (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
 
  433  if ((image->channels & WriteMaskChannel) == 0)
 
  435  if ((nexus_info->region.width == 0) || (nexus_info->region.height == 0))
 
  437  cache_info=(CacheInfo *) image->cache;
 
  438  if (cache_info == (CacheInfo *) NULL)
 
  440  p=GetAuthenticPixelCacheNexus(image,nexus_info->region.x,nexus_info->region.y,
 
  441    nexus_info->region.width,nexus_info->region.height,
 
  442    nexus_info->virtual_nexus,exception);
 
  443  q=nexus_info->pixels;
 
  444  if ((p == (Quantum *) NULL) || (q == (Quantum *) NULL))
 
  446  for (y=0; y < (ssize_t) nexus_info->region.height; y++)
 
  451    for (x=0; x < (ssize_t) nexus_info->region.width; x++)
 
  459      mask_alpha=QuantumScale*(double) GetPixelWriteMask(image,p);
 
  460      if (fabs(mask_alpha) >= MagickEpsilon)
 
  462          for (i=0; i < (ssize_t) image->number_channels; i++)
 
  464            PixelChannel channel = GetPixelChannelChannel(image,i);
 
  465            PixelTrait traits = GetPixelChannelTraits(image,channel);
 
  466            if ((traits & UpdatePixelTrait) == 0)
 
  468            q[i]=ClampToQuantum(MagickOver_((
double) p[i],mask_alpha*(
double)
 
  469              GetPixelAlpha(image,p),(
double) q[i],(
double)
 
  470              GetPixelAlpha(image,q)));
 
  472          SetPixelAlpha(image,GetPixelAlpha(image,p),q);
 
  474      p+=(ptrdiff_t) GetPixelChannels(image);
 
  475      q+=(ptrdiff_t) GetPixelChannels(image);
 
  503MagickPrivate Cache ClonePixelCache(
const Cache cache)
 
  506    *magick_restrict clone_info;
 
  509    *magick_restrict cache_info;
 
  511  assert(cache != NULL);
 
  512  cache_info=(
const CacheInfo *) cache;
 
  513  assert(cache_info->signature == MagickCoreSignature);
 
  514  if (IsEventLogging() != MagickFalse)
 
  515    (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
 
  516      cache_info->filename);
 
  517  clone_info=(CacheInfo *) AcquirePixelCache(cache_info->number_threads);
 
  518  clone_info->virtual_pixel_method=cache_info->virtual_pixel_method;
 
  519  return((Cache ) clone_info);
 
  547MagickPrivate 
void ClonePixelCacheMethods(Cache clone,
const Cache cache)
 
  550    *magick_restrict cache_info,
 
  551    *magick_restrict source_info;
 
  553  assert(clone != (Cache) NULL);
 
  554  source_info=(CacheInfo *) clone;
 
  555  assert(source_info->signature == MagickCoreSignature);
 
  556  if (IsEventLogging() != MagickFalse)
 
  557    (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
 
  558      source_info->filename);
 
  559  assert(cache != (Cache) NULL);
 
  560  cache_info=(CacheInfo *) cache;
 
  561  assert(cache_info->signature == MagickCoreSignature);
 
  562  source_info->methods=cache_info->methods;
 
  594static MagickBooleanType ClonePixelCacheOnDisk(
 
  595  CacheInfo *magick_restrict cache_info,CacheInfo *magick_restrict clone_info)
 
  615  if ((OpenPixelCacheOnDisk(cache_info,ReadMode) == MagickFalse) ||
 
  616      (OpenPixelCacheOnDisk(clone_info,IOMode) == MagickFalse))
 
  618  if ((lseek(cache_info->file,0,SEEK_SET) < 0) ||
 
  619      (lseek(clone_info->file,0,SEEK_SET) < 0))
 
  621  quantum=(size_t) MagickMaxBufferExtent;
 
  622  if ((fstat(cache_info->file,&file_stats) == 0) && (file_stats.st_size > 0))
 
  624#if defined(MAGICKCORE_HAVE_LINUX_SENDFILE) 
  625      if (cache_info->length < 0x7ffff000)
 
  627          count=sendfile(clone_info->file,cache_info->file,(off_t *) NULL,
 
  628            (
size_t) cache_info->length);
 
  629          if (count == (ssize_t) cache_info->length)
 
  631          if ((lseek(cache_info->file,0,SEEK_SET) < 0) ||
 
  632              (lseek(clone_info->file,0,SEEK_SET) < 0))
 
  636      quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
 
  638  buffer=(
unsigned char *) AcquireQuantumMemory(quantum,
sizeof(*buffer));
 
  639  if (buffer == (
unsigned char *) NULL)
 
  640    ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
 
  642  while ((count=read(cache_info->file,buffer,quantum)) > 0)
 
  647    number_bytes=write(clone_info->file,buffer,(
size_t) count);
 
  648    if (number_bytes != count)
 
  650    extent+=(size_t) number_bytes;
 
  652  buffer=(
unsigned char *) RelinquishMagickMemory(buffer);
 
  653  if (extent != cache_info->length)
 
  658#if defined(MAGICKCORE_OPENMP_SUPPORT) 
  659static inline int GetCacheNumberThreads(
const CacheInfo *source,
 
  660  const CacheInfo *destination,
const size_t chunk,
const int factor)
 
  663    max_threads = (size_t) GetMagickResourceLimit(ThreadResource),
 
  664    number_threads = 1UL,
 
  665    workload_factor = 64UL << factor;
 
  670  number_threads=(chunk <= workload_factor) ? 1UL :
 
  671    (chunk >= (workload_factor << 6)) ? max_threads :
 
  672    1UL+(chunk-workload_factor)*(max_threads-1L)/(((workload_factor << 6))-1L);
 
  676  if (((source->type != MemoryCache) && (source->type != MapCache)) ||
 
  677      ((destination->type != MemoryCache) && (destination->type != MapCache)))
 
  678    number_threads=MagickMin(number_threads,4);
 
  679  return((
int) number_threads);
 
  683static MagickBooleanType ClonePixelCacheRepository(
 
  684  CacheInfo *magick_restrict clone_info,CacheInfo *magick_restrict cache_info,
 
  685  ExceptionInfo *exception)
 
  687#define cache_number_threads(source,destination,chunk,factor) \ 
  688  num_threads(GetCacheNumberThreads((source),(destination),(chunk),(factor))) 
  695    **magick_restrict cache_nexus,
 
  696    **magick_restrict clone_nexus;
 
  704  assert(cache_info != (CacheInfo *) NULL);
 
  705  assert(clone_info != (CacheInfo *) NULL);
 
  706  assert(exception != (ExceptionInfo *) NULL);
 
  707  if (cache_info->type == PingCache)
 
  709  length=cache_info->number_channels*
sizeof(*cache_info->channel_map);
 
  710  if ((cache_info->storage_class == clone_info->storage_class) &&
 
  711      (cache_info->colorspace == clone_info->colorspace) &&
 
  712      (cache_info->alpha_trait == clone_info->alpha_trait) &&
 
  713      (cache_info->channels == clone_info->channels) &&
 
  714      (cache_info->columns == clone_info->columns) &&
 
  715      (cache_info->rows == clone_info->rows) &&
 
  716      (cache_info->number_channels == clone_info->number_channels) &&
 
  717      (memcmp(cache_info->channel_map,clone_info->channel_map,length) == 0) &&
 
  718      (cache_info->metacontent_extent == clone_info->metacontent_extent))
 
  723      if (((cache_info->type == MemoryCache) ||
 
  724           (cache_info->type == MapCache)) &&
 
  725          ((clone_info->type == MemoryCache) || (clone_info->type == MapCache)))
 
  727          (void) memcpy(clone_info->pixels,cache_info->pixels,
 
  728            cache_info->number_channels*cache_info->columns*cache_info->rows*
 
  729            sizeof(*cache_info->pixels));
 
  730          if ((cache_info->metacontent_extent != 0) &&
 
  731              (clone_info->metacontent_extent != 0))
 
  732            (void) memcpy(clone_info->metacontent,cache_info->metacontent,
 
  733              cache_info->columns*cache_info->rows*
 
  734              clone_info->metacontent_extent*
sizeof(
unsigned char));
 
  737      if ((cache_info->type == DiskCache) && (clone_info->type == DiskCache))
 
  738        return(ClonePixelCacheOnDisk(cache_info,clone_info));
 
  743  cache_nexus=AcquirePixelCacheNexus(cache_info->number_threads);
 
  744  clone_nexus=AcquirePixelCacheNexus(clone_info->number_threads);
 
  745  length=cache_info->number_channels*
sizeof(*cache_info->channel_map);
 
  746  optimize=(cache_info->number_channels == clone_info->number_channels) &&
 
  747    (memcmp(cache_info->channel_map,clone_info->channel_map,length) == 0) ?
 
  748    MagickTrue : MagickFalse;
 
  749  length=(size_t) MagickMin(cache_info->number_channels*cache_info->columns,
 
  750    clone_info->number_channels*clone_info->columns);
 
  752#if defined(MAGICKCORE_OPENMP_SUPPORT) 
  753  #pragma omp parallel for schedule(static) shared(status) \ 
  754    cache_number_threads(cache_info,clone_info,cache_info->rows,3) 
  756  for (y=0; y < (ssize_t) cache_info->rows; y++)
 
  759      id = GetOpenMPThreadId();
 
  767    if (status == MagickFalse)
 
  769    if (y >= (ssize_t) clone_info->rows)
 
  771    pixels=SetPixelCacheNexusPixels(cache_info,ReadMode,0,y,
 
  772      cache_info->columns,1,MagickFalse,cache_nexus[
id],exception);
 
  773    if (pixels == (Quantum *) NULL)
 
  775    status=ReadPixelCachePixels(cache_info,cache_nexus[
id],exception);
 
  776    if (status == MagickFalse)
 
  778    pixels=SetPixelCacheNexusPixels(clone_info,WriteMode,0,y,
 
  779      clone_info->columns,1,MagickFalse,clone_nexus[
id],exception);
 
  780    if (pixels == (Quantum *) NULL)
 
  782    (void) memset(clone_nexus[
id]->pixels,0,(
size_t) clone_nexus[
id]->length);
 
  783    if (optimize != MagickFalse)
 
  784      (void) memcpy(clone_nexus[
id]->pixels,cache_nexus[
id]->pixels,length*
 
  797        p=cache_nexus[id]->pixels;
 
  798        q=clone_nexus[id]->pixels;
 
  799        for (x=0; x < (ssize_t) cache_info->columns; x++)
 
  804          if (x == (ssize_t) clone_info->columns)
 
  806          for (i=0; i < (ssize_t) clone_info->number_channels; i++)
 
  814            channel=clone_info->channel_map[i].channel;
 
  815            traits=cache_info->channel_map[channel].traits;
 
  816            if (traits != UndefinedPixelTrait)
 
  817              *q=*(p+cache_info->channel_map[channel].offset);
 
  820          p+=(ptrdiff_t) cache_info->number_channels;
 
  823    status=WritePixelCachePixels(clone_info,clone_nexus[
id],exception);
 
  825  if ((cache_info->metacontent_extent != 0) &&
 
  826      (clone_info->metacontent_extent != 0))
 
  831      length=(size_t) MagickMin(cache_info->metacontent_extent,
 
  832        clone_info->metacontent_extent);
 
  833#if defined(MAGICKCORE_OPENMP_SUPPORT) 
  834      #pragma omp parallel for schedule(static) shared(status) \ 
  835        cache_number_threads(cache_info,clone_info,cache_info->rows,3) 
  837      for (y=0; y < (ssize_t) cache_info->rows; y++)
 
  840          id = GetOpenMPThreadId();
 
  845        if (status == MagickFalse)
 
  847        if (y >= (ssize_t) clone_info->rows)
 
  849        pixels=SetPixelCacheNexusPixels(cache_info,ReadMode,0,y,
 
  850          cache_info->columns,1,MagickFalse,cache_nexus[
id],exception);
 
  851        if (pixels == (Quantum *) NULL)
 
  853        status=ReadPixelCacheMetacontent(cache_info,cache_nexus[
id],exception);
 
  854        if (status == MagickFalse)
 
  856        pixels=SetPixelCacheNexusPixels(clone_info,WriteMode,0,y,
 
  857          clone_info->columns,1,MagickFalse,clone_nexus[
id],exception);
 
  858        if (pixels == (Quantum *) NULL)
 
  860        if ((clone_nexus[
id]->metacontent != (
void *) NULL) &&
 
  861            (cache_nexus[
id]->metacontent != (
void *) NULL))
 
  862          (void) memcpy(clone_nexus[
id]->metacontent,
 
  863            cache_nexus[
id]->metacontent,length*
sizeof(
unsigned char));
 
  864        status=WritePixelCacheMetacontent(clone_info,clone_nexus[
id],exception);
 
  867  clone_nexus=DestroyPixelCacheNexus(clone_nexus,clone_info->number_threads);
 
  868  cache_nexus=DestroyPixelCacheNexus(cache_nexus,cache_info->number_threads);
 
  869  if (cache_info->debug != MagickFalse)
 
  872        message[MagickPathExtent];
 
  874      (void) FormatLocaleString(message,MagickPathExtent,
"%s => %s",
 
  875        CommandOptionToMnemonic(MagickCacheOptions,(ssize_t) cache_info->type),
 
  876        CommandOptionToMnemonic(MagickCacheOptions,(ssize_t) clone_info->type));
 
  877      (void) LogMagickEvent(CacheEvent,GetMagickModule(),
"%s",message);
 
  904static void DestroyImagePixelCache(Image *image)
 
  906  assert(image != (Image *) NULL);
 
  907  assert(image->signature == MagickCoreSignature);
 
  908  if (IsEventLogging() != MagickFalse)
 
  909    (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
 
  910  if (image->cache != (
void *) NULL)
 
  911    image->cache=DestroyPixelCache(image->cache);
 
  936MagickExport 
void DestroyImagePixels(Image *image)
 
  939    *magick_restrict cache_info;
 
  941  assert(image != (
const Image *) NULL);
 
  942  assert(image->signature == MagickCoreSignature);
 
  943  if (IsEventLogging() != MagickFalse)
 
  944    (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
 
  945  assert(image->cache != (Cache) NULL);
 
  946  cache_info=(CacheInfo *) image->cache;
 
  947  assert(cache_info->signature == MagickCoreSignature);
 
  948  if (cache_info->methods.destroy_pixel_handler != (DestroyPixelHandler) NULL)
 
  950      cache_info->methods.destroy_pixel_handler(image);
 
  953  image->cache=DestroyPixelCache(image->cache);
 
  979static MagickBooleanType ClosePixelCacheOnDisk(CacheInfo *cache_info)
 
  985  if (cache_info->file != -1)
 
  987      status=close_utf8(cache_info->file);
 
  988      cache_info->file=(-1);
 
  989      RelinquishMagickResource(FileResource,1);
 
  991  return(status == -1 ? MagickFalse : MagickTrue);
 
  994static inline void RelinquishPixelCachePixels(CacheInfo *cache_info)
 
  996  switch (cache_info->type)
 
 1000      (void) ShredMagickMemory(cache_info->pixels,(
size_t) cache_info->length);
 
 1001#if defined(MAGICKCORE_OPENCL_SUPPORT) 
 1002      if (cache_info->opencl != (MagickCLCacheInfo) NULL)
 
 1004          cache_info->opencl=RelinquishMagickCLCacheInfo(cache_info->opencl,
 
 1006          cache_info->pixels=(Quantum *) NULL;
 
 1010      if (cache_info->mapped == MagickFalse)
 
 1011        cache_info->pixels=(Quantum *) RelinquishAlignedMemory(
 
 1012          cache_info->pixels);
 
 1015          (void) UnmapBlob(cache_info->pixels,(
size_t) cache_info->length);
 
 1016          cache_info->pixels=(Quantum *) NULL;
 
 1018      RelinquishMagickResource(MemoryResource,cache_info->length);
 
 1023      (void) UnmapBlob(cache_info->pixels,(
size_t) cache_info->length);
 
 1024      cache_info->pixels=(Quantum *) NULL;
 
 1025      if ((cache_info->mode != ReadMode) && (cache_info->mode != PersistMode))
 
 1026        (void) RelinquishUniqueFileResource(cache_info->cache_filename);
 
 1027      *cache_info->cache_filename=
'\0';
 
 1028      RelinquishMagickResource(MapResource,cache_info->length);
 
 1033      if (cache_info->file != -1)
 
 1034        (void) ClosePixelCacheOnDisk(cache_info);
 
 1035      if ((cache_info->mode != ReadMode) && (cache_info->mode != PersistMode))
 
 1036        (void) RelinquishUniqueFileResource(cache_info->cache_filename);
 
 1037      *cache_info->cache_filename=
'\0';
 
 1038      RelinquishMagickResource(DiskResource,cache_info->length);
 
 1041    case DistributedCache:
 
 1043      *cache_info->cache_filename=
'\0';
 
 1044      (void) RelinquishDistributePixelCache((DistributeCacheInfo *)
 
 1045        cache_info->server_info);
 
 1051  cache_info->type=UndefinedCache;
 
 1052  cache_info->mapped=MagickFalse;
 
 1053  cache_info->metacontent=(
void *) NULL;
 
 1056MagickPrivate Cache DestroyPixelCache(Cache cache)
 
 1059    *magick_restrict cache_info;
 
 1061  assert(cache != (Cache) NULL);
 
 1062  cache_info=(CacheInfo *) cache;
 
 1063  assert(cache_info->signature == MagickCoreSignature);
 
 1064  if (IsEventLogging() != MagickFalse)
 
 1065    (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
 
 1066      cache_info->filename);
 
 1067  LockSemaphoreInfo(cache_info->semaphore);
 
 1068  cache_info->reference_count--;
 
 1069  if (cache_info->reference_count != 0)
 
 1071      UnlockSemaphoreInfo(cache_info->semaphore);
 
 1072      return((Cache) NULL);
 
 1074  UnlockSemaphoreInfo(cache_info->semaphore);
 
 1075  if (cache_info->debug != MagickFalse)
 
 1078        message[MagickPathExtent];
 
 1080      (void) FormatLocaleString(message,MagickPathExtent,
"destroy %s",
 
 1081        cache_info->filename);
 
 1082      (void) LogMagickEvent(CacheEvent,GetMagickModule(),
"%s",message);
 
 1084  RelinquishPixelCachePixels(cache_info);
 
 1085  if (cache_info->server_info != (DistributeCacheInfo *) NULL)
 
 1086    cache_info->server_info=DestroyDistributeCacheInfo((DistributeCacheInfo *)
 
 1087      cache_info->server_info);
 
 1088  if (cache_info->nexus_info != (NexusInfo **) NULL)
 
 1089    cache_info->nexus_info=DestroyPixelCacheNexus(cache_info->nexus_info,
 
 1090      cache_info->number_threads);
 
 1091  if (cache_info->random_info != (RandomInfo *) NULL)
 
 1092    cache_info->random_info=DestroyRandomInfo(cache_info->random_info);
 
 1094    RelinquishSemaphoreInfo(&cache_info->file_semaphore);
 
 1096    RelinquishSemaphoreInfo(&cache_info->semaphore);
 
 1097  cache_info->signature=(~MagickCoreSignature);
 
 1098  cache_info=(CacheInfo *) RelinquishAlignedMemory(cache_info);
 
 1129static inline void RelinquishCacheNexusPixels(NexusInfo *nexus_info)
 
 1131  if (nexus_info->mapped == MagickFalse)
 
 1132    (void) RelinquishAlignedMemory(nexus_info->cache);
 
 1134    (
void) UnmapBlob(nexus_info->cache,(
size_t) nexus_info->length);
 
 1135  nexus_info->cache=(Quantum *) NULL;
 
 1136  nexus_info->pixels=(Quantum *) NULL;
 
 1137  nexus_info->metacontent=(
void *) NULL;
 
 1138  nexus_info->length=0;
 
 1139  nexus_info->mapped=MagickFalse;
 
 1142MagickPrivate NexusInfo **DestroyPixelCacheNexus(NexusInfo **nexus_info,
 
 1143  const size_t number_threads)
 
 1148  assert(nexus_info != (NexusInfo **) NULL);
 
 1149  for (i=0; i < (ssize_t) (2*number_threads); i++)
 
 1151    if (nexus_info[i]->cache != (Quantum *) NULL)
 
 1152      RelinquishCacheNexusPixels(nexus_info[i]);
 
 1153    nexus_info[i]->signature=(~MagickCoreSignature);
 
 1155  *nexus_info=(NexusInfo *) RelinquishMagickMemory(*nexus_info);
 
 1156  nexus_info=(NexusInfo **) RelinquishAlignedMemory(nexus_info);
 
 1185MagickExport 
void *GetAuthenticMetacontent(
const Image *image)
 
 1188    *magick_restrict cache_info;
 
 1191    id = GetOpenMPThreadId();
 
 1193  assert(image != (
const Image *) NULL);
 
 1194  assert(image->signature == MagickCoreSignature);
 
 1195  assert(image->cache != (Cache) NULL);
 
 1196  cache_info=(CacheInfo *) image->cache;
 
 1197  assert(cache_info->signature == MagickCoreSignature);
 
 1198  if (cache_info->methods.get_authentic_metacontent_from_handler !=
 
 1199      (GetAuthenticMetacontentFromHandler) NULL)
 
 1204      metacontent=cache_info->methods.
 
 1205        get_authentic_metacontent_from_handler(image);
 
 1206      return(metacontent);
 
 1208  assert(
id < (
int) cache_info->number_threads);
 
 1209  return(cache_info->nexus_info[
id]->metacontent);
 
 1236static void *GetAuthenticMetacontentFromCache(
const Image *image)
 
 1239    *magick_restrict cache_info;
 
 1242    id = GetOpenMPThreadId();
 
 1244  assert(image != (
const Image *) NULL);
 
 1245  assert(image->signature == MagickCoreSignature);
 
 1246  assert(image->cache != (Cache) NULL);
 
 1247  cache_info=(CacheInfo *) image->cache;
 
 1248  assert(cache_info->signature == MagickCoreSignature);
 
 1249  assert(
id < (
int) cache_info->number_threads);
 
 1250  return(cache_info->nexus_info[
id]->metacontent);
 
 1253#if defined(MAGICKCORE_OPENCL_SUPPORT) 
 1282MagickPrivate cl_mem GetAuthenticOpenCLBuffer(
const Image *image,
 
 1283  MagickCLDevice device,ExceptionInfo *exception)
 
 1286    *magick_restrict cache_info;
 
 1288  assert(image != (
const Image *) NULL);
 
 1289  assert(device != (
const MagickCLDevice) NULL);
 
 1290  cache_info=(CacheInfo *) image->cache;
 
 1291  if ((cache_info->type == UndefinedCache) || (cache_info->reference_count > 1))
 
 1293      SyncImagePixelCache((Image *) image,exception);
 
 1294      cache_info=(CacheInfo *) image->cache;
 
 1296  if ((cache_info->type != MemoryCache) || (cache_info->mapped != MagickFalse))
 
 1297    return((cl_mem) NULL);
 
 1298  LockSemaphoreInfo(cache_info->semaphore);
 
 1299  if ((cache_info->opencl != (MagickCLCacheInfo) NULL) &&
 
 1300      (cache_info->opencl->device->context != device->context))
 
 1301    cache_info->opencl=CopyMagickCLCacheInfo(cache_info->opencl);
 
 1302  if (cache_info->opencl == (MagickCLCacheInfo) NULL)
 
 1304      assert(cache_info->pixels != (Quantum *) NULL);
 
 1305      cache_info->opencl=AcquireMagickCLCacheInfo(device,cache_info->pixels,
 
 1306        cache_info->length);
 
 1308  if (cache_info->opencl != (MagickCLCacheInfo) NULL)
 
 1309    RetainOpenCLMemObject(cache_info->opencl->buffer);
 
 1310  UnlockSemaphoreInfo(cache_info->semaphore);
 
 1311  if (cache_info->opencl == (MagickCLCacheInfo) NULL)
 
 1312    return((cl_mem) NULL);
 
 1313  assert(cache_info->opencl->pixels == cache_info->pixels);
 
 1314  return(cache_info->opencl->buffer);
 
 1353MagickPrivate Quantum *GetAuthenticPixelCacheNexus(Image *image,
const ssize_t x,
 
 1354  const ssize_t y,
const size_t columns,
const size_t rows,NexusInfo *nexus_info,
 
 1355  ExceptionInfo *exception)
 
 1358    *magick_restrict cache_info;
 
 1361    *magick_restrict pixels;
 
 1366  assert(image != (Image *) NULL);
 
 1367  assert(image->signature == MagickCoreSignature);
 
 1368  pixels=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickTrue,
 
 1369    nexus_info,exception);
 
 1370  if (pixels == (Quantum *) NULL)
 
 1371    return((Quantum *) NULL);
 
 1372  cache_info=(CacheInfo *) image->cache;
 
 1373  assert(cache_info->signature == MagickCoreSignature);
 
 1374  if (nexus_info->authentic_pixel_cache != MagickFalse)
 
 1376  if (ReadPixelCachePixels(cache_info,nexus_info,exception) == MagickFalse)
 
 1377    return((Quantum *) NULL);
 
 1378  if (cache_info->metacontent_extent != 0)
 
 1379    if (ReadPixelCacheMetacontent(cache_info,nexus_info,exception) == MagickFalse)
 
 1380      return((Quantum *) NULL);
 
 1407static Quantum *GetAuthenticPixelsFromCache(
const Image *image)
 
 1410    *magick_restrict cache_info;
 
 1413    id = GetOpenMPThreadId();
 
 1415  assert(image != (
const Image *) NULL);
 
 1416  assert(image->signature == MagickCoreSignature);
 
 1417  assert(image->cache != (Cache) NULL);
 
 1418  cache_info=(CacheInfo *) image->cache;
 
 1419  assert(cache_info->signature == MagickCoreSignature);
 
 1420  assert(
id < (
int) cache_info->number_threads);
 
 1421  return(cache_info->nexus_info[
id]->pixels);
 
 1448MagickExport Quantum *GetAuthenticPixelQueue(
const Image *image)
 
 1451    *magick_restrict cache_info;
 
 1454    id = GetOpenMPThreadId();
 
 1456  assert(image != (
const Image *) NULL);
 
 1457  assert(image->signature == MagickCoreSignature);
 
 1458  assert(image->cache != (Cache) NULL);
 
 1459  cache_info=(CacheInfo *) image->cache;
 
 1460  assert(cache_info->signature == MagickCoreSignature);
 
 1461  if (cache_info->methods.get_authentic_pixels_from_handler !=
 
 1462       (GetAuthenticPixelsFromHandler) NULL)
 
 1463    return(cache_info->methods.get_authentic_pixels_from_handler(image));
 
 1464  assert(
id < (
int) cache_info->number_threads);
 
 1465  return(cache_info->nexus_info[
id]->pixels);
 
 1513MagickExport Quantum *GetAuthenticPixels(Image *image,
const ssize_t x,
 
 1514  const ssize_t y,
const size_t columns,
const size_t rows,
 
 1515  ExceptionInfo *exception)
 
 1518    *magick_restrict cache_info;
 
 1521    id = GetOpenMPThreadId();
 
 1526  assert(image != (Image *) NULL);
 
 1527  assert(image->signature == MagickCoreSignature);
 
 1528  assert(image->cache != (Cache) NULL);
 
 1529  cache_info=(CacheInfo *) image->cache;
 
 1530  assert(cache_info->signature == MagickCoreSignature);
 
 1531  if (cache_info->methods.get_authentic_pixels_handler !=
 
 1532      (GetAuthenticPixelsHandler) NULL)
 
 1534      pixels=cache_info->methods.get_authentic_pixels_handler(image,x,y,columns,
 
 1538  assert(
id < (
int) cache_info->number_threads);
 
 1539  pixels=GetAuthenticPixelCacheNexus(image,x,y,columns,rows,
 
 1540    cache_info->nexus_info[
id],exception);
 
 1575static Quantum *GetAuthenticPixelsCache(Image *image,
const ssize_t x,
 
 1576  const ssize_t y,
const size_t columns,
const size_t rows,
 
 1577  ExceptionInfo *exception)
 
 1580    *magick_restrict cache_info;
 
 1583    id = GetOpenMPThreadId();
 
 1586    *magick_restrict pixels;
 
 1588  assert(image != (
const Image *) NULL);
 
 1589  assert(image->signature == MagickCoreSignature);
 
 1590  assert(image->cache != (Cache) NULL);
 
 1591  cache_info=(CacheInfo *) image->cache;
 
 1592  if (cache_info == (Cache) NULL)
 
 1593    return((Quantum *) NULL);
 
 1594  assert(cache_info->signature == MagickCoreSignature);
 
 1595  assert(
id < (
int) cache_info->number_threads);
 
 1596  pixels=GetAuthenticPixelCacheNexus(image,x,y,columns,rows,
 
 1597    cache_info->nexus_info[
id],exception);
 
 1624MagickExport MagickSizeType GetImageExtent(
const Image *image)
 
 1627    *magick_restrict cache_info;
 
 1630    id = GetOpenMPThreadId();
 
 1632  assert(image != (Image *) NULL);
 
 1633  assert(image->signature == MagickCoreSignature);
 
 1634  if (IsEventLogging() != MagickFalse)
 
 1635    (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
 
 1636  assert(image->cache != (Cache) NULL);
 
 1637  cache_info=(CacheInfo *) image->cache;
 
 1638  assert(cache_info->signature == MagickCoreSignature);
 
 1639  assert(
id < (
int) cache_info->number_threads);
 
 1640  return(GetPixelCacheNexusExtent(cache_info,cache_info->nexus_info[
id]));
 
 1673static MagickBooleanType GetDynamicThrottlePolicy(
void)
 
 1675  static MagickBooleanType
 
 1676    check_policy = MagickTrue;
 
 1678  static MagickBooleanType
 
 1679    dynamic_throttle = MagickFalse;
 
 1681  if (check_policy != MagickFalse)
 
 1683      char *value = GetPolicyValue(
"resource:dynamic-throttle");
 
 1684      if (value != (
char *) NULL)
 
 1686          dynamic_throttle=IsStringTrue(value);
 
 1687          value=DestroyString(value);
 
 1689    check_policy=MagickFalse;
 
 1691  return(dynamic_throttle);
 
 1694static inline MagickBooleanType ValidatePixelCacheMorphology(
 
 1695  const Image *magick_restrict image)
 
 1698    *magick_restrict cache_info;
 
 1700  const PixelChannelMap
 
 1707  cache_info=(CacheInfo *) image->cache;
 
 1708  p=image->channel_map;
 
 1709  q=cache_info->channel_map;
 
 1710  if ((image->storage_class != cache_info->storage_class) ||
 
 1711      (image->colorspace != cache_info->colorspace) ||
 
 1712      (image->alpha_trait != cache_info->alpha_trait) ||
 
 1713      (image->channels != cache_info->channels) ||
 
 1714      (image->columns != cache_info->columns) ||
 
 1715      (image->rows != cache_info->rows) ||
 
 1716      (image->number_channels != cache_info->number_channels) ||
 
 1717      (memcmp(p,q,image->number_channels*
sizeof(*p)) != 0) ||
 
 1718      (image->metacontent_extent != cache_info->metacontent_extent) ||
 
 1719      (cache_info->nexus_info == (NexusInfo **) NULL))
 
 1720    return(MagickFalse);
 
 1724static Cache GetImagePixelCache(Image *image,
const MagickBooleanType clone,
 
 1725  ExceptionInfo *exception)
 
 1728    *magick_restrict cache_info;
 
 1732    status = MagickTrue;
 
 1734  static MagickSizeType
 
 1735    cpu_throttle = MagickResourceInfinity,
 
 1738  if (IsImageTTLExpired(image) != MagickFalse)
 
 1743      (void) ThrowMagickException(exception,GetMagickModule(),
 
 1744        ResourceLimitError,
"TimeLimitExceeded",
"`%s'",image->filename);
 
 1745      return((Cache) NULL);
 
 1747  if (cpu_throttle == MagickResourceInfinity)
 
 1748    cpu_throttle=GetMagickResourceLimit(ThrottleResource);
 
 1749  if ((GetDynamicThrottlePolicy() != MagickFalse) && ((cycles % 65536) == 0))
 
 1762#if defined(MAGICKCORE_HAVE_GETLOADAVG) 
 1763      if (getloadavg(&load_average,1) != 1)
 
 1766      load=MagickMax(load_average-GetOpenMPMaximumThreads(),0.0);
 
 1767      cpu_throttle=(MagickSizeType) (max_delay*(1.0-exp(-sensitivity*load)));
 
 1769  if ((cpu_throttle != 0) && ((cycles % 4096) == 0))
 
 1770    MagickDelay(cpu_throttle);
 
 1772  LockSemaphoreInfo(image->semaphore);
 
 1773  assert(image->cache != (Cache) NULL);
 
 1774  cache_info=(CacheInfo *) image->cache;
 
 1775#if defined(MAGICKCORE_OPENCL_SUPPORT) 
 1776  CopyOpenCLBuffer(cache_info);
 
 1778  destroy=MagickFalse;
 
 1779  if ((cache_info->reference_count > 1) || (cache_info->mode == ReadMode))
 
 1781      LockSemaphoreInfo(cache_info->semaphore);
 
 1782      if ((cache_info->reference_count > 1) || (cache_info->mode == ReadMode))
 
 1793          clone_image=(*image);
 
 1794          clone_image.semaphore=AcquireSemaphoreInfo();
 
 1795          clone_image.reference_count=1;
 
 1796          clone_image.cache=ClonePixelCache(cache_info);
 
 1797          clone_info=(CacheInfo *) clone_image.cache;
 
 1798          status=OpenPixelCache(&clone_image,IOMode,exception);
 
 1799          if (status == MagickFalse)
 
 1800            clone_info=(CacheInfo *) DestroyPixelCache(clone_info);
 
 1803              if (clone != MagickFalse)
 
 1804                status=ClonePixelCacheRepository(clone_info,cache_info,
 
 1806              if (status == MagickFalse)
 
 1807                clone_info=(CacheInfo *) DestroyPixelCache(clone_info);
 
 1811                  image->cache=clone_info;
 
 1814          RelinquishSemaphoreInfo(&clone_image.semaphore);
 
 1816      UnlockSemaphoreInfo(cache_info->semaphore);
 
 1818  if (destroy != MagickFalse)
 
 1819    cache_info=(CacheInfo *) DestroyPixelCache(cache_info);
 
 1820  if (status != MagickFalse)
 
 1825      if (image->type != UndefinedType)
 
 1826        image->type=UndefinedType;
 
 1827      if (ValidatePixelCacheMorphology(image) == MagickFalse)
 
 1829          status=OpenPixelCache(image,IOMode,exception);
 
 1830          cache_info=(CacheInfo *) image->cache;
 
 1831          if (cache_info->file != -1)
 
 1832            (void) ClosePixelCacheOnDisk(cache_info);
 
 1835  UnlockSemaphoreInfo(image->semaphore);
 
 1836  if (status == MagickFalse)
 
 1837    return((Cache) NULL);
 
 1838  return(image->cache);
 
 1864MagickExport CacheType GetImagePixelCacheType(
const Image *image)
 
 1867    *magick_restrict cache_info;
 
 1869  assert(image != (Image *) NULL);
 
 1870  assert(image->signature == MagickCoreSignature);
 
 1871  assert(image->cache != (Cache) NULL);
 
 1872  cache_info=(CacheInfo *) image->cache;
 
 1873  assert(cache_info->signature == MagickCoreSignature);
 
 1874  return(cache_info->type);
 
 1908static inline MagickBooleanType CopyPixel(
const Image *image,
 
 1909  const Quantum *source,Quantum *destination)
 
 1914  if (source == (
const Quantum *) NULL)
 
 1916      destination[RedPixelChannel]=ClampToQuantum(image->background_color.red);
 
 1917      destination[GreenPixelChannel]=ClampToQuantum(
 
 1918        image->background_color.green);
 
 1919      destination[BluePixelChannel]=ClampToQuantum(
 
 1920        image->background_color.blue);
 
 1921      destination[BlackPixelChannel]=ClampToQuantum(
 
 1922        image->background_color.black);
 
 1923      destination[AlphaPixelChannel]=ClampToQuantum(
 
 1924        image->background_color.alpha);
 
 1925      return(MagickFalse);
 
 1927  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
 
 1929    PixelChannel channel = GetPixelChannelChannel(image,i);
 
 1930    destination[channel]=source[i];
 
 1935MagickExport MagickBooleanType GetOneAuthenticPixel(Image *image,
 
 1936  const ssize_t x,
const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
 
 1939    *magick_restrict cache_info;
 
 1944  assert(image != (Image *) NULL);
 
 1945  assert(image->signature == MagickCoreSignature);
 
 1946  assert(image->cache != (Cache) NULL);
 
 1947  cache_info=(CacheInfo *) image->cache;
 
 1948  assert(cache_info->signature == MagickCoreSignature);
 
 1949  (void) memset(pixel,0,MaxPixelChannels*
sizeof(*pixel));
 
 1950  if (cache_info->methods.get_one_authentic_pixel_from_handler != (GetOneAuthenticPixelFromHandler) NULL)
 
 1951    return(cache_info->methods.get_one_authentic_pixel_from_handler(image,x,y,pixel,exception));
 
 1952  q=GetAuthenticPixelsCache(image,x,y,1UL,1UL,exception);
 
 1953  return(CopyPixel(image,q,pixel));
 
 1987static MagickBooleanType GetOneAuthenticPixelFromCache(Image *image,
 
 1988  const ssize_t x,
const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
 
 1991    *magick_restrict cache_info;
 
 1994    id = GetOpenMPThreadId();
 
 1999  assert(image != (
const Image *) NULL);
 
 2000  assert(image->signature == MagickCoreSignature);
 
 2001  assert(image->cache != (Cache) NULL);
 
 2002  cache_info=(CacheInfo *) image->cache;
 
 2003  assert(cache_info->signature == MagickCoreSignature);
 
 2004  assert(
id < (
int) cache_info->number_threads);
 
 2005  (void) memset(pixel,0,MaxPixelChannels*
sizeof(*pixel));
 
 2006  q=GetAuthenticPixelCacheNexus(image,x,y,1UL,1UL,cache_info->nexus_info[
id],
 
 2008  return(CopyPixel(image,q,pixel));
 
 2042MagickExport MagickBooleanType GetOneVirtualPixel(
const Image *image,
 
 2043  const ssize_t x,
const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
 
 2046    *magick_restrict cache_info;
 
 2049    id = GetOpenMPThreadId();
 
 2054  assert(image != (
const Image *) NULL);
 
 2055  assert(image->signature == MagickCoreSignature);
 
 2056  assert(image->cache != (Cache) NULL);
 
 2057  cache_info=(CacheInfo *) image->cache;
 
 2058  assert(cache_info->signature == MagickCoreSignature);
 
 2059  (void) memset(pixel,0,MaxPixelChannels*
sizeof(*pixel));
 
 2060  if (cache_info->methods.get_one_virtual_pixel_from_handler !=
 
 2061       (GetOneVirtualPixelFromHandler) NULL)
 
 2062    return(cache_info->methods.get_one_virtual_pixel_from_handler(image,
 
 2063      GetPixelCacheVirtualMethod(image),x,y,pixel,exception));
 
 2064  assert(
id < (
int) cache_info->number_threads);
 
 2065  p=GetVirtualPixelCacheNexus(image,GetPixelCacheVirtualMethod(image),x,y,
 
 2066    1UL,1UL,cache_info->nexus_info[
id],exception);
 
 2067  return(CopyPixel(image,p,pixel));
 
 2104static MagickBooleanType GetOneVirtualPixelFromCache(
const Image *image,
 
 2105  const VirtualPixelMethod virtual_pixel_method,
const ssize_t x,
const ssize_t y,
 
 2106  Quantum *pixel,ExceptionInfo *exception)
 
 2109    *magick_restrict cache_info;
 
 2112    id = GetOpenMPThreadId();
 
 2117  assert(image != (
const Image *) NULL);
 
 2118  assert(image->signature == MagickCoreSignature);
 
 2119  assert(image->cache != (Cache) NULL);
 
 2120  cache_info=(CacheInfo *) image->cache;
 
 2121  assert(cache_info->signature == MagickCoreSignature);
 
 2122  assert(
id < (
int) cache_info->number_threads);
 
 2123  (void) memset(pixel,0,MaxPixelChannels*
sizeof(*pixel));
 
 2124  p=GetVirtualPixelCacheNexus(image,virtual_pixel_method,x,y,1UL,1UL,
 
 2125    cache_info->nexus_info[
id],exception);
 
 2126  return(CopyPixel(image,p,pixel));
 
 2163MagickExport MagickBooleanType GetOneVirtualPixelInfo(
const Image *image,
 
 2164  const VirtualPixelMethod virtual_pixel_method,
const ssize_t x,
const ssize_t y,
 
 2165  PixelInfo *pixel,ExceptionInfo *exception)
 
 2168    *magick_restrict cache_info;
 
 2171    id = GetOpenMPThreadId();
 
 2176  assert(image != (
const Image *) NULL);
 
 2177  assert(image->signature == MagickCoreSignature);
 
 2178  assert(image->cache != (Cache) NULL);
 
 2179  cache_info=(CacheInfo *) image->cache;
 
 2180  assert(cache_info->signature == MagickCoreSignature);
 
 2181  assert(
id < (
int) cache_info->number_threads);
 
 2182  GetPixelInfo(image,pixel);
 
 2183  p=GetVirtualPixelCacheNexus(image,virtual_pixel_method,x,y,1UL,1UL,
 
 2184    cache_info->nexus_info[
id],exception);
 
 2185  if (p == (
const Quantum *) NULL)
 
 2186    return(MagickFalse);
 
 2187  GetPixelInfoPixel(image,p,pixel);
 
 2213MagickPrivate ColorspaceType GetPixelCacheColorspace(
const Cache cache)
 
 2216    *magick_restrict cache_info;
 
 2218  assert(cache != (Cache) NULL);
 
 2219  cache_info=(CacheInfo *) cache;
 
 2220  assert(cache_info->signature == MagickCoreSignature);
 
 2221  if (IsEventLogging() != MagickFalse)
 
 2222    (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
 
 2223      cache_info->filename);
 
 2224  return(cache_info->colorspace);
 
 2250MagickExport 
const char *GetPixelCacheFilename(
const Image *image)
 
 2253    *magick_restrict cache_info;
 
 2255  assert(image != (
const Image *) NULL);
 
 2256  assert(image->signature == MagickCoreSignature);
 
 2257  assert(image->cache != (Cache) NULL);
 
 2258  cache_info=(CacheInfo *) image->cache;
 
 2259  assert(cache_info->signature == MagickCoreSignature);
 
 2260  return(cache_info->cache_filename);
 
 2285MagickPrivate 
void GetPixelCacheMethods(CacheMethods *cache_methods)
 
 2287  assert(cache_methods != (CacheMethods *) NULL);
 
 2288  (void) memset(cache_methods,0,
sizeof(*cache_methods));
 
 2289  cache_methods->get_virtual_pixel_handler=GetVirtualPixelCache;
 
 2290  cache_methods->get_virtual_pixels_handler=GetVirtualPixelsCache;
 
 2291  cache_methods->get_virtual_metacontent_from_handler=
 
 2292    GetVirtualMetacontentFromCache;
 
 2293  cache_methods->get_one_virtual_pixel_from_handler=GetOneVirtualPixelFromCache;
 
 2294  cache_methods->get_authentic_pixels_handler=GetAuthenticPixelsCache;
 
 2295  cache_methods->get_authentic_metacontent_from_handler=
 
 2296    GetAuthenticMetacontentFromCache;
 
 2297  cache_methods->get_authentic_pixels_from_handler=GetAuthenticPixelsFromCache;
 
 2298  cache_methods->get_one_authentic_pixel_from_handler=
 
 2299    GetOneAuthenticPixelFromCache;
 
 2300  cache_methods->queue_authentic_pixels_handler=QueueAuthenticPixelsCache;
 
 2301  cache_methods->sync_authentic_pixels_handler=SyncAuthenticPixelsCache;
 
 2302  cache_methods->destroy_pixel_handler=DestroyImagePixelCache;
 
 2330MagickPrivate MagickSizeType GetPixelCacheNexusExtent(
const Cache cache,
 
 2331  NexusInfo *magick_restrict nexus_info)
 
 2334    *magick_restrict cache_info;
 
 2339  assert(cache != NULL);
 
 2340  cache_info=(CacheInfo *) cache;
 
 2341  assert(cache_info->signature == MagickCoreSignature);
 
 2342  extent=(MagickSizeType) nexus_info->region.width*nexus_info->region.height;
 
 2344    return((MagickSizeType) cache_info->columns*cache_info->rows);
 
 2375MagickExport 
void *GetPixelCachePixels(Image *image,MagickSizeType *length,
 
 2376  ExceptionInfo *magick_unused(exception))
 
 2379    *magick_restrict cache_info;
 
 2381  assert(image != (
const Image *) NULL);
 
 2382  assert(image->signature == MagickCoreSignature);
 
 2383  assert(image->cache != (Cache) NULL);
 
 2384  assert(length != (MagickSizeType *) NULL);
 
 2385  magick_unreferenced(exception);
 
 2386  cache_info=(CacheInfo *) image->cache;
 
 2387  assert(cache_info->signature == MagickCoreSignature);
 
 2388  *length=cache_info->length;
 
 2389  if ((cache_info->type != MemoryCache) && (cache_info->type != MapCache))
 
 2390    return((
void *) NULL);
 
 2391  return((
void *) cache_info->pixels);
 
 2418MagickPrivate ClassType GetPixelCacheStorageClass(
const Cache cache)
 
 2421    *magick_restrict cache_info;
 
 2423  assert(cache != (Cache) NULL);
 
 2424  cache_info=(CacheInfo *) cache;
 
 2425  assert(cache_info->signature == MagickCoreSignature);
 
 2426  if (IsEventLogging() != MagickFalse)
 
 2427    (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
 
 2428      cache_info->filename);
 
 2429  return(cache_info->storage_class);
 
 2459MagickPrivate 
void GetPixelCacheTileSize(
const Image *image,
size_t *width,
 
 2463    *magick_restrict cache_info;
 
 2465  assert(image != (Image *) NULL);
 
 2466  assert(image->signature == MagickCoreSignature);
 
 2467  if (IsEventLogging() != MagickFalse)
 
 2468    (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
 
 2469  cache_info=(CacheInfo *) image->cache;
 
 2470  assert(cache_info->signature == MagickCoreSignature);
 
 2471  *width=2048UL/(MagickMax(cache_info->number_channels,1)*
sizeof(Quantum));
 
 2472  if (GetImagePixelCacheType(image) == DiskCache)
 
 2473    *width=8192UL/(MagickMax(cache_info->number_channels,1)*
sizeof(Quantum));
 
 2501MagickPrivate VirtualPixelMethod GetPixelCacheVirtualMethod(
const Image *image)
 
 2504    *magick_restrict cache_info;
 
 2506  assert(image != (Image *) NULL);
 
 2507  assert(image->signature == MagickCoreSignature);
 
 2508  assert(image->cache != (Cache) NULL);
 
 2509  cache_info=(CacheInfo *) image->cache;
 
 2510  assert(cache_info->signature == MagickCoreSignature);
 
 2511  return(cache_info->virtual_pixel_method);
 
 2537static const void *GetVirtualMetacontentFromCache(
const Image *image)
 
 2540    *magick_restrict cache_info;
 
 2543    id = GetOpenMPThreadId();
 
 2546    *magick_restrict metacontent;
 
 2548  assert(image != (
const Image *) NULL);
 
 2549  assert(image->signature == MagickCoreSignature);
 
 2550  assert(image->cache != (Cache) NULL);
 
 2551  cache_info=(CacheInfo *) image->cache;
 
 2552  assert(cache_info->signature == MagickCoreSignature);
 
 2553  assert(
id < (
int) cache_info->number_threads);
 
 2554  metacontent=GetVirtualMetacontentFromNexus(cache_info,
 
 2555    cache_info->nexus_info[
id]);
 
 2556  return(metacontent);
 
 2585MagickPrivate 
const void *GetVirtualMetacontentFromNexus(
const Cache cache,
 
 2586  NexusInfo *magick_restrict nexus_info)
 
 2589    *magick_restrict cache_info;
 
 2591  assert(cache != (Cache) NULL);
 
 2592  cache_info=(CacheInfo *) cache;
 
 2593  assert(cache_info->signature == MagickCoreSignature);
 
 2594  if (cache_info->storage_class == UndefinedClass)
 
 2595    return((
void *) NULL);
 
 2596  return(nexus_info->metacontent);
 
 2623MagickExport 
const void *GetVirtualMetacontent(
const Image *image)
 
 2626    *magick_restrict cache_info;
 
 2629    id = GetOpenMPThreadId();
 
 2632    *magick_restrict metacontent;
 
 2634  assert(image != (
const Image *) NULL);
 
 2635  assert(image->signature == MagickCoreSignature);
 
 2636  assert(image->cache != (Cache) NULL);
 
 2637  cache_info=(CacheInfo *) image->cache;
 
 2638  assert(cache_info->signature == MagickCoreSignature);
 
 2639  if (cache_info->methods.get_virtual_metacontent_from_handler != (GetVirtualMetacontentFromHandler) NULL)
 
 2641      metacontent=cache_info->methods.get_virtual_metacontent_from_handler(
 
 2643      if (metacontent != (
const void *) NULL)
 
 2644        return(metacontent);
 
 2646  assert(
id < (
int) cache_info->number_threads);
 
 2647  metacontent=GetVirtualMetacontentFromNexus(cache_info,
 
 2648    cache_info->nexus_info[
id]);
 
 2649  return(metacontent);
 
 2692     0,  48,  12,  60,   3,  51,  15,  63,
 
 2693    32,  16,  44,  28,  35,  19,  47,  31,
 
 2694     8,  56,   4,  52,  11,  59,   7,  55,
 
 2695    40,  24,  36,  20,  43,  27,  39,  23,
 
 2696     2,  50,  14,  62,   1,  49,  13,  61,
 
 2697    34,  18,  46,  30,  33,  17,  45,  29,
 
 2698    10,  58,   6,  54,   9,  57,   5,  53,
 
 2699    42,  26,  38,  22,  41,  25,  37,  21
 
 2702static inline ssize_t DitherX(
const ssize_t x,
const size_t columns)
 
 2707  index=x+DitherMatrix[x & 0x07]-32L;
 
 2710  if (index >= (ssize_t) columns)
 
 2711    return((ssize_t) columns-1L);
 
 2715static inline ssize_t DitherY(
const ssize_t y,
const size_t rows)
 
 2720  index=y+DitherMatrix[y & 0x07]-32L;
 
 2723  if (index >= (ssize_t) rows)
 
 2724    return((ssize_t) rows-1L);
 
 2728static inline ssize_t EdgeX(
const ssize_t x,
const size_t columns)
 
 2732  if (x >= (ssize_t) columns)
 
 2733    return((ssize_t) (columns-1));
 
 2737static inline ssize_t EdgeY(
const ssize_t y,
const size_t rows)
 
 2741  if (y >= (ssize_t) rows)
 
 2742    return((ssize_t) (rows-1));
 
 2746static inline MagickBooleanType IsOffsetOverflow(
const MagickOffsetType x,
 
 2747  const MagickOffsetType y)
 
 2749  if (((y > 0) && (x > ((MagickOffsetType) MAGICK_SSIZE_MAX-y))) ||
 
 2750      ((y < 0) && (x < ((MagickOffsetType) MAGICK_SSIZE_MIN-y))))
 
 2751    return(MagickFalse);
 
 2755static inline ssize_t RandomX(RandomInfo *random_info,
const size_t columns)
 
 2757  return((ssize_t) (columns*GetPseudoRandomValue(random_info)));
 
 2760static inline ssize_t RandomY(RandomInfo *random_info,
const size_t rows)
 
 2762  return((ssize_t) (rows*GetPseudoRandomValue(random_info)));
 
 2765static inline MagickModulo VirtualPixelModulo(
const ssize_t offset,
 
 2766  const size_t extent)
 
 2771  modulo.quotient=offset;
 
 2775      modulo.quotient=offset/((ssize_t) extent);
 
 2776      modulo.remainder=offset % ((ssize_t) extent);
 
 2778  if ((modulo.remainder != 0) && ((offset ^ ((ssize_t) extent)) < 0))
 
 2781      modulo.remainder+=((ssize_t) extent);
 
 2786MagickPrivate 
const Quantum *GetVirtualPixelCacheNexus(
const Image *image,
 
 2787  const VirtualPixelMethod virtual_pixel_method,
const ssize_t x,
const ssize_t y,
 
 2788  const size_t columns,
const size_t rows,NexusInfo *nexus_info,
 
 2789  ExceptionInfo *exception)
 
 2792    *magick_restrict cache_info;
 
 2808    *magick_restrict virtual_nexus;
 
 2811    *magick_restrict pixels,
 
 2813    virtual_pixel[MaxPixelChannels];
 
 2824    *magick_restrict virtual_metacontent;
 
 2829  assert(image != (
const Image *) NULL);
 
 2830  assert(image->signature == MagickCoreSignature);
 
 2831  assert(image->cache != (Cache) NULL);
 
 2832  cache_info=(CacheInfo *) image->cache;
 
 2833  assert(cache_info->signature == MagickCoreSignature);
 
 2834  if (cache_info->type == UndefinedCache)
 
 2835    return((
const Quantum *) NULL);
 
 2836#if defined(MAGICKCORE_OPENCL_SUPPORT) 
 2837  CopyOpenCLBuffer(cache_info);
 
 2839  pixels=SetPixelCacheNexusPixels(cache_info,ReadMode,x,y,columns,rows,
 
 2840    ((image->channels & WriteMaskChannel) != 0) ||
 
 2841    ((image->channels & CompositeMaskChannel) != 0) ? MagickTrue : MagickFalse,
 
 2842    nexus_info,exception);
 
 2843  if (pixels == (Quantum *) NULL)
 
 2844    return((
const Quantum *) NULL);
 
 2845  if (IsValidPixelOffset(nexus_info->region.y,cache_info->columns) == MagickFalse)
 
 2846    return((
const Quantum *) NULL);
 
 2847  offset=nexus_info->region.y*(MagickOffsetType) cache_info->columns;
 
 2848  if (IsOffsetOverflow(offset,(MagickOffsetType) nexus_info->region.x) == MagickFalse)
 
 2849    return((
const Quantum *) NULL);
 
 2850  offset+=nexus_info->region.x;
 
 2851  length=(MagickSizeType) (nexus_info->region.height-1L)*cache_info->columns+
 
 2852    nexus_info->region.width-1L;
 
 2853  number_pixels=(MagickSizeType) cache_info->columns*cache_info->rows;
 
 2854  if ((offset >= 0) && (((MagickSizeType) offset+length) < number_pixels))
 
 2855    if ((x >= 0) && ((x+(ssize_t) columns-1) < (ssize_t) cache_info->columns) &&
 
 2856        (y >= 0) && ((y+(ssize_t) rows-1) < (ssize_t) cache_info->rows))
 
 2864        if (nexus_info->authentic_pixel_cache != MagickFalse)
 
 2866        status=ReadPixelCachePixels(cache_info,nexus_info,exception);
 
 2867        if (status == MagickFalse)
 
 2868          return((
const Quantum *) NULL);
 
 2869        if (cache_info->metacontent_extent != 0)
 
 2871            status=ReadPixelCacheMetacontent(cache_info,nexus_info,exception);
 
 2872            if (status == MagickFalse)
 
 2873              return((
const Quantum *) NULL);
 
 2880  virtual_nexus=nexus_info->virtual_nexus;
 
 2882  s=(
unsigned char *) nexus_info->metacontent;
 
 2883  (void) memset(virtual_pixel,0,cache_info->number_channels*
 
 2884    sizeof(*virtual_pixel));
 
 2885  virtual_metacontent=(
void *) NULL;
 
 2886  switch (virtual_pixel_method)
 
 2888    case BackgroundVirtualPixelMethod:
 
 2889    case BlackVirtualPixelMethod:
 
 2890    case GrayVirtualPixelMethod:
 
 2891    case TransparentVirtualPixelMethod:
 
 2892    case MaskVirtualPixelMethod:
 
 2893    case WhiteVirtualPixelMethod:
 
 2894    case EdgeVirtualPixelMethod:
 
 2895    case CheckerTileVirtualPixelMethod:
 
 2896    case HorizontalTileVirtualPixelMethod:
 
 2897    case VerticalTileVirtualPixelMethod:
 
 2899      if (cache_info->metacontent_extent != 0)
 
 2904          virtual_metacontent=(
void *) AcquireQuantumMemory(1,
 
 2905            cache_info->metacontent_extent);
 
 2906          if (virtual_metacontent == (
void *) NULL)
 
 2908              (void) ThrowMagickException(exception,GetMagickModule(),
 
 2909                CacheError,
"UnableToGetCacheNexus",
"`%s'",image->filename);
 
 2910              return((
const Quantum *) NULL);
 
 2912          (void) memset(virtual_metacontent,0,cache_info->metacontent_extent);
 
 2914      switch (virtual_pixel_method)
 
 2916        case BlackVirtualPixelMethod:
 
 2918          for (i=0; i < (ssize_t) cache_info->number_channels; i++)
 
 2919            SetPixelChannel(image,(PixelChannel) i,(Quantum) 0,virtual_pixel);
 
 2920          SetPixelAlpha(image,OpaqueAlpha,virtual_pixel);
 
 2923        case GrayVirtualPixelMethod:
 
 2925          for (i=0; i < (ssize_t) cache_info->number_channels; i++)
 
 2926            SetPixelChannel(image,(PixelChannel) i,QuantumRange/2,
 
 2928          SetPixelAlpha(image,OpaqueAlpha,virtual_pixel);
 
 2931        case TransparentVirtualPixelMethod:
 
 2933          for (i=0; i < (ssize_t) cache_info->number_channels; i++)
 
 2934            SetPixelChannel(image,(PixelChannel) i,(Quantum) 0,virtual_pixel);
 
 2935          SetPixelAlpha(image,TransparentAlpha,virtual_pixel);
 
 2938        case MaskVirtualPixelMethod:
 
 2939        case WhiteVirtualPixelMethod:
 
 2941          for (i=0; i < (ssize_t) cache_info->number_channels; i++)
 
 2942            SetPixelChannel(image,(PixelChannel) i,QuantumRange,virtual_pixel);
 
 2943          SetPixelAlpha(image,OpaqueAlpha,virtual_pixel);
 
 2948          SetPixelRed(image,ClampToQuantum(image->background_color.red),
 
 2950          SetPixelGreen(image,ClampToQuantum(image->background_color.green),
 
 2952          SetPixelBlue(image,ClampToQuantum(image->background_color.blue),
 
 2954          SetPixelBlack(image,ClampToQuantum(image->background_color.black),
 
 2956          SetPixelAlpha(image,ClampToQuantum(image->background_color.alpha),
 
 2966  for (v=0; v < (ssize_t) rows; v++)
 
 2972    if ((virtual_pixel_method == EdgeVirtualPixelMethod) ||
 
 2973        (virtual_pixel_method == UndefinedVirtualPixelMethod))
 
 2974      y_offset=EdgeY(y_offset,cache_info->rows);
 
 2975    for (u=0; u < (ssize_t) columns; u+=(ssize_t) length)
 
 2981      length=(MagickSizeType) MagickMin((ssize_t) cache_info->columns-
 
 2982        x_offset,(ssize_t) columns-u);
 
 2983      if (((x_offset < 0) || (x_offset >= (ssize_t) cache_info->columns)) ||
 
 2984          ((y_offset < 0) || (y_offset >= (ssize_t) cache_info->rows)) ||
 
 2994          length=(MagickSizeType) 1;
 
 2995          switch (virtual_pixel_method)
 
 2997            case EdgeVirtualPixelMethod:
 
 3000              p=GetVirtualPixelCacheNexus(image,virtual_pixel_method,
 
 3001                EdgeX(x_offset,cache_info->columns),
 
 3002                EdgeY(y_offset,cache_info->rows),1UL,1UL,virtual_nexus,
 
 3004              r=GetVirtualMetacontentFromNexus(cache_info,virtual_nexus);
 
 3007            case RandomVirtualPixelMethod:
 
 3009              if (cache_info->random_info == (RandomInfo *) NULL)
 
 3010                cache_info->random_info=AcquireRandomInfo();
 
 3011              p=GetVirtualPixelCacheNexus(image,virtual_pixel_method,
 
 3012                RandomX(cache_info->random_info,cache_info->columns),
 
 3013                RandomY(cache_info->random_info,cache_info->rows),1UL,1UL,
 
 3014                virtual_nexus,exception);
 
 3015              r=GetVirtualMetacontentFromNexus(cache_info,virtual_nexus);
 
 3018            case DitherVirtualPixelMethod:
 
 3020              p=GetVirtualPixelCacheNexus(image,virtual_pixel_method,
 
 3021                DitherX(x_offset,cache_info->columns),
 
 3022                DitherY(y_offset,cache_info->rows),1UL,1UL,virtual_nexus,
 
 3024              r=GetVirtualMetacontentFromNexus(cache_info,virtual_nexus);
 
 3027            case TileVirtualPixelMethod:
 
 3029              x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
 
 3030              y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
 
 3031              p=GetVirtualPixelCacheNexus(image,virtual_pixel_method,
 
 3032                x_modulo.remainder,y_modulo.remainder,1UL,1UL,virtual_nexus,
 
 3034              r=GetVirtualMetacontentFromNexus(cache_info,virtual_nexus);
 
 3037            case MirrorVirtualPixelMethod:
 
 3039              x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
 
 3040              if ((x_modulo.quotient & 0x01) == 1L)
 
 3041                x_modulo.remainder=(ssize_t) cache_info->columns-
 
 3042                  x_modulo.remainder-1L;
 
 3043              y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
 
 3044              if ((y_modulo.quotient & 0x01) == 1L)
 
 3045                y_modulo.remainder=(ssize_t) cache_info->rows-
 
 3046                  y_modulo.remainder-1L;
 
 3047              p=GetVirtualPixelCacheNexus(image,virtual_pixel_method,
 
 3048                x_modulo.remainder,y_modulo.remainder,1UL,1UL,virtual_nexus,
 
 3050              r=GetVirtualMetacontentFromNexus(cache_info,virtual_nexus);
 
 3053            case HorizontalTileEdgeVirtualPixelMethod:
 
 3055              x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
 
 3056              p=GetVirtualPixelCacheNexus(image,virtual_pixel_method,
 
 3057                x_modulo.remainder,EdgeY(y_offset,cache_info->rows),1UL,1UL,
 
 3058                virtual_nexus,exception);
 
 3059              r=GetVirtualMetacontentFromNexus(cache_info,virtual_nexus);
 
 3062            case VerticalTileEdgeVirtualPixelMethod:
 
 3064              y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
 
 3065              p=GetVirtualPixelCacheNexus(image,virtual_pixel_method,
 
 3066                EdgeX(x_offset,cache_info->columns),y_modulo.remainder,1UL,1UL,
 
 3067                virtual_nexus,exception);
 
 3068              r=GetVirtualMetacontentFromNexus(cache_info,virtual_nexus);
 
 3071            case BackgroundVirtualPixelMethod:
 
 3072            case BlackVirtualPixelMethod:
 
 3073            case GrayVirtualPixelMethod:
 
 3074            case TransparentVirtualPixelMethod:
 
 3075            case MaskVirtualPixelMethod:
 
 3076            case WhiteVirtualPixelMethod:
 
 3079              r=virtual_metacontent;
 
 3082            case CheckerTileVirtualPixelMethod:
 
 3084              x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
 
 3085              y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
 
 3086              if (((x_modulo.quotient ^ y_modulo.quotient) & 0x01) != 0L)
 
 3089                  r=virtual_metacontent;
 
 3092              p=GetVirtualPixelCacheNexus(image,virtual_pixel_method,
 
 3093                x_modulo.remainder,y_modulo.remainder,1UL,1UL,virtual_nexus,
 
 3095              r=GetVirtualMetacontentFromNexus(cache_info,virtual_nexus);
 
 3098            case HorizontalTileVirtualPixelMethod:
 
 3100              if ((y_offset < 0) || (y_offset >= (ssize_t) cache_info->rows))
 
 3103                  r=virtual_metacontent;
 
 3106              x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
 
 3107              y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
 
 3108              p=GetVirtualPixelCacheNexus(image,virtual_pixel_method,
 
 3109                x_modulo.remainder,y_modulo.remainder,1UL,1UL,virtual_nexus,
 
 3111              r=GetVirtualMetacontentFromNexus(cache_info,virtual_nexus);
 
 3114            case VerticalTileVirtualPixelMethod:
 
 3116              if ((x_offset < 0) || (x_offset >= (ssize_t) cache_info->columns))
 
 3119                  r=virtual_metacontent;
 
 3122              x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
 
 3123              y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
 
 3124              p=GetVirtualPixelCacheNexus(image,virtual_pixel_method,
 
 3125                x_modulo.remainder,y_modulo.remainder,1UL,1UL,virtual_nexus,
 
 3127              r=GetVirtualMetacontentFromNexus(cache_info,virtual_nexus);
 
 3131          if (p == (
const Quantum *) NULL)
 
 3133          (void) memcpy(q,p,(
size_t) (cache_info->number_channels*length*
 
 3135          q+=(ptrdiff_t) cache_info->number_channels;
 
 3136          if ((s != (
void *) NULL) && (r != (
const void *) NULL))
 
 3138              (void) memcpy(s,r,(
size_t) cache_info->metacontent_extent);
 
 3139              s+=(ptrdiff_t) cache_info->metacontent_extent;
 
 3146      p=GetVirtualPixelCacheNexus(image,virtual_pixel_method,x_offset,y_offset,
 
 3147        (
size_t) length,1UL,virtual_nexus,exception);
 
 3148      if (p == (
const Quantum *) NULL)
 
 3150      r=GetVirtualMetacontentFromNexus(cache_info,virtual_nexus);
 
 3151      (void) memcpy(q,p,(
size_t) (cache_info->number_channels*length*
 
 3153      q+=(ptrdiff_t) cache_info->number_channels*length;
 
 3154      if ((r != (
void *) NULL) && (s != (
const void *) NULL))
 
 3156          (void) memcpy(s,r,(
size_t) length);
 
 3157          s+=(ptrdiff_t) length*cache_info->metacontent_extent;
 
 3160    if (u < (ssize_t) columns)
 
 3166  if (virtual_metacontent != (
void *) NULL)
 
 3167    virtual_metacontent=(
void *) RelinquishMagickMemory(virtual_metacontent);
 
 3168  if (v < (ssize_t) rows)
 
 3169    return((
const Quantum *) NULL);
 
 3207static const Quantum *GetVirtualPixelCache(
const Image *image,
 
 3208  const VirtualPixelMethod virtual_pixel_method,
const ssize_t x,
const ssize_t y,
 
 3209  const size_t columns,
const size_t rows,ExceptionInfo *exception)
 
 3212    *magick_restrict cache_info;
 
 3215    id = GetOpenMPThreadId();
 
 3220  assert(image != (
const Image *) NULL);
 
 3221  assert(image->signature == MagickCoreSignature);
 
 3222  assert(image->cache != (Cache) NULL);
 
 3223  cache_info=(CacheInfo *) image->cache;
 
 3224  assert(cache_info->signature == MagickCoreSignature);
 
 3225  assert(
id < (
int) cache_info->number_threads);
 
 3226  p=GetVirtualPixelCacheNexus(image,virtual_pixel_method,x,y,columns,rows,
 
 3227    cache_info->nexus_info[
id],exception);
 
 3254MagickExport 
const Quantum *GetVirtualPixelQueue(
const Image *image)
 
 3257    *magick_restrict cache_info;
 
 3260    id = GetOpenMPThreadId();
 
 3262  assert(image != (
const Image *) NULL);
 
 3263  assert(image->signature == MagickCoreSignature);
 
 3264  assert(image->cache != (Cache) NULL);
 
 3265  cache_info=(CacheInfo *) image->cache;
 
 3266  assert(cache_info->signature == MagickCoreSignature);
 
 3267  if (cache_info->methods.get_virtual_pixels_handler !=
 
 3268       (GetVirtualPixelsHandler) NULL)
 
 3269    return(cache_info->methods.get_virtual_pixels_handler(image));
 
 3270  assert(
id < (
int) cache_info->number_threads);
 
 3271  return(GetVirtualPixelsNexus(cache_info,cache_info->nexus_info[
id]));
 
 3322MagickExport 
const Quantum *GetVirtualPixels(
const Image *image,
 
 3323  const ssize_t x,
const ssize_t y,
const size_t columns,
const size_t rows,
 
 3324  ExceptionInfo *exception)
 
 3327    *magick_restrict cache_info;
 
 3330    id = GetOpenMPThreadId();
 
 3335  assert(image != (
const Image *) NULL);
 
 3336  assert(image->signature == MagickCoreSignature);
 
 3337  assert(image->cache != (Cache) NULL);
 
 3338  cache_info=(CacheInfo *) image->cache;
 
 3339  assert(cache_info->signature == MagickCoreSignature);
 
 3340  if (cache_info->methods.get_virtual_pixel_handler !=
 
 3341       (GetVirtualPixelHandler) NULL)
 
 3342    return(cache_info->methods.get_virtual_pixel_handler(image,
 
 3343      GetPixelCacheVirtualMethod(image),x,y,columns,rows,exception));
 
 3344  assert(
id < (
int) cache_info->number_threads);
 
 3345  p=GetVirtualPixelCacheNexus(image,GetPixelCacheVirtualMethod(image),x,y,
 
 3346    columns,rows,cache_info->nexus_info[
id],exception);
 
 3373static const Quantum *GetVirtualPixelsCache(
const Image *image)
 
 3376    *magick_restrict cache_info;
 
 3379    id = GetOpenMPThreadId();
 
 3381  assert(image != (
const Image *) NULL);
 
 3382  assert(image->signature == MagickCoreSignature);
 
 3383  assert(image->cache != (Cache) NULL);
 
 3384  cache_info=(CacheInfo *) image->cache;
 
 3385  assert(cache_info->signature == MagickCoreSignature);
 
 3386  assert(
id < (
int) cache_info->number_threads);
 
 3387  return(GetVirtualPixelsNexus(image->cache,cache_info->nexus_info[
id]));
 
 3416MagickPrivate 
const Quantum *GetVirtualPixelsNexus(
const Cache cache,
 
 3417  NexusInfo *magick_restrict nexus_info)
 
 3420    *magick_restrict cache_info;
 
 3422  assert(cache != (Cache) NULL);
 
 3423  cache_info=(CacheInfo *) cache;
 
 3424  assert(cache_info->signature == MagickCoreSignature);
 
 3425  if (cache_info->storage_class == UndefinedClass)
 
 3426    return((Quantum *) NULL);
 
 3427  return((
const Quantum *) nexus_info->pixels);
 
 3460static inline Quantum ApplyPixelCompositeMask(
const Quantum p,
 
 3461  const MagickRealType alpha,
const Quantum q,
const MagickRealType beta)
 
 3466  if (fabs((
double) (alpha-(
double) TransparentAlpha)) < MagickEpsilon)
 
 3468  gamma=1.0-QuantumScale*QuantumScale*alpha*beta;
 
 3469  gamma=MagickSafeReciprocal(gamma);
 
 3470  return(ClampToQuantum(gamma*MagickOver_((
double) p,alpha,(
double) q,beta)));
 
 3473static MagickBooleanType MaskPixelCacheNexus(Image *image,NexusInfo *nexus_info,
 
 3474  ExceptionInfo *exception)
 
 3477    *magick_restrict cache_info;
 
 3489  if (IsEventLogging() != MagickFalse)
 
 3490    (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
 
 3491  if ((image->channels & CompositeMaskChannel) == 0)
 
 3493  if ((nexus_info->region.width == 0) || (nexus_info->region.height == 0))
 
 3495  cache_info=(CacheInfo *) image->cache;
 
 3496  if (cache_info == (Cache) NULL)
 
 3497    return(MagickFalse);
 
 3498  p=GetAuthenticPixelCacheNexus(image,nexus_info->region.x,nexus_info->region.y,
 
 3499    nexus_info->region.width,nexus_info->region.height,
 
 3500    nexus_info->virtual_nexus,exception);
 
 3501  q=nexus_info->pixels;
 
 3502  if ((p == (Quantum *) NULL) || (q == (Quantum *) NULL))
 
 3503    return(MagickFalse);
 
 3504  for (y=0; y < (ssize_t) nexus_info->region.height; y++)
 
 3509    for (x=0; x < (ssize_t) nexus_info->region.width; x++)
 
 3517      alpha=(double) GetPixelCompositeMask(image,p);
 
 3518      for (i=0; i < (ssize_t) image->number_channels; i++)
 
 3520        PixelChannel channel = GetPixelChannelChannel(image,i);
 
 3521        PixelTrait traits = GetPixelChannelTraits(image,channel);
 
 3522        if ((traits & UpdatePixelTrait) == 0)
 
 3524        q[i]=ApplyPixelCompositeMask(q[i],alpha,p[i],GetPixelAlpha(image,p));
 
 3526      p+=(ptrdiff_t) GetPixelChannels(image);
 
 3527      q+=(ptrdiff_t) GetPixelChannels(image);
 
 3564static MagickBooleanType OpenPixelCacheOnDisk(CacheInfo *cache_info,
 
 3573  if ((cache_info->file != -1) && (cache_info->disk_mode == mode))
 
 3575  if (*cache_info->cache_filename == 
'\0')
 
 3576    file=AcquireUniqueFileResource(cache_info->cache_filename);
 
 3582        file=open_utf8(cache_info->cache_filename,O_RDONLY | O_BINARY,0);
 
 3587        file=open_utf8(cache_info->cache_filename,O_WRONLY | O_CREAT |
 
 3588          O_BINARY | O_EXCL,S_MODE);
 
 3590          file=open_utf8(cache_info->cache_filename,O_WRONLY | O_BINARY,S_MODE);
 
 3596        file=open_utf8(cache_info->cache_filename,O_RDWR | O_CREAT | O_BINARY |
 
 3599          file=open_utf8(cache_info->cache_filename,O_RDWR | O_BINARY,S_MODE);
 
 3604    return(MagickFalse);
 
 3605  (void) AcquireMagickResource(FileResource,1);
 
 3606  if (cache_info->file != -1)
 
 3607    (void) ClosePixelCacheOnDisk(cache_info);
 
 3608  cache_info->file=file;
 
 3609  cache_info->disk_mode=mode;
 
 3613static inline MagickOffsetType WritePixelCacheRegion(
 
 3614  const CacheInfo *magick_restrict cache_info,
const MagickOffsetType offset,
 
 3615  const MagickSizeType length,
const unsigned char *magick_restrict buffer)
 
 3623#if !defined(MAGICKCORE_HAVE_PWRITE) 
 3624  if (lseek(cache_info->file,offset,SEEK_SET) < 0)
 
 3625    return((MagickOffsetType) -1);
 
 3627  for (i=0; i < (MagickOffsetType) length; i+=count)
 
 3629#if !defined(MAGICKCORE_HAVE_PWRITE) 
 3630    count=write(cache_info->file,buffer+i,(
size_t) MagickMin(length-
 
 3631      (MagickSizeType) i,MagickMaxBufferExtent));
 
 3633    count=pwrite(cache_info->file,buffer+i,(
size_t) MagickMin(length-
 
 3634      (MagickSizeType) i,MagickMaxBufferExtent),offset+i);
 
 3646static MagickBooleanType SetPixelCacheExtent(Image *image,MagickSizeType length)
 
 3649    *magick_restrict cache_info;
 
 3654  cache_info=(CacheInfo *) image->cache;
 
 3655  if (cache_info->debug != MagickFalse)
 
 3658        format[MagickPathExtent],
 
 3659        message[MagickPathExtent];
 
 3661      (void) FormatMagickSize(length,MagickFalse,
"B",MagickPathExtent,format);
 
 3662      (void) FormatLocaleString(message,MagickPathExtent,
 
 3663        "extend %s (%s[%d], disk, %s)",cache_info->filename,
 
 3664        cache_info->cache_filename,cache_info->file,format);
 
 3665      (void) LogMagickEvent(CacheEvent,GetMagickModule(),
"%s",message);
 
 3667  if (length != (MagickSizeType) ((MagickOffsetType) length))
 
 3668    return(MagickFalse);
 
 3669  offset=(MagickOffsetType) lseek(cache_info->file,0,SEEK_END);
 
 3671    return(MagickFalse);
 
 3672  if ((MagickSizeType) offset < length)
 
 3678      extent=(MagickOffsetType) length-1;
 
 3679      count=WritePixelCacheRegion(cache_info,extent,1,(
const unsigned char *)
 
 3682        return(MagickFalse);
 
 3683#if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE) 
 3684      if (cache_info->synchronize != MagickFalse)
 
 3685        if (posix_fallocate(cache_info->file,offset+1,extent-offset) != 0)
 
 3686          return(MagickFalse);
 
 3689  offset=(MagickOffsetType) lseek(cache_info->file,0,SEEK_SET);
 
 3691    return(MagickFalse);
 
 3695static MagickBooleanType OpenPixelCache(Image *image,
const MapMode mode,
 
 3696  ExceptionInfo *exception)
 
 3699    *magick_restrict cache_info,
 
 3703    format[MagickPathExtent],
 
 3704    message[MagickPathExtent];
 
 3721  assert(image != (
const Image *) NULL);
 
 3722  assert(image->signature == MagickCoreSignature);
 
 3723  assert(image->cache != (Cache) NULL);
 
 3724  if (IsEventLogging() != MagickFalse)
 
 3725    (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
 
 3726  if (cache_anonymous_memory < 0)
 
 3734      cache_anonymous_memory=0;
 
 3735      value=GetPolicyValue(
"pixel-cache-memory");
 
 3736      if (value == (
char *) NULL)
 
 3737        value=GetPolicyValue(
"cache:memory-map");
 
 3738      if (LocaleCompare(value,
"anonymous") == 0)
 
 3740#if defined(MAGICKCORE_HAVE_MMAP) && defined(MAP_ANONYMOUS) 
 3741          cache_anonymous_memory=1;
 
 3743          (void) ThrowMagickException(exception,GetMagickModule(),
 
 3744            MissingDelegateError,
"DelegateLibrarySupportNotBuiltIn",
 
 3745            "`%s' (policy requires anonymous memory mapping)",image->filename);
 
 3748      value=DestroyString(value);
 
 3750  if ((image->columns == 0) || (image->rows == 0))
 
 3751    ThrowBinaryException(CacheError,
"NoPixelsDefinedInCache",image->filename);
 
 3752  cache_info=(CacheInfo *) image->cache;
 
 3753  assert(cache_info->signature == MagickCoreSignature);
 
 3754  if (((MagickSizeType) image->columns > cache_info->width_limit) ||
 
 3755      ((MagickSizeType) image->rows > cache_info->height_limit))
 
 3757      (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
 
 3758        "WidthOrHeightExceedsLimit",
"`%s' (%.20gx%.20g) > (%.20gx%.20g)",
 
 3759        image->filename, (
double) image->columns, (
double) image->rows,
 
 3760        (
double) cache_info->width_limit,(
double) cache_info->height_limit);
 
 3761      return(MagickFalse);
 
 3763  if (GetMagickResourceLimit(ListLengthResource) != MagickResourceInfinity)
 
 3765      length=GetImageListLength(image);
 
 3766      if (AcquireMagickResource(ListLengthResource,length) == MagickFalse)
 
 3767        ThrowBinaryException(ResourceLimitError,
"ListLengthExceedsLimit",
 
 3770  source_info=(*cache_info);
 
 3771  source_info.file=(-1);
 
 3772  (void) FormatLocaleString(cache_info->filename,MagickPathExtent,
"%s[%.20g]",
 
 3773    image->filename,(
double) image->scene);
 
 3774  cache_info->storage_class=image->storage_class;
 
 3775  cache_info->colorspace=image->colorspace;
 
 3776  cache_info->alpha_trait=image->alpha_trait;
 
 3777  cache_info->channels=image->channels;
 
 3778  cache_info->rows=image->rows;
 
 3779  cache_info->columns=image->columns;
 
 3780  status=ResetPixelChannelMap(image,exception);
 
 3781  if (status == MagickFalse)
 
 3782    return(MagickFalse);
 
 3783  cache_info->number_channels=GetPixelChannels(image);
 
 3784  (void) memcpy(cache_info->channel_map,image->channel_map,MaxPixelChannels*
 
 3785    sizeof(*image->channel_map));
 
 3786  cache_info->metacontent_extent=image->metacontent_extent;
 
 3787  cache_info->mode=mode;
 
 3788  number_pixels=(MagickSizeType) cache_info->columns*cache_info->rows;
 
 3789  packet_size=MagickMax(cache_info->number_channels,1)*
sizeof(Quantum);
 
 3790  if (image->metacontent_extent != 0)
 
 3791    packet_size+=cache_info->metacontent_extent;
 
 3792  length=number_pixels*packet_size;
 
 3793  columns=(size_t) (length/cache_info->rows/packet_size);
 
 3794  if ((cache_info->columns != columns) || ((ssize_t) cache_info->columns < 0) ||
 
 3795      ((ssize_t) cache_info->rows < 0))
 
 3796    ThrowBinaryException(ResourceLimitError,
"PixelCacheAllocationFailed",
 
 3798  cache_info->length=length;
 
 3799  if (image->ping != MagickFalse)
 
 3801      cache_info->type=PingCache;
 
 3804  status=AcquireMagickResource(AreaResource,(MagickSizeType)
 
 3805    cache_info->columns*cache_info->rows);
 
 3806  if (cache_info->mode == PersistMode)
 
 3808  length=number_pixels*(cache_info->number_channels*
sizeof(Quantum)+
 
 3809    cache_info->metacontent_extent);
 
 3810  if ((status != MagickFalse) &&
 
 3811      (length == (MagickSizeType) ((
size_t) length)) &&
 
 3812      ((cache_info->type == UndefinedCache) ||
 
 3813       (cache_info->type == MemoryCache)))
 
 3815      status=AcquireMagickResource(MemoryResource,cache_info->length);
 
 3816      if (status != MagickFalse)
 
 3819          if (cache_anonymous_memory <= 0)
 
 3821              cache_info->mapped=MagickFalse;
 
 3822              cache_info->pixels=(Quantum *) MagickAssumeAligned(
 
 3823                AcquireAlignedMemory(1,(
size_t) cache_info->length));
 
 3827              cache_info->mapped=MagickTrue;
 
 3828              cache_info->pixels=(Quantum *) MapBlob(-1,IOMode,0,(
size_t)
 
 3829                cache_info->length);
 
 3831          if (cache_info->pixels == (Quantum *) NULL)
 
 3833              cache_info->mapped=source_info.mapped;
 
 3834              cache_info->pixels=source_info.pixels;
 
 3841              cache_info->type=MemoryCache;
 
 3842              cache_info->metacontent=(
void *) NULL;
 
 3843              if (cache_info->metacontent_extent != 0)
 
 3844                cache_info->metacontent=(
void *) (cache_info->pixels+
 
 3845                  cache_info->number_channels*number_pixels);
 
 3846              if ((source_info.storage_class != UndefinedClass) &&
 
 3849                  status=ClonePixelCacheRepository(cache_info,&source_info,
 
 3851                  RelinquishPixelCachePixels(&source_info);
 
 3853              if (cache_info->debug != MagickFalse)
 
 3855                  (void) FormatMagickSize(cache_info->length,MagickTrue,
"B",
 
 3856                    MagickPathExtent,format);
 
 3857                  type=CommandOptionToMnemonic(MagickCacheOptions,(ssize_t)
 
 3859                  (void) FormatLocaleString(message,MagickPathExtent,
 
 3860                    "open %s (%s %s, %.20gx%.20gx%.20g %s)",
 
 3861                    cache_info->filename,cache_info->mapped != MagickFalse ?
 
 3862                    "Anonymous" : 
"Heap",type,(
double) cache_info->columns,
 
 3863                    (
double) cache_info->rows,(
double)
 
 3864                    cache_info->number_channels,format);
 
 3865                  (void) LogMagickEvent(CacheEvent,GetMagickModule(),
"%s",
 
 3868              cache_info->storage_class=image->storage_class;
 
 3871                  if ((source_info.storage_class != UndefinedClass) &&
 
 3873                    RelinquishPixelCachePixels(&source_info);
 
 3874                  cache_info->type=UndefinedCache;
 
 3875                  return(MagickFalse);
 
 3881  status=AcquireMagickResource(DiskResource,cache_info->length);
 
 3882  hosts=(
const char *) GetImageRegistry(StringRegistryType,
"cache:hosts",
 
 3884  if ((status == MagickFalse) && (hosts != (
const char *) NULL))
 
 3892      server_info=AcquireDistributeCacheInfo(exception);
 
 3893      if (server_info != (DistributeCacheInfo *) NULL)
 
 3895          status=OpenDistributePixelCache(server_info,image);
 
 3896          if (status == MagickFalse)
 
 3898              ThrowFileException(exception,CacheError,
"UnableToOpenPixelCache",
 
 3899                GetDistributeCacheHostname(server_info));
 
 3900              server_info=DestroyDistributeCacheInfo(server_info);
 
 3908              cache_info->type=DistributedCache;
 
 3909              cache_info->server_info=server_info;
 
 3910              (void) FormatLocaleString(cache_info->cache_filename,
 
 3911                MagickPathExtent,
"%s:%d",GetDistributeCacheHostname(
 
 3912                (DistributeCacheInfo *) cache_info->server_info),
 
 3913                GetDistributeCachePort((DistributeCacheInfo *)
 
 3914                cache_info->server_info));
 
 3915              if ((source_info.storage_class != UndefinedClass) &&
 
 3918                  status=ClonePixelCacheRepository(cache_info,&source_info,
 
 3920                  RelinquishPixelCachePixels(&source_info);
 
 3922              if (cache_info->debug != MagickFalse)
 
 3924                  (void) FormatMagickSize(cache_info->length,MagickFalse,
"B",
 
 3925                    MagickPathExtent,format);
 
 3926                  type=CommandOptionToMnemonic(MagickCacheOptions,(ssize_t)
 
 3928                  (void) FormatLocaleString(message,MagickPathExtent,
 
 3929                    "open %s (%s[%d], %s, %.20gx%.20gx%.20g %s)",
 
 3930                    cache_info->filename,cache_info->cache_filename,
 
 3931                    GetDistributeCacheFile((DistributeCacheInfo *)
 
 3932                    cache_info->server_info),type,(
double) cache_info->columns,
 
 3933                    (
double) cache_info->rows,(
double)
 
 3934                    cache_info->number_channels,format);
 
 3935                  (void) LogMagickEvent(CacheEvent,GetMagickModule(),
"%s",
 
 3940                  if ((source_info.storage_class != UndefinedClass) &&
 
 3942                    RelinquishPixelCachePixels(&source_info);
 
 3943                  cache_info->type=UndefinedCache;
 
 3944                  return(MagickFalse);
 
 3949      if ((source_info.storage_class != UndefinedClass) && (mode != ReadMode))
 
 3950        RelinquishPixelCachePixels(&source_info);
 
 3951      cache_info->type=UndefinedCache;
 
 3952      (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
 
 3953        "CacheResourcesExhausted",
"`%s'",image->filename);
 
 3954      return(MagickFalse);
 
 3959  if (status == MagickFalse)
 
 3961      if ((source_info.storage_class != UndefinedClass) && (mode != ReadMode))
 
 3962        RelinquishPixelCachePixels(&source_info);
 
 3963      cache_info->type=UndefinedCache;
 
 3964      (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
 
 3965        "CacheResourcesExhausted",
"`%s'",image->filename);
 
 3966      return(MagickFalse);
 
 3968  if ((source_info.storage_class != UndefinedClass) && (mode != ReadMode) &&
 
 3969      (cache_info->mode != PersistMode))
 
 3971      (void) ClosePixelCacheOnDisk(cache_info);
 
 3972      *cache_info->cache_filename=
'\0';
 
 3974  if (OpenPixelCacheOnDisk(cache_info,mode) == MagickFalse)
 
 3976      if ((source_info.storage_class != UndefinedClass) && (mode != ReadMode))
 
 3977        RelinquishPixelCachePixels(&source_info);
 
 3978      cache_info->type=UndefinedCache;
 
 3979      ThrowFileException(exception,CacheError,
"UnableToOpenPixelCache",
 
 3981      return(MagickFalse);
 
 3983  status=SetPixelCacheExtent(image,(MagickSizeType) cache_info->offset+
 
 3984    cache_info->length);
 
 3985  if (status == MagickFalse)
 
 3987      if ((source_info.storage_class != UndefinedClass) && (mode != ReadMode))
 
 3988        RelinquishPixelCachePixels(&source_info);
 
 3989      cache_info->type=UndefinedCache;
 
 3990      ThrowFileException(exception,CacheError,
"UnableToExtendCache",
 
 3992      return(MagickFalse);
 
 3994  cache_info->type=DiskCache;
 
 3995  length=number_pixels*(cache_info->number_channels*
sizeof(Quantum)+
 
 3996    cache_info->metacontent_extent);
 
 3997  if (length == (MagickSizeType) ((
size_t) length))
 
 3999      status=AcquireMagickResource(MapResource,cache_info->length);
 
 4000      if (status != MagickFalse)
 
 4002          cache_info->pixels=(Quantum *) MapBlob(cache_info->file,mode,
 
 4003            cache_info->offset,(
size_t) cache_info->length);
 
 4004          if (cache_info->pixels == (Quantum *) NULL)
 
 4006              cache_info->mapped=source_info.mapped;
 
 4007              cache_info->pixels=source_info.pixels;
 
 4008              RelinquishMagickResource(MapResource,cache_info->length);
 
 4015              (void) ClosePixelCacheOnDisk(cache_info);
 
 4016              cache_info->type=MapCache;
 
 4017              cache_info->mapped=MagickTrue;
 
 4018              cache_info->metacontent=(
void *) NULL;
 
 4019              if (cache_info->metacontent_extent != 0)
 
 4020                cache_info->metacontent=(
void *) (cache_info->pixels+
 
 4021                  cache_info->number_channels*number_pixels);
 
 4022              if ((source_info.storage_class != UndefinedClass) &&
 
 4025                  status=ClonePixelCacheRepository(cache_info,&source_info,
 
 4027                  RelinquishPixelCachePixels(&source_info);
 
 4029              if (cache_info->debug != MagickFalse)
 
 4031                  (void) FormatMagickSize(cache_info->length,MagickTrue,
"B",
 
 4032                    MagickPathExtent,format);
 
 4033                  type=CommandOptionToMnemonic(MagickCacheOptions,(ssize_t)
 
 4035                  (void) FormatLocaleString(message,MagickPathExtent,
 
 4036                    "open %s (%s[%d], %s, %.20gx%.20gx%.20g %s)",
 
 4037                    cache_info->filename,cache_info->cache_filename,
 
 4038                    cache_info->file,type,(
double) cache_info->columns,
 
 4039                    (
double) cache_info->rows,(
double)
 
 4040                    cache_info->number_channels,format);
 
 4041                  (void) LogMagickEvent(CacheEvent,GetMagickModule(),
"%s",
 
 4046                  if ((source_info.storage_class != UndefinedClass) &&
 
 4048                    RelinquishPixelCachePixels(&source_info);
 
 4049                  cache_info->type=UndefinedCache;
 
 4050                  return(MagickFalse);
 
 4057  if ((source_info.storage_class != UndefinedClass) && (mode != ReadMode))
 
 4059      status=ClonePixelCacheRepository(cache_info,&source_info,exception);
 
 4060      RelinquishPixelCachePixels(&source_info);
 
 4062  if (cache_info->debug != MagickFalse)
 
 4064      (void) FormatMagickSize(cache_info->length,MagickFalse,
"B",
 
 4065        MagickPathExtent,format);
 
 4066      type=CommandOptionToMnemonic(MagickCacheOptions,(ssize_t)
 
 4068      (void) FormatLocaleString(message,MagickPathExtent,
 
 4069        "open %s (%s[%d], %s, %.20gx%.20gx%.20g %s)",cache_info->filename,
 
 4070        cache_info->cache_filename,cache_info->file,type,(
double)
 
 4071        cache_info->columns,(
double) cache_info->rows,(
double)
 
 4072        cache_info->number_channels,format);
 
 4073      (void) LogMagickEvent(CacheEvent,GetMagickModule(),
"%s",message);
 
 4077      cache_info->type=UndefinedCache;
 
 4078      return(MagickFalse);
 
 4120MagickExport MagickBooleanType PersistPixelCache(Image *image,
 
 4121  const char *filename,
const MagickBooleanType attach,MagickOffsetType *offset,
 
 4122  ExceptionInfo *exception)
 
 4125    *magick_restrict cache_info,
 
 4126    *magick_restrict clone_info;
 
 4134  assert(image != (Image *) NULL);
 
 4135  assert(image->signature == MagickCoreSignature);
 
 4136  if (IsEventLogging() != MagickFalse)
 
 4137    (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
 
 4138  assert(image->cache != (
void *) NULL);
 
 4139  assert(filename != (
const char *) NULL);
 
 4140  assert(offset != (MagickOffsetType *) NULL);
 
 4141  page_size=GetMagickPageSize();
 
 4142  cache_info=(CacheInfo *) image->cache;
 
 4143  assert(cache_info->signature == MagickCoreSignature);
 
 4144#if defined(MAGICKCORE_OPENCL_SUPPORT) 
 4145  CopyOpenCLBuffer(cache_info);
 
 4147  if (attach != MagickFalse)
 
 4152      if (cache_info->debug != MagickFalse)
 
 4153        (void) LogMagickEvent(CacheEvent,GetMagickModule(),
 
 4154          "attach persistent cache");
 
 4155      (void) CopyMagickString(cache_info->cache_filename,filename,
 
 4157      cache_info->type=MapCache;
 
 4158      cache_info->offset=(*offset);
 
 4159      if (OpenPixelCache(image,ReadMode,exception) == MagickFalse)
 
 4160        return(MagickFalse);
 
 4161      *offset=(*offset+(MagickOffsetType) cache_info->length+page_size-
 
 4162        ((MagickOffsetType) cache_info->length % page_size));
 
 4168  status=AcquireMagickResource(DiskResource,cache_info->length);
 
 4169  if (status == MagickFalse)
 
 4171      (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
 
 4172        "CacheResourcesExhausted",
"`%s'",image->filename);
 
 4173      return(MagickFalse);
 
 4175  clone_info=(CacheInfo *) ClonePixelCache(cache_info);
 
 4176  clone_info->type=DiskCache;
 
 4177  (void) CopyMagickString(clone_info->cache_filename,filename,MagickPathExtent);
 
 4178  clone_info->file=(-1);
 
 4179  clone_info->storage_class=cache_info->storage_class;
 
 4180  clone_info->colorspace=cache_info->colorspace;
 
 4181  clone_info->alpha_trait=cache_info->alpha_trait;
 
 4182  clone_info->channels=cache_info->channels;
 
 4183  clone_info->columns=cache_info->columns;
 
 4184  clone_info->rows=cache_info->rows;
 
 4185  clone_info->number_channels=cache_info->number_channels;
 
 4186  clone_info->metacontent_extent=cache_info->metacontent_extent;
 
 4187  clone_info->mode=PersistMode;
 
 4188  clone_info->length=cache_info->length;
 
 4189  (void) memcpy(clone_info->channel_map,cache_info->channel_map,
 
 4190    MaxPixelChannels*
sizeof(*cache_info->channel_map));
 
 4191  clone_info->offset=(*offset);
 
 4192  status=OpenPixelCacheOnDisk(clone_info,WriteMode);
 
 4193  if (status != MagickFalse)
 
 4194    status=ClonePixelCacheRepository(clone_info,cache_info,exception);
 
 4195  *offset=(*offset+(MagickOffsetType) cache_info->length+page_size-
 
 4196    ((MagickOffsetType) cache_info->length % page_size));
 
 4197  clone_info=(CacheInfo *) DestroyPixelCache(clone_info);
 
 4239MagickPrivate Quantum *QueueAuthenticPixelCacheNexus(Image *image,
 
 4240  const ssize_t x,
const ssize_t y,
const size_t columns,
const size_t rows,
 
 4241  const MagickBooleanType clone,NexusInfo *nexus_info,ExceptionInfo *exception)
 
 4244    *magick_restrict cache_info;
 
 4253    *magick_restrict pixels;
 
 4258  assert(image != (
const Image *) NULL);
 
 4259  assert(image->signature == MagickCoreSignature);
 
 4260  assert(image->cache != (Cache) NULL);
 
 4261  cache_info=(CacheInfo *) GetImagePixelCache(image,clone,exception);
 
 4262  if (cache_info == (Cache) NULL)
 
 4263    return((Quantum *) NULL);
 
 4264  assert(cache_info->signature == MagickCoreSignature);
 
 4265  if ((cache_info->columns == 0) || (cache_info->rows == 0) || (x < 0) ||
 
 4266      (y < 0) || (x >= (ssize_t) cache_info->columns) ||
 
 4267      (y >= (ssize_t) cache_info->rows))
 
 4269      (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
 
 4270        "PixelsAreNotAuthentic",
"`%s'",image->filename);
 
 4271      return((Quantum *) NULL);
 
 4273  if (IsValidPixelOffset(y,cache_info->columns) == MagickFalse)
 
 4274    return((Quantum *) NULL);
 
 4275  offset=y*(MagickOffsetType) cache_info->columns+x;
 
 4277    return((Quantum *) NULL);
 
 4278  number_pixels=(MagickSizeType) cache_info->columns*cache_info->rows;
 
 4279  offset+=((MagickOffsetType) rows-1)*(MagickOffsetType) cache_info->columns+
 
 4280    (MagickOffsetType) columns-1;
 
 4281  if ((MagickSizeType) offset >= number_pixels)
 
 4282    return((Quantum *) NULL);
 
 4286  pixels=SetPixelCacheNexusPixels(cache_info,WriteMode,x,y,columns,rows,
 
 4287    ((image->channels & WriteMaskChannel) != 0) ||
 
 4288    ((image->channels & CompositeMaskChannel) != 0) ? MagickTrue : MagickFalse,
 
 4289    nexus_info,exception);
 
 4326static Quantum *QueueAuthenticPixelsCache(Image *image,
const ssize_t x,
 
 4327  const ssize_t y,
const size_t columns,
const size_t rows,
 
 4328  ExceptionInfo *exception)
 
 4331    *magick_restrict cache_info;
 
 4334    id = GetOpenMPThreadId();
 
 4337    *magick_restrict pixels;
 
 4339  assert(image != (
const Image *) NULL);
 
 4340  assert(image->signature == MagickCoreSignature);
 
 4341  assert(image->cache != (Cache) NULL);
 
 4342  cache_info=(CacheInfo *) image->cache;
 
 4343  assert(cache_info->signature == MagickCoreSignature);
 
 4344  assert(
id < (
int) cache_info->number_threads);
 
 4345  pixels=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickFalse,
 
 4346    cache_info->nexus_info[
id],exception);
 
 4406MagickExport Quantum *QueueAuthenticPixels(Image *image,
const ssize_t x,
 
 4407  const ssize_t y,
const size_t columns,
const size_t rows,
 
 4408  ExceptionInfo *exception)
 
 4411    *magick_restrict cache_info;
 
 4414    id = GetOpenMPThreadId();
 
 4417    *magick_restrict pixels;
 
 4419  assert(image != (Image *) NULL);
 
 4420  assert(image->signature == MagickCoreSignature);
 
 4421  assert(image->cache != (Cache) NULL);
 
 4422  cache_info=(CacheInfo *) image->cache;
 
 4423  assert(cache_info->signature == MagickCoreSignature);
 
 4424  if (cache_info->methods.queue_authentic_pixels_handler !=
 
 4425      (QueueAuthenticPixelsHandler) NULL)
 
 4427      pixels=cache_info->methods.queue_authentic_pixels_handler(image,x,y,
 
 4428        columns,rows,exception);
 
 4431  assert(
id < (
int) cache_info->number_threads);
 
 4432  pixels=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickFalse,
 
 4433    cache_info->nexus_info[
id],exception);
 
 4466static inline MagickOffsetType ReadPixelCacheRegion(
 
 4467  const CacheInfo *magick_restrict cache_info,
const MagickOffsetType offset,
 
 4468  const MagickSizeType length,
unsigned char *magick_restrict buffer)
 
 4476#if !defined(MAGICKCORE_HAVE_PREAD) 
 4477  if (lseek(cache_info->file,offset,SEEK_SET) < 0)
 
 4478    return((MagickOffsetType) -1);
 
 4480  for (i=0; i < (MagickOffsetType) length; i+=count)
 
 4482#if !defined(MAGICKCORE_HAVE_PREAD) 
 4483    count=read(cache_info->file,buffer+i,(
size_t) MagickMin(length-
 
 4484      (MagickSizeType) i,(
size_t) MagickMaxBufferExtent));
 
 4486    count=pread(cache_info->file,buffer+i,(
size_t) MagickMin(length-
 
 4487      (MagickSizeType) i,(
size_t) MagickMaxBufferExtent),offset+i);
 
 4499static MagickBooleanType ReadPixelCacheMetacontent(
 
 4500  CacheInfo *magick_restrict cache_info,NexusInfo *magick_restrict nexus_info,
 
 4501  ExceptionInfo *exception)
 
 4520  if (cache_info->metacontent_extent == 0)
 
 4521    return(MagickFalse);
 
 4522  if (nexus_info->authentic_pixel_cache != MagickFalse)
 
 4524  if (IsValidPixelOffset(nexus_info->region.y,cache_info->columns) == MagickFalse)
 
 4525    return(MagickFalse);
 
 4526  offset=nexus_info->region.y*(MagickOffsetType) cache_info->columns+
 
 4527    nexus_info->region.x;
 
 4528  length=(MagickSizeType) nexus_info->region.width*
 
 4529    cache_info->metacontent_extent;
 
 4530  extent=length*nexus_info->region.height;
 
 4531  rows=nexus_info->region.height;
 
 4533  q=(
unsigned char *) nexus_info->metacontent;
 
 4534  switch (cache_info->type)
 
 4545      if ((cache_info->columns == nexus_info->region.width) &&
 
 4546          (extent == (MagickSizeType) ((
size_t) extent)))
 
 4551      p=(
unsigned char *) cache_info->metacontent+offset*(MagickOffsetType)
 
 4552        cache_info->metacontent_extent;
 
 4553      for (y=0; y < (ssize_t) rows; y++)
 
 4555        (void) memcpy(q,p,(
size_t) length);
 
 4556        p+=(ptrdiff_t) cache_info->metacontent_extent*cache_info->columns;
 
 4557        q+=(ptrdiff_t) cache_info->metacontent_extent*nexus_info->region.width;
 
 4566      LockSemaphoreInfo(cache_info->file_semaphore);
 
 4567      if (OpenPixelCacheOnDisk(cache_info,IOMode) == MagickFalse)
 
 4569          ThrowFileException(exception,FileOpenError,
"UnableToOpenFile",
 
 4570            cache_info->cache_filename);
 
 4571          UnlockSemaphoreInfo(cache_info->file_semaphore);
 
 4572          return(MagickFalse);
 
 4574      if ((cache_info->columns == nexus_info->region.width) &&
 
 4575          (extent <= MagickMaxBufferExtent))
 
 4580      extent=(MagickSizeType) cache_info->columns*cache_info->rows;
 
 4581      for (y=0; y < (ssize_t) rows; y++)
 
 4583        count=ReadPixelCacheRegion(cache_info,cache_info->offset+
 
 4584          (MagickOffsetType) extent*(MagickOffsetType)
 
 4585          cache_info->number_channels*(MagickOffsetType) 
sizeof(Quantum)+offset*
 
 4586          (MagickOffsetType) cache_info->metacontent_extent,length,
 
 4587          (
unsigned char *) q);
 
 4588        if (count != (MagickOffsetType) length)
 
 4590        offset+=(MagickOffsetType) cache_info->columns;
 
 4591        q+=(ptrdiff_t) cache_info->metacontent_extent*nexus_info->region.width;
 
 4593      if (IsFileDescriptorLimitExceeded() != MagickFalse)
 
 4594        (void) ClosePixelCacheOnDisk(cache_info);
 
 4595      UnlockSemaphoreInfo(cache_info->file_semaphore);
 
 4598    case DistributedCache:
 
 4606      LockSemaphoreInfo(cache_info->file_semaphore);
 
 4607      region=nexus_info->region;
 
 4608      if ((cache_info->columns != nexus_info->region.width) ||
 
 4609          (extent > MagickMaxBufferExtent))
 
 4616      for (y=0; y < (ssize_t) rows; y++)
 
 4618        count=ReadDistributePixelCacheMetacontent((DistributeCacheInfo *)
 
 4619          cache_info->server_info,®ion,length,(
unsigned char *) q);
 
 4620        if (count != (MagickOffsetType) length)
 
 4622        q+=(ptrdiff_t) cache_info->metacontent_extent*nexus_info->region.width;
 
 4625      UnlockSemaphoreInfo(cache_info->file_semaphore);
 
 4631  if (y < (ssize_t) rows)
 
 4633      ThrowFileException(exception,CacheError,
"UnableToReadPixelCache",
 
 4634        cache_info->cache_filename);
 
 4635      return(MagickFalse);
 
 4637  if ((cache_info->debug != MagickFalse) &&
 
 4638      (CacheTick(nexus_info->region.y,cache_info->rows) != MagickFalse))
 
 4639    (void) LogMagickEvent(CacheEvent,GetMagickModule(),
 
 4640      "%s[%.20gx%.20g%+.20g%+.20g]",cache_info->filename,(
double)
 
 4641      nexus_info->region.width,(
double) nexus_info->region.height,(
double)
 
 4642      nexus_info->region.x,(
double) nexus_info->region.y);
 
 4674static MagickBooleanType ReadPixelCachePixels(
 
 4675  CacheInfo *magick_restrict cache_info,NexusInfo *magick_restrict nexus_info,
 
 4676  ExceptionInfo *exception)
 
 4696  if (nexus_info->authentic_pixel_cache != MagickFalse)
 
 4698  if (IsValidPixelOffset(nexus_info->region.y,cache_info->columns) == MagickFalse)
 
 4699    return(MagickFalse);
 
 4700  offset=nexus_info->region.y*(MagickOffsetType) cache_info->columns;
 
 4701  if ((ssize_t) (offset/cache_info->columns) != nexus_info->region.y)
 
 4702    return(MagickFalse);
 
 4703  offset+=nexus_info->region.x;
 
 4704  number_channels=cache_info->number_channels;
 
 4705  length=(MagickSizeType) number_channels*nexus_info->region.width*
 
 4707  if ((length/number_channels/
sizeof(Quantum)) != nexus_info->region.width)
 
 4708    return(MagickFalse);
 
 4709  rows=nexus_info->region.height;
 
 4711  if ((extent == 0) || ((extent/length) != rows))
 
 4712    return(MagickFalse);
 
 4714  q=nexus_info->pixels;
 
 4715  switch (cache_info->type)
 
 4726      if ((cache_info->columns == nexus_info->region.width) &&
 
 4727          (extent == (MagickSizeType) ((
size_t) extent)))
 
 4732      p=cache_info->pixels+(MagickOffsetType) cache_info->number_channels*
 
 4734      for (y=0; y < (ssize_t) rows; y++)
 
 4736        (void) memcpy(q,p,(
size_t) length);
 
 4737        p+=(ptrdiff_t) cache_info->number_channels*cache_info->columns;
 
 4738        q+=(ptrdiff_t) cache_info->number_channels*nexus_info->region.width;
 
 4747      LockSemaphoreInfo(cache_info->file_semaphore);
 
 4748      if (OpenPixelCacheOnDisk(cache_info,IOMode) == MagickFalse)
 
 4750          ThrowFileException(exception,FileOpenError,
"UnableToOpenFile",
 
 4751            cache_info->cache_filename);
 
 4752          UnlockSemaphoreInfo(cache_info->file_semaphore);
 
 4753          return(MagickFalse);
 
 4755      if ((cache_info->columns == nexus_info->region.width) &&
 
 4756          (extent <= MagickMaxBufferExtent))
 
 4761      for (y=0; y < (ssize_t) rows; y++)
 
 4763        count=ReadPixelCacheRegion(cache_info,cache_info->offset+offset*
 
 4764          (MagickOffsetType) cache_info->number_channels*(MagickOffsetType)
 
 4765          sizeof(*q),length,(
unsigned char *) q);
 
 4766        if (count != (MagickOffsetType) length)
 
 4768        offset+=(MagickOffsetType) cache_info->columns;
 
 4769        q+=(ptrdiff_t) cache_info->number_channels*nexus_info->region.width;
 
 4771      if (IsFileDescriptorLimitExceeded() != MagickFalse)
 
 4772        (void) ClosePixelCacheOnDisk(cache_info);
 
 4773      UnlockSemaphoreInfo(cache_info->file_semaphore);
 
 4776    case DistributedCache:
 
 4784      LockSemaphoreInfo(cache_info->file_semaphore);
 
 4785      region=nexus_info->region;
 
 4786      if ((cache_info->columns != nexus_info->region.width) ||
 
 4787          (extent > MagickMaxBufferExtent))
 
 4794      for (y=0; y < (ssize_t) rows; y++)
 
 4796        count=ReadDistributePixelCachePixels((DistributeCacheInfo *)
 
 4797          cache_info->server_info,®ion,length,(
unsigned char *) q);
 
 4798        if (count != (MagickOffsetType) length)
 
 4800        q+=(ptrdiff_t) cache_info->number_channels*nexus_info->region.width;
 
 4803      UnlockSemaphoreInfo(cache_info->file_semaphore);
 
 4809  if (y < (ssize_t) rows)
 
 4811      ThrowFileException(exception,CacheError,
"UnableToReadPixelCache",
 
 4812        cache_info->cache_filename);
 
 4813      return(MagickFalse);
 
 4815  if ((cache_info->debug != MagickFalse) &&
 
 4816      (CacheTick(nexus_info->region.y,cache_info->rows) != MagickFalse))
 
 4817    (void) LogMagickEvent(CacheEvent,GetMagickModule(),
 
 4818      "%s[%.20gx%.20g%+.20g%+.20g]",cache_info->filename,(
double)
 
 4819      nexus_info->region.width,(
double) nexus_info->region.height,(
double)
 
 4820      nexus_info->region.x,(
double) nexus_info->region.y);
 
 4847MagickPrivate Cache ReferencePixelCache(Cache cache)
 
 4850    *magick_restrict cache_info;
 
 4852  assert(cache != (Cache *) NULL);
 
 4853  cache_info=(CacheInfo *) cache;
 
 4854  assert(cache_info->signature == MagickCoreSignature);
 
 4855  LockSemaphoreInfo(cache_info->semaphore);
 
 4856  cache_info->reference_count++;
 
 4857  UnlockSemaphoreInfo(cache_info->semaphore);
 
 4883MagickPrivate 
void ResetPixelCacheChannels(Image *image)
 
 4886    *magick_restrict cache_info;
 
 4888  assert(image != (
const Image *) NULL);
 
 4889  assert(image->signature == MagickCoreSignature);
 
 4890  assert(image->cache != (Cache) NULL);
 
 4891  cache_info=(CacheInfo *) image->cache;
 
 4892  assert(cache_info->signature == MagickCoreSignature);
 
 4893  cache_info->number_channels=GetPixelChannels(image);
 
 4914MagickPrivate 
void ResetCacheAnonymousMemory(
void)
 
 4916  cache_anonymous_memory=0;
 
 4948MagickExport MagickBooleanType ReshapePixelCache(Image *image,
 
 4949  const size_t columns,
const size_t rows,ExceptionInfo *exception)
 
 4957  assert(image != (Image *) NULL);
 
 4958  assert(image->signature == MagickCoreSignature);
 
 4959  if (IsEventLogging() != MagickFalse)
 
 4960    (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
 
 4961  assert(image->cache != (
void *) NULL);
 
 4962  extent=(MagickSizeType) columns*rows;
 
 4963  if (extent > ((MagickSizeType) image->columns*image->rows))
 
 4964    ThrowBinaryException(ImageError,
"WidthOrHeightExceedsLimit",
 
 4966  image->columns=columns;
 
 4968  cache_info=(CacheInfo *) image->cache;
 
 4969  cache_info->columns=columns;
 
 4970  cache_info->rows=rows;
 
 4971  return(SyncImagePixelCache(image,exception));
 
 4998MagickPrivate 
void SetPixelCacheMethods(Cache cache,CacheMethods *cache_methods)
 
 5001    *magick_restrict cache_info;
 
 5003  GetOneAuthenticPixelFromHandler
 
 5004    get_one_authentic_pixel_from_handler;
 
 5006  GetOneVirtualPixelFromHandler
 
 5007    get_one_virtual_pixel_from_handler;
 
 5012  assert(cache != (Cache) NULL);
 
 5013  assert(cache_methods != (CacheMethods *) NULL);
 
 5014  cache_info=(CacheInfo *) cache;
 
 5015  assert(cache_info->signature == MagickCoreSignature);
 
 5016  if (IsEventLogging() != MagickFalse)
 
 5017    (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
 
 5018      cache_info->filename);
 
 5019  if (cache_methods->get_virtual_pixel_handler != (GetVirtualPixelHandler) NULL)
 
 5020    cache_info->methods.get_virtual_pixel_handler=
 
 5021      cache_methods->get_virtual_pixel_handler;
 
 5022  if (cache_methods->destroy_pixel_handler != (DestroyPixelHandler) NULL)
 
 5023    cache_info->methods.destroy_pixel_handler=
 
 5024      cache_methods->destroy_pixel_handler;
 
 5025  if (cache_methods->get_virtual_metacontent_from_handler !=
 
 5026      (GetVirtualMetacontentFromHandler) NULL)
 
 5027    cache_info->methods.get_virtual_metacontent_from_handler=
 
 5028      cache_methods->get_virtual_metacontent_from_handler;
 
 5029  if (cache_methods->get_authentic_pixels_handler !=
 
 5030      (GetAuthenticPixelsHandler) NULL)
 
 5031    cache_info->methods.get_authentic_pixels_handler=
 
 5032      cache_methods->get_authentic_pixels_handler;
 
 5033  if (cache_methods->queue_authentic_pixels_handler !=
 
 5034      (QueueAuthenticPixelsHandler) NULL)
 
 5035    cache_info->methods.queue_authentic_pixels_handler=
 
 5036      cache_methods->queue_authentic_pixels_handler;
 
 5037  if (cache_methods->sync_authentic_pixels_handler !=
 
 5038      (SyncAuthenticPixelsHandler) NULL)
 
 5039    cache_info->methods.sync_authentic_pixels_handler=
 
 5040      cache_methods->sync_authentic_pixels_handler;
 
 5041  if (cache_methods->get_authentic_pixels_from_handler !=
 
 5042      (GetAuthenticPixelsFromHandler) NULL)
 
 5043    cache_info->methods.get_authentic_pixels_from_handler=
 
 5044      cache_methods->get_authentic_pixels_from_handler;
 
 5045  if (cache_methods->get_authentic_metacontent_from_handler !=
 
 5046      (GetAuthenticMetacontentFromHandler) NULL)
 
 5047    cache_info->methods.get_authentic_metacontent_from_handler=
 
 5048      cache_methods->get_authentic_metacontent_from_handler;
 
 5049  get_one_virtual_pixel_from_handler=
 
 5050    cache_info->methods.get_one_virtual_pixel_from_handler;
 
 5051  if (get_one_virtual_pixel_from_handler !=
 
 5052      (GetOneVirtualPixelFromHandler) NULL)
 
 5053    cache_info->methods.get_one_virtual_pixel_from_handler=
 
 5054      cache_methods->get_one_virtual_pixel_from_handler;
 
 5055  get_one_authentic_pixel_from_handler=
 
 5056    cache_methods->get_one_authentic_pixel_from_handler;
 
 5057  if (get_one_authentic_pixel_from_handler !=
 
 5058      (GetOneAuthenticPixelFromHandler) NULL)
 
 5059    cache_info->methods.get_one_authentic_pixel_from_handler=
 
 5060      cache_methods->get_one_authentic_pixel_from_handler;
 
 5101static inline MagickBooleanType AcquireCacheNexusPixels(
 
 5102  const CacheInfo *magick_restrict cache_info,
const MagickSizeType length,
 
 5103  NexusInfo *magick_restrict nexus_info,ExceptionInfo *exception)
 
 5105  if (length != (MagickSizeType) ((
size_t) length))
 
 5107      (void) ThrowMagickException(exception,GetMagickModule(),
 
 5108        ResourceLimitError,
"PixelCacheAllocationFailed",
"`%s'",
 
 5109        cache_info->filename);
 
 5110      return(MagickFalse);
 
 5112  nexus_info->length=0;
 
 5113  nexus_info->mapped=MagickFalse;
 
 5114  if (cache_anonymous_memory <= 0)
 
 5116      nexus_info->cache=(Quantum *) MagickAssumeAligned(AcquireAlignedMemory(1,
 
 5118      if (nexus_info->cache != (Quantum *) NULL)
 
 5119        (void) memset(nexus_info->cache,0,(
size_t) length);
 
 5123      nexus_info->cache=(Quantum *) MapBlob(-1,IOMode,0,(
size_t) length);
 
 5124      if (nexus_info->cache != (Quantum *) NULL)
 
 5125        nexus_info->mapped=MagickTrue;
 
 5127  if (nexus_info->cache == (Quantum *) NULL)
 
 5129      (void) ThrowMagickException(exception,GetMagickModule(),
 
 5130        ResourceLimitError,
"PixelCacheAllocationFailed",
"`%s'",
 
 5131        cache_info->filename);
 
 5132      return(MagickFalse);
 
 5134  nexus_info->length=length;
 
 5138static inline void PrefetchPixelCacheNexusPixels(
const NexusInfo *nexus_info,
 
 5141  if (nexus_info->length < CACHE_LINE_SIZE)
 
 5143  if (mode == ReadMode)
 
 5145      MagickCachePrefetch((
unsigned char *) nexus_info->pixels+CACHE_LINE_SIZE,
 
 5149  MagickCachePrefetch((
unsigned char *) nexus_info->pixels+CACHE_LINE_SIZE,1,1);
 
 5152static Quantum *SetPixelCacheNexusPixels(
 
 5153  const CacheInfo *magick_restrict cache_info,
const MapMode mode,
 
 5154  const ssize_t x,
const ssize_t y,
const size_t width,
const size_t height,
 
 5155  const MagickBooleanType buffered,NexusInfo *magick_restrict nexus_info,
 
 5156  ExceptionInfo *exception)
 
 5165  assert(cache_info != (
const CacheInfo *) NULL);
 
 5166  assert(cache_info->signature == MagickCoreSignature);
 
 5167  if (cache_info->type == UndefinedCache)
 
 5168    return((Quantum *) NULL);
 
 5169  assert(nexus_info->signature == MagickCoreSignature);
 
 5170  (void) memset(&nexus_info->region,0,
sizeof(nexus_info->region));
 
 5171  if ((width == 0) || (height == 0))
 
 5173      (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
 
 5174        "NoPixelsDefinedInCache",
"`%s'",cache_info->filename);
 
 5175      return((Quantum *) NULL);
 
 5177  if (((MagickSizeType) width > cache_info->width_limit) ||
 
 5178      ((MagickSizeType) height > cache_info->height_limit))
 
 5180      (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
 
 5181        "WidthOrHeightExceedsLimit",
"`%s'",cache_info->filename);
 
 5182      return((Quantum *) NULL);
 
 5184  if ((IsValidPixelOffset(x,width) == MagickFalse) ||
 
 5185      (IsValidPixelOffset(y,height) == MagickFalse))
 
 5187      (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
 
 5188        "InvalidPixel",
"`%s'",cache_info->filename);
 
 5189      return((Quantum *) NULL);
 
 5191  if (((cache_info->type == MemoryCache) || (cache_info->type == MapCache)) &&
 
 5192      (buffered == MagickFalse))
 
 5194      if (((x >= 0) && (y >= 0) &&
 
 5195          (((ssize_t) height+y-1) < (ssize_t) cache_info->rows)) &&
 
 5196          (((x == 0) && (width == cache_info->columns)) || ((height == 1) &&
 
 5197          (((ssize_t) width+x-1) < (ssize_t) cache_info->columns))))
 
 5205          if (IsValidPixelOffset(y,cache_info->columns) == MagickFalse)
 
 5206            return((Quantum *) NULL);
 
 5207          offset=y*(MagickOffsetType) cache_info->columns+x;
 
 5208          nexus_info->pixels=cache_info->pixels+(MagickOffsetType)
 
 5209            cache_info->number_channels*offset;
 
 5210          nexus_info->metacontent=(
void *) NULL;
 
 5211          if (cache_info->metacontent_extent != 0)
 
 5212            nexus_info->metacontent=(
unsigned char *) cache_info->metacontent+
 
 5213              offset*(MagickOffsetType) cache_info->metacontent_extent;
 
 5214          nexus_info->region.width=width;
 
 5215          nexus_info->region.height=height;
 
 5216          nexus_info->region.x=x;
 
 5217          nexus_info->region.y=y;
 
 5218          nexus_info->authentic_pixel_cache=MagickTrue;
 
 5219          PrefetchPixelCacheNexusPixels(nexus_info,mode);
 
 5220          return(nexus_info->pixels);
 
 5226  number_pixels=(MagickSizeType) width*height;
 
 5227  length=MagickMax(number_pixels,MagickMax(cache_info->columns,
 
 5228    cache_info->rows))*cache_info->number_channels*
sizeof(*nexus_info->pixels);
 
 5229  if (cache_info->metacontent_extent != 0)
 
 5230    length+=number_pixels*cache_info->metacontent_extent;
 
 5232  if (nexus_info->cache == (Quantum *) NULL)
 
 5233    status=AcquireCacheNexusPixels(cache_info,length,nexus_info,exception);
 
 5235    if (nexus_info->length < length)
 
 5237        RelinquishCacheNexusPixels(nexus_info);
 
 5238        status=AcquireCacheNexusPixels(cache_info,length,nexus_info,exception);
 
 5240  if (status == MagickFalse)
 
 5241    return((Quantum *) NULL);
 
 5242  nexus_info->pixels=nexus_info->cache;
 
 5243  nexus_info->metacontent=(
void *) NULL;
 
 5244  if (cache_info->metacontent_extent != 0)
 
 5245    nexus_info->metacontent=(
void *) (nexus_info->pixels+
 
 5246      cache_info->number_channels*number_pixels);
 
 5247  nexus_info->region.width=width;
 
 5248  nexus_info->region.height=height;
 
 5249  nexus_info->region.x=x;
 
 5250  nexus_info->region.y=y;
 
 5251  nexus_info->authentic_pixel_cache=cache_info->type == PingCache ?
 
 5252    MagickTrue : MagickFalse;
 
 5253  PrefetchPixelCacheNexusPixels(nexus_info,mode);
 
 5254  return(nexus_info->pixels);
 
 5287static MagickBooleanType SetCacheAlphaChannel(Image *image,
const Quantum alpha,
 
 5288  ExceptionInfo *exception)
 
 5291    *magick_restrict image_view;
 
 5299  assert(image != (Image *) NULL);
 
 5300  assert(image->signature == MagickCoreSignature);
 
 5301  if (IsEventLogging() != MagickFalse)
 
 5302    (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
 
 5303  assert(image->cache != (Cache) NULL);
 
 5304  image->alpha_trait=BlendPixelTrait;
 
 5306  image_view=AcquireVirtualCacheView(image,exception);  
 
 5307#if defined(MAGICKCORE_OPENMP_SUPPORT) 
 5308  #pragma omp parallel for schedule(static) shared(status) \ 
 5309    magick_number_threads(image,image,image->rows,2) 
 5311  for (y=0; y < (ssize_t) image->rows; y++)
 
 5319    if (status == MagickFalse)
 
 5321    q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
 
 5322    if (q == (Quantum *) NULL)
 
 5327    for (x=0; x < (ssize_t) image->columns; x++)
 
 5329      SetPixelAlpha(image,alpha,q);
 
 5330      q+=(ptrdiff_t) GetPixelChannels(image);
 
 5332    status=SyncCacheViewAuthenticPixels(image_view,exception);
 
 5334  image_view=DestroyCacheView(image_view);
 
 5338MagickPrivate VirtualPixelMethod SetPixelCacheVirtualMethod(Image *image,
 
 5339  const VirtualPixelMethod virtual_pixel_method,ExceptionInfo *exception)
 
 5342    *magick_restrict cache_info;
 
 5347  assert(image != (Image *) NULL);
 
 5348  assert(image->signature == MagickCoreSignature);
 
 5349  if (IsEventLogging() != MagickFalse)
 
 5350    (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
 
 5351  assert(image->cache != (Cache) NULL);
 
 5352  cache_info=(CacheInfo *) image->cache;
 
 5353  assert(cache_info->signature == MagickCoreSignature);
 
 5354  method=cache_info->virtual_pixel_method;
 
 5355  cache_info->virtual_pixel_method=virtual_pixel_method;
 
 5356  if ((image->columns != 0) && (image->rows != 0))
 
 5357    switch (virtual_pixel_method)
 
 5359      case BackgroundVirtualPixelMethod:
 
 5361        if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
 
 5362            ((image->alpha_trait & BlendPixelTrait) == 0))
 
 5363          (void) SetCacheAlphaChannel(image,OpaqueAlpha,exception);
 
 5364        if ((IsPixelInfoGray(&image->background_color) == MagickFalse) &&
 
 5365            (IsGrayColorspace(image->colorspace) != MagickFalse))
 
 5366          (void) SetImageColorspace(image,sRGBColorspace,exception);
 
 5369      case TransparentVirtualPixelMethod:
 
 5371        if ((image->alpha_trait & BlendPixelTrait) == 0)
 
 5372          (void) SetCacheAlphaChannel(image,OpaqueAlpha,exception);
 
 5381#if defined(MAGICKCORE_OPENCL_SUPPORT) 
 5406static void CopyOpenCLBuffer(CacheInfo *magick_restrict cache_info)
 
 5408  assert(cache_info != (CacheInfo *) NULL);
 
 5409  assert(cache_info->signature == MagickCoreSignature);
 
 5410  if ((cache_info->type != MemoryCache) ||
 
 5411      (cache_info->opencl == (MagickCLCacheInfo) NULL))
 
 5416  LockSemaphoreInfo(cache_info->semaphore);
 
 5417  cache_info->opencl=CopyMagickCLCacheInfo(cache_info->opencl);
 
 5418  UnlockSemaphoreInfo(cache_info->semaphore);
 
 5421MagickPrivate 
void SyncAuthenticOpenCLBuffer(
const Image *image)
 
 5424    *magick_restrict cache_info;
 
 5426  assert(image != (
const Image *) NULL);
 
 5427  cache_info=(CacheInfo *) image->cache;
 
 5428  CopyOpenCLBuffer(cache_info);
 
 5461MagickPrivate MagickBooleanType SyncAuthenticPixelCacheNexus(Image *image,
 
 5462  NexusInfo *magick_restrict nexus_info,ExceptionInfo *exception)
 
 5465    *magick_restrict cache_info;
 
 5473  assert(image != (Image *) NULL);
 
 5474  assert(image->signature == MagickCoreSignature);
 
 5475  if (image->cache == (Cache) NULL)
 
 5476    ThrowBinaryException(CacheError,
"PixelCacheIsNotOpen",image->filename);
 
 5477  cache_info=(CacheInfo *) image->cache;
 
 5478  assert(cache_info->signature == MagickCoreSignature);
 
 5479  if (cache_info->type == UndefinedCache)
 
 5480    return(MagickFalse);
 
 5481  if (image->mask_trait != UpdatePixelTrait)
 
 5483      if (((image->channels & WriteMaskChannel) != 0) &&
 
 5484          (ClipPixelCacheNexus(image,nexus_info,exception) == MagickFalse))
 
 5485        return(MagickFalse);
 
 5486      if (((image->channels & CompositeMaskChannel) != 0) &&
 
 5487          (MaskPixelCacheNexus(image,nexus_info,exception) == MagickFalse))
 
 5488        return(MagickFalse);
 
 5490  if (nexus_info->authentic_pixel_cache != MagickFalse)
 
 5492      if (image->taint == MagickFalse)
 
 5493        image->taint=MagickTrue;
 
 5496  assert(cache_info->signature == MagickCoreSignature);
 
 5497  status=WritePixelCachePixels(cache_info,nexus_info,exception);
 
 5498  if ((cache_info->metacontent_extent != 0) &&
 
 5499      (WritePixelCacheMetacontent(cache_info,nexus_info,exception) == MagickFalse))
 
 5500    return(MagickFalse);
 
 5501  if ((status != MagickFalse) && (image->taint == MagickFalse))
 
 5502    image->taint=MagickTrue;
 
 5533static MagickBooleanType SyncAuthenticPixelsCache(Image *image,
 
 5534  ExceptionInfo *exception)
 
 5537    *magick_restrict cache_info;
 
 5540    id = GetOpenMPThreadId();
 
 5545  assert(image != (Image *) NULL);
 
 5546  assert(image->signature == MagickCoreSignature);
 
 5547  assert(image->cache != (Cache) NULL);
 
 5548  cache_info=(CacheInfo *) image->cache;
 
 5549  assert(cache_info->signature == MagickCoreSignature);
 
 5550  assert(
id < (
int) cache_info->number_threads);
 
 5551  status=SyncAuthenticPixelCacheNexus(image,cache_info->nexus_info[
id],
 
 5583MagickExport MagickBooleanType SyncAuthenticPixels(Image *image,
 
 5584  ExceptionInfo *exception)
 
 5587    *magick_restrict cache_info;
 
 5590    id = GetOpenMPThreadId();
 
 5595  assert(image != (Image *) NULL);
 
 5596  assert(image->signature == MagickCoreSignature);
 
 5597  assert(image->cache != (Cache) NULL);
 
 5598  cache_info=(CacheInfo *) image->cache;
 
 5599  assert(cache_info->signature == MagickCoreSignature);
 
 5600  if (cache_info->methods.sync_authentic_pixels_handler != (SyncAuthenticPixelsHandler) NULL)
 
 5602      status=cache_info->methods.sync_authentic_pixels_handler(image,
 
 5606  assert(
id < (
int) cache_info->number_threads);
 
 5607  status=SyncAuthenticPixelCacheNexus(image,cache_info->nexus_info[
id],
 
 5639MagickPrivate MagickBooleanType SyncImagePixelCache(Image *image,
 
 5640  ExceptionInfo *exception)
 
 5643    *magick_restrict cache_info;
 
 5645  assert(image != (Image *) NULL);
 
 5646  assert(exception != (ExceptionInfo *) NULL);
 
 5647  cache_info=(CacheInfo *) GetImagePixelCache(image,MagickTrue,exception);
 
 5648  return(cache_info == (CacheInfo *) NULL ? MagickFalse : MagickTrue);
 
 5679static MagickBooleanType WritePixelCacheMetacontent(CacheInfo *cache_info,
 
 5680  NexusInfo *magick_restrict nexus_info,ExceptionInfo *exception)
 
 5699  if (cache_info->metacontent_extent == 0)
 
 5700    return(MagickFalse);
 
 5701  if (nexus_info->authentic_pixel_cache != MagickFalse)
 
 5703  if (nexus_info->metacontent == (
unsigned char *) NULL)
 
 5704    return(MagickFalse);
 
 5705  if (IsValidPixelOffset(nexus_info->region.y,cache_info->columns) == MagickFalse)
 
 5706    return(MagickFalse);
 
 5707  offset=nexus_info->region.y*(MagickOffsetType) cache_info->columns+
 
 5708    nexus_info->region.x;
 
 5709  length=(MagickSizeType) nexus_info->region.width*
 
 5710    cache_info->metacontent_extent;
 
 5711  extent=(MagickSizeType) length*nexus_info->region.height;
 
 5712  rows=nexus_info->region.height;
 
 5714  p=(
unsigned char *) nexus_info->metacontent;
 
 5715  switch (cache_info->type)
 
 5726      if ((cache_info->columns == nexus_info->region.width) &&
 
 5727          (extent == (MagickSizeType) ((
size_t) extent)))
 
 5732      q=(
unsigned char *) cache_info->metacontent+offset*
 
 5733        (MagickOffsetType) cache_info->metacontent_extent;
 
 5734      for (y=0; y < (ssize_t) rows; y++)
 
 5736        (void) memcpy(q,p,(
size_t) length);
 
 5737        p+=(ptrdiff_t) nexus_info->region.width*cache_info->metacontent_extent;
 
 5738        q+=(ptrdiff_t) cache_info->columns*cache_info->metacontent_extent;
 
 5747      LockSemaphoreInfo(cache_info->file_semaphore);
 
 5748      if (OpenPixelCacheOnDisk(cache_info,IOMode) == MagickFalse)
 
 5750          ThrowFileException(exception,FileOpenError,
"UnableToOpenFile",
 
 5751            cache_info->cache_filename);
 
 5752          UnlockSemaphoreInfo(cache_info->file_semaphore);
 
 5753          return(MagickFalse);
 
 5755      if ((cache_info->columns == nexus_info->region.width) &&
 
 5756          (extent <= MagickMaxBufferExtent))
 
 5761      extent=(MagickSizeType) cache_info->columns*cache_info->rows;
 
 5762      for (y=0; y < (ssize_t) rows; y++)
 
 5764        count=WritePixelCacheRegion(cache_info,cache_info->offset+
 
 5765          (MagickOffsetType) extent*(MagickOffsetType)
 
 5766          cache_info->number_channels*(MagickOffsetType) 
sizeof(Quantum)+offset*
 
 5767          (MagickOffsetType) cache_info->metacontent_extent,length,
 
 5768          (
const unsigned char *) p);
 
 5769        if (count != (MagickOffsetType) length)
 
 5771        p+=(ptrdiff_t) cache_info->metacontent_extent*nexus_info->region.width;
 
 5772        offset+=(MagickOffsetType) cache_info->columns;
 
 5774      if (IsFileDescriptorLimitExceeded() != MagickFalse)
 
 5775        (void) ClosePixelCacheOnDisk(cache_info);
 
 5776      UnlockSemaphoreInfo(cache_info->file_semaphore);
 
 5779    case DistributedCache:
 
 5787      LockSemaphoreInfo(cache_info->file_semaphore);
 
 5788      region=nexus_info->region;
 
 5789      if ((cache_info->columns != nexus_info->region.width) ||
 
 5790          (extent > MagickMaxBufferExtent))
 
 5797      for (y=0; y < (ssize_t) rows; y++)
 
 5799        count=WriteDistributePixelCacheMetacontent((DistributeCacheInfo *)
 
 5800          cache_info->server_info,®ion,length,(
const unsigned char *) p);
 
 5801        if (count != (MagickOffsetType) length)
 
 5803        p+=(ptrdiff_t) cache_info->metacontent_extent*nexus_info->region.width;
 
 5806      UnlockSemaphoreInfo(cache_info->file_semaphore);
 
 5812  if (y < (ssize_t) rows)
 
 5814      ThrowFileException(exception,CacheError,
"UnableToWritePixelCache",
 
 5815        cache_info->cache_filename);
 
 5816      return(MagickFalse);
 
 5818  if ((cache_info->debug != MagickFalse) &&
 
 5819      (CacheTick(nexus_info->region.y,cache_info->rows) != MagickFalse))
 
 5820    (void) LogMagickEvent(CacheEvent,GetMagickModule(),
 
 5821      "%s[%.20gx%.20g%+.20g%+.20g]",cache_info->filename,(
double)
 
 5822      nexus_info->region.width,(
double) nexus_info->region.height,(
double)
 
 5823      nexus_info->region.x,(
double) nexus_info->region.y);
 
 5855static MagickBooleanType WritePixelCachePixels(
 
 5856  CacheInfo *magick_restrict cache_info,NexusInfo *magick_restrict nexus_info,
 
 5857  ExceptionInfo *exception)
 
 5876  if (nexus_info->authentic_pixel_cache != MagickFalse)
 
 5878  if (IsValidPixelOffset(nexus_info->region.y,cache_info->columns) == MagickFalse)
 
 5879    return(MagickFalse);
 
 5880  offset=nexus_info->region.y*(MagickOffsetType) cache_info->columns+
 
 5881    nexus_info->region.x;
 
 5882  length=(MagickSizeType) cache_info->number_channels*nexus_info->region.width*
 
 5884  extent=length*nexus_info->region.height;
 
 5885  rows=nexus_info->region.height;
 
 5887  p=nexus_info->pixels;
 
 5888  switch (cache_info->type)
 
 5899      if ((cache_info->columns == nexus_info->region.width) &&
 
 5900          (extent == (MagickSizeType) ((
size_t) extent)))
 
 5905      q=cache_info->pixels+(MagickOffsetType) cache_info->number_channels*
 
 5907      for (y=0; y < (ssize_t) rows; y++)
 
 5909        (void) memcpy(q,p,(
size_t) length);
 
 5910        p+=(ptrdiff_t) cache_info->number_channels*nexus_info->region.width;
 
 5911        q+=(ptrdiff_t) cache_info->number_channels*cache_info->columns;
 
 5920      LockSemaphoreInfo(cache_info->file_semaphore);
 
 5921      if (OpenPixelCacheOnDisk(cache_info,IOMode) == MagickFalse)
 
 5923          ThrowFileException(exception,FileOpenError,
"UnableToOpenFile",
 
 5924            cache_info->cache_filename);
 
 5925          UnlockSemaphoreInfo(cache_info->file_semaphore);
 
 5926          return(MagickFalse);
 
 5928      if ((cache_info->columns == nexus_info->region.width) &&
 
 5929          (extent <= MagickMaxBufferExtent))
 
 5934      for (y=0; y < (ssize_t) rows; y++)
 
 5936        count=WritePixelCacheRegion(cache_info,cache_info->offset+offset*
 
 5937          (MagickOffsetType) cache_info->number_channels*(MagickOffsetType)
 
 5938          sizeof(*p),length,(
const unsigned char *) p);
 
 5939        if (count != (MagickOffsetType) length)
 
 5941        p+=(ptrdiff_t) cache_info->number_channels*nexus_info->region.width;
 
 5942        offset+=(MagickOffsetType) cache_info->columns;
 
 5944      if (IsFileDescriptorLimitExceeded() != MagickFalse)
 
 5945        (void) ClosePixelCacheOnDisk(cache_info);
 
 5946      UnlockSemaphoreInfo(cache_info->file_semaphore);
 
 5949    case DistributedCache:
 
 5957      LockSemaphoreInfo(cache_info->file_semaphore);
 
 5958      region=nexus_info->region;
 
 5959      if ((cache_info->columns != nexus_info->region.width) ||
 
 5960          (extent > MagickMaxBufferExtent))
 
 5967      for (y=0; y < (ssize_t) rows; y++)
 
 5969        count=WriteDistributePixelCachePixels((DistributeCacheInfo *)
 
 5970          cache_info->server_info,®ion,length,(
const unsigned char *) p);
 
 5971        if (count != (MagickOffsetType) length)
 
 5973        p+=(ptrdiff_t) cache_info->number_channels*nexus_info->region.width;
 
 5976      UnlockSemaphoreInfo(cache_info->file_semaphore);
 
 5982  if (y < (ssize_t) rows)
 
 5984      ThrowFileException(exception,CacheError,
"UnableToWritePixelCache",
 
 5985        cache_info->cache_filename);
 
 5986      return(MagickFalse);
 
 5988  if ((cache_info->debug != MagickFalse) &&
 
 5989      (CacheTick(nexus_info->region.y,cache_info->rows) != MagickFalse))
 
 5990    (void) LogMagickEvent(CacheEvent,GetMagickModule(),
 
 5991      "%s[%.20gx%.20g%+.20g%+.20g]",cache_info->filename,(
double)
 
 5992      nexus_info->region.width,(
double) nexus_info->region.height,(
double)
 
 5993      nexus_info->region.x,(
double) nexus_info->region.y);