% MagickCore Pixel Cache Methods %
% %
% Software Design %
-% John Cristy %
+% Cristy %
% July 1999 %
% %
% %
-% Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization %
% dedicated to making software imaging solutions freely available. %
% %
% You may not use this file except in compliance with the License. You may %
quotient,
remainder;
} MagickModulo;
-
-struct _NexusInfo
-{
- MagickBooleanType
- mapped;
-
- RectangleInfo
- region;
-
- MagickSizeType
- length;
-
- Quantum
- *cache,
- *pixels;
-
- void
- *metacontent;
-
- size_t
- signature;
-};
\f
/*
Forward declarations.
const size_t,ExceptionInfo *),
*QueueAuthenticPixelsCache(Image *,const ssize_t,const ssize_t,const size_t,
const size_t,ExceptionInfo *),
- *SetPixelCacheNexusPixels(const Image *,const MapMode,const RectangleInfo *,
- NexusInfo *,ExceptionInfo *) magick_hot_spot;
+ *SetPixelCacheNexusPixels(const CacheInfo *,const MapMode,
+ const RectangleInfo *,NexusInfo *,ExceptionInfo *) magick_hot_spot;
#if defined(__cplusplus) || defined(c_plusplus)
}
MagickPrivate Cache AcquirePixelCache(const size_t number_threads)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
char
*synchronize;
cache_info->synchronize=IsStringTrue(synchronize);
synchronize=DestroyString(synchronize);
}
- cache_info->semaphore=AllocateSemaphoreInfo();
+ cache_info->semaphore=AcquireSemaphoreInfo();
cache_info->reference_count=1;
- cache_info->file_semaphore=AllocateSemaphoreInfo();
+ cache_info->file_semaphore=AcquireSemaphoreInfo();
cache_info->debug=IsEventLogging();
cache_info->signature=MagickSignature;
return((Cache ) cache_info);
MagickPrivate NexusInfo **AcquirePixelCacheNexus(const size_t number_threads)
{
NexusInfo
- **nexus_info;
+ **restrict nexus_info;
register ssize_t
i;
MagickSizeType *length,ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
*/
MagickPrivate MagickBooleanType CacheComponentGenesis(void)
{
- AcquireSemaphoreInfo(&cache_semaphore);
+ if (cache_semaphore == (SemaphoreInfo *) NULL)
+ cache_semaphore=AcquireSemaphoreInfo();
return(MagickTrue);
}
\f
MagickPrivate void CacheComponentTerminus(void)
{
if (cache_semaphore == (SemaphoreInfo *) NULL)
- AcquireSemaphoreInfo(&cache_semaphore);
+ ActivateSemaphoreInfo(&cache_semaphore);
LockSemaphoreInfo(cache_semaphore);
instantiate_cache=MagickFalse;
UnlockSemaphoreInfo(cache_semaphore);
- DestroySemaphoreInfo(&cache_semaphore);
+ RelinquishSemaphoreInfo(&cache_semaphore);
}
\f
/*
MagickPrivate Cache ClonePixelCache(const Cache cache)
{
CacheInfo
- *clone_info;
+ *restrict clone_info;
const CacheInfo
- *cache_info;
+ *restrict cache_info;
assert(cache != NULL);
cache_info=(const CacheInfo *) cache;
% %
% %
% %
-+ C l o n e P i x e l C a c h e P i x e l s %
++ C l o n e P i x e l C a c h e M e t h o d s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ClonePixelCacheMethods() clones the pixel cache methods from one cache to
+% another.
+%
+% The format of the ClonePixelCacheMethods() method is:
+%
+% void ClonePixelCacheMethods(Cache clone,const Cache cache)
+%
+% A description of each parameter follows:
+%
+% o clone: Specifies a pointer to a Cache structure.
+%
+% o cache: the pixel cache.
+%
+*/
+MagickPrivate void ClonePixelCacheMethods(Cache clone,const Cache cache)
+{
+ CacheInfo
+ *restrict cache_info,
+ *restrict source_info;
+
+ assert(clone != (Cache) NULL);
+ source_info=(CacheInfo *) clone;
+ assert(source_info->signature == MagickSignature);
+ if (source_info->debug != MagickFalse)
+ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
+ source_info->filename);
+ assert(cache != (Cache) NULL);
+ cache_info=(CacheInfo *) cache;
+ assert(cache_info->signature == MagickSignature);
+ source_info->methods=cache_info->methods;
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C l o n e P i x e l C a c h e R e p o s i t o r y %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %
-% ClonePixelCachePixels() clones the source pixel cache to the destination
+% ClonePixelCacheRepository() clones the source pixel cache to the destination
% cache.
%
-% The format of the ClonePixelCachePixels() method is:
+% The format of the ClonePixelCacheRepository() method is:
%
-% MagickBooleanType ClonePixelCachePixels(CacheInfo *cache_info,
+% MagickBooleanType ClonePixelCacheRepository(CacheInfo *cache_info,
% CacheInfo *source_info,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
*/
-static MagickBooleanType ClosePixelCacheOnDisk(CacheInfo *cache_info)
+static inline void CopyPixels(Quantum *destination,const Quantum *source,
+ const MagickSizeType number_pixels)
{
- int
- status;
-
- status=(-1);
- if (cache_info->file != -1)
- {
- status=close(cache_info->file);
- cache_info->file=(-1);
- RelinquishMagickResource(FileResource,1);
- }
- return(status == -1 ? MagickFalse : MagickTrue);
-}
+#if !defined(MAGICKCORE_OPENMP_SUPPORT) || (MAGICKCORE_QUANTUM_DEPTH <= 8)
+ (void) memcpy(destination,source,(size_t) number_pixels*sizeof(*source));
+#else
+ {
+ register MagickOffsetType
+ i;
-static inline MagickSizeType MagickMax(const MagickSizeType x,
- const MagickSizeType y)
-{
- if (x > y)
- return(x);
- return(y);
+ if ((number_pixels*sizeof(*source)) < MagickMaxBufferExtent)
+ {
+ (void) memcpy(destination,source,(size_t) number_pixels*
+ sizeof(*source));
+ return;
+ }
+ #pragma omp parallel for
+ for (i=0; i < (MagickOffsetType) number_pixels; i++)
+ destination[i]=source[i];
+ }
+#endif
}
static inline MagickSizeType MagickMin(const MagickSizeType x,
return(y);
}
-static MagickBooleanType OpenPixelCacheOnDisk(CacheInfo *cache_info,
- const MapMode mode)
-{
- int
- file;
-
- /*
- Open pixel cache on disk.
- */
- if (cache_info->file != -1)
- return(MagickTrue); /* cache already open */
- if (*cache_info->cache_filename == '\0')
- file=AcquireUniqueFileResource(cache_info->cache_filename);
- else
- switch (mode)
- {
- case ReadMode:
- {
- file=open_utf8(cache_info->cache_filename,O_RDONLY | O_BINARY,0);
- break;
- }
- case WriteMode:
- {
- file=open_utf8(cache_info->cache_filename,O_WRONLY | O_CREAT |
- O_BINARY | O_EXCL,S_MODE);
- if (file == -1)
- file=open_utf8(cache_info->cache_filename,O_WRONLY | O_BINARY,S_MODE);
- break;
- }
- case IOMode:
- default:
- {
- file=open_utf8(cache_info->cache_filename,O_RDWR | O_CREAT | O_BINARY |
- O_EXCL,S_MODE);
- if (file == -1)
- file=open_utf8(cache_info->cache_filename,O_RDWR | O_BINARY,S_MODE);
- break;
- }
- }
- if (file == -1)
- return(MagickFalse);
- (void) AcquireMagickResource(FileResource,1);
- cache_info->file=file;
- cache_info->mode=mode;
- return(MagickTrue);
-}
-
-static inline MagickOffsetType ReadPixelCacheRegion(
- const CacheInfo *restrict cache_info,const MagickOffsetType offset,
- const MagickSizeType length,unsigned char *restrict buffer)
-{
- register MagickOffsetType
- i;
-
- ssize_t
- count;
-
-#if !defined(MAGICKCORE_HAVE_PREAD)
- if (lseek(cache_info->file,offset,SEEK_SET) < 0)
- return((MagickOffsetType) -1);
-#endif
- count=0;
- for (i=0; i < (MagickOffsetType) length; i+=count)
- {
-#if !defined(MAGICKCORE_HAVE_PREAD)
- count=read(cache_info->file,buffer+i,(size_t) MagickMin(length-i,
- (MagickSizeType) SSIZE_MAX));
-#else
- count=pread(cache_info->file,buffer+i,(size_t) MagickMin(length-i,
- (MagickSizeType) SSIZE_MAX),(off_t) (offset+i));
-#endif
- if (count <= 0)
- {
- count=0;
- if (errno != EINTR)
- break;
- }
- }
- return(i);
-}
-
-static inline MagickOffsetType WritePixelCacheRegion(
- const CacheInfo *restrict cache_info,const MagickOffsetType offset,
- const MagickSizeType length,const unsigned char *restrict buffer)
-{
- register MagickOffsetType
- i;
-
- ssize_t
- count;
-
-#if !defined(MAGICKCORE_HAVE_PWRITE)
- if (lseek(cache_info->file,offset,SEEK_SET) < 0)
- return((MagickOffsetType) -1);
-#endif
- count=0;
- for (i=0; i < (MagickOffsetType) length; i+=count)
- {
-#if !defined(MAGICKCORE_HAVE_PWRITE)
- count=write(cache_info->file,buffer+i,(size_t) MagickMin(length-i,
- (MagickSizeType) SSIZE_MAX));
-#else
- count=pwrite(cache_info->file,buffer+i,(size_t) MagickMin(length-i,
- (MagickSizeType) SSIZE_MAX),(off_t) (offset+i));
-#endif
- if (count <= 0)
- {
- count=0;
- if (errno != EINTR)
- break;
- }
- }
- return(i);
-}
-
-static MagickBooleanType DiskToDiskPixelCacheClone(CacheInfo *clone_info,
- CacheInfo *cache_info,ExceptionInfo *exception)
-{
- MagickOffsetType
- count;
-
- register MagickOffsetType
- i;
-
- size_t
- length;
-
- unsigned char
- *blob;
-
- /*
- Clone pixel cache (both caches on disk).
- */
- blob=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
- sizeof(*blob));
- if (blob == (unsigned char *) NULL)
- {
- (void) ThrowMagickException(exception,GetMagickModule(),
- ResourceLimitError,"MemoryAllocationFailed","`%s'",
- cache_info->filename);
- return(MagickFalse);
- }
- if (OpenPixelCacheOnDisk(cache_info,ReadMode) == MagickFalse)
- {
- blob=(unsigned char *) RelinquishMagickMemory(blob);
- ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
- cache_info->cache_filename);
- return(MagickFalse);
- }
- if (OpenPixelCacheOnDisk(clone_info,WriteMode) == MagickFalse)
- {
- (void) ClosePixelCacheOnDisk(cache_info);
- blob=(unsigned char *) RelinquishMagickMemory(blob);
- ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
- clone_info->cache_filename);
- return(MagickFalse);
- }
- count=0;
- for (i=0; i < (MagickOffsetType) cache_info->length; i+=count)
- {
- count=ReadPixelCacheRegion(cache_info,cache_info->offset+i,
- MagickMin(cache_info->length-i,(MagickSizeType) MagickMaxBufferExtent),
- blob);
- if (count <= 0)
- {
- ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
- cache_info->cache_filename);
- break;
- }
- length=(size_t) count;
- count=WritePixelCacheRegion(clone_info,clone_info->offset+i,length,blob);
- if ((MagickSizeType) count != length)
- {
- ThrowFileException(exception,CacheError,"UnableToWritePixelCache",
- clone_info->cache_filename);
- break;
- }
- }
- (void) ClosePixelCacheOnDisk(clone_info);
- (void) ClosePixelCacheOnDisk(cache_info);
- blob=(unsigned char *) RelinquishMagickMemory(blob);
- if (i < (MagickOffsetType) cache_info->length)
- return(MagickFalse);
- return(MagickTrue);
-}
-
-static MagickBooleanType PixelCacheCloneOptimized(CacheInfo *clone_info,
- CacheInfo *cache_info,ExceptionInfo *exception)
+static MagickBooleanType ClonePixelCacheRepository(
+ CacheInfo *restrict clone_info,CacheInfo *restrict cache_info,
+ ExceptionInfo *exception)
{
- MagickOffsetType
- count;
+#define MaxCacheThreads 2
+#define cache_threads(source,destination,chunk) \
+ num_threads((chunk) < (16*GetMagickResourceLimit(ThreadResource)) ? 1 : \
+ GetMagickResourceLimit(ThreadResource) < MaxCacheThreads ? \
+ GetMagickResourceLimit(ThreadResource) : MaxCacheThreads)
- if ((cache_info->type != DiskCache) && (clone_info->type != DiskCache))
- {
- /*
- Clone pixel cache (both caches in memory).
- */
- (void) memcpy(clone_info->pixels,cache_info->pixels,(size_t)
- cache_info->length);
- return(MagickTrue);
- }
- if ((clone_info->type != DiskCache) && (cache_info->type == DiskCache))
- {
- /*
- Clone pixel cache (one cache on disk, one in memory).
- */
- if (OpenPixelCacheOnDisk(cache_info,ReadMode) == MagickFalse)
- {
- ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
- cache_info->cache_filename);
- return(MagickFalse);
- }
- count=ReadPixelCacheRegion(cache_info,cache_info->offset,
- cache_info->length,(unsigned char *) clone_info->pixels);
- (void) ClosePixelCacheOnDisk(cache_info);
- if ((MagickSizeType) count != cache_info->length)
- {
- ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
- cache_info->cache_filename);
- return(MagickFalse);
- }
- return(MagickTrue);
- }
- if ((clone_info->type == DiskCache) && (cache_info->type != DiskCache))
- {
- /*
- Clone pixel cache (one cache on disk, one in memory).
- */
- if (OpenPixelCacheOnDisk(clone_info,WriteMode) == MagickFalse)
- {
- ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
- clone_info->cache_filename);
- return(MagickFalse);
- }
- count=WritePixelCacheRegion(clone_info,clone_info->offset,
- clone_info->length,(unsigned char *) cache_info->pixels);
- (void) ClosePixelCacheOnDisk(clone_info);
- if ((MagickSizeType) count != clone_info->length)
- {
- ThrowFileException(exception,CacheError,"UnableToWritePixelCache",
- clone_info->cache_filename);
- return(MagickFalse);
- }
- return(MagickTrue);
- }
- /*
- Clone pixel cache (both caches on disk).
- */
- return(DiskToDiskPixelCacheClone(clone_info,cache_info,exception));
-}
-
-static MagickBooleanType PixelCacheCloneUnoptimized(CacheInfo *clone_info,
- CacheInfo *cache_info,ExceptionInfo *exception)
-{
MagickBooleanType
+ optimize,
status;
- MagickOffsetType
- cache_offset,
- clone_offset,
- count;
-
- register ssize_t
- x;
-
- register unsigned char
- *p;
+ NexusInfo
+ **restrict cache_nexus,
+ **restrict clone_nexus;
size_t
length;
ssize_t
y;
- unsigned char
- *blob;
-
- /*
- Clone pixel cache (unoptimized).
- */
- length=(size_t) MagickMax(MagickMax(cache_info->number_channels,
- clone_info->number_channels)*sizeof(Quantum),MagickMax(
- cache_info->metacontent_extent,clone_info->metacontent_extent));
- blob=(unsigned char *) AcquireQuantumMemory(length,sizeof(*blob));
- if (blob == (unsigned char *) NULL)
- {
- (void) ThrowMagickException(exception,GetMagickModule(),
- ResourceLimitError,"MemoryAllocationFailed","`%s'",
- cache_info->filename);
- return(MagickFalse);
- }
- (void) ResetMagickMemory(blob,0,length*sizeof(*blob));
- cache_offset=0;
- clone_offset=0;
- if (cache_info->type == DiskCache)
- {
- if (OpenPixelCacheOnDisk(cache_info,ReadMode) == MagickFalse)
- {
- blob=(unsigned char *) RelinquishMagickMemory(blob);
- ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
- cache_info->cache_filename);
- return(MagickFalse);
- }
- cache_offset=cache_info->offset;
- }
- if (clone_info->type == DiskCache)
+ assert(cache_info != (CacheInfo *) NULL);
+ assert(clone_info != (CacheInfo *) NULL);
+ assert(exception != (ExceptionInfo *) NULL);
+ if (cache_info->type == PingCache)
+ return(MagickTrue);
+ length=cache_info->number_channels*sizeof(*cache_info->channel_map);
+ if (((cache_info->type == MemoryCache) || (cache_info->type == MapCache)) &&
+ ((clone_info->type == MemoryCache) || (clone_info->type == MapCache)) &&
+ (cache_info->columns == clone_info->columns) &&
+ (cache_info->rows == clone_info->rows) &&
+ (cache_info->number_channels == clone_info->number_channels) &&
+ (memcmp(cache_info->channel_map,clone_info->channel_map,length) == 0) &&
+ (cache_info->metacontent_extent == clone_info->metacontent_extent))
{
- if (OpenPixelCacheOnDisk(clone_info,WriteMode) == MagickFalse)
- {
- blob=(unsigned char *) RelinquishMagickMemory(blob);
- ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
- clone_info->cache_filename);
- return(MagickFalse);
- }
- clone_offset=clone_info->offset;
+ CopyPixels(clone_info->pixels,cache_info->pixels,cache_info->columns*
+ cache_info->number_channels*cache_info->rows);
+ if (cache_info->metacontent_extent != 0)
+ (void) memcpy(clone_info->metacontent,cache_info->metacontent,
+ cache_info->columns*cache_info->rows*clone_info->metacontent_extent*
+ sizeof(cache_info->metacontent));
+ return(MagickTrue);
}
/*
- Clone pixel channels.
+ Mismatched pixel cache morphology.
*/
+ cache_nexus=AcquirePixelCacheNexus(MaxCacheThreads);
+ clone_nexus=AcquirePixelCacheNexus(MaxCacheThreads);
+ if ((cache_nexus == (NexusInfo **) NULL) ||
+ (clone_nexus == (NexusInfo **) NULL))
+ ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
+ length=cache_info->number_channels*sizeof(*cache_info->channel_map);
+ optimize=(cache_info->number_channels == clone_info->number_channels) &&
+ (memcmp(cache_info->channel_map,clone_info->channel_map,length) == 0) ?
+ MagickTrue : MagickFalse;
+ length=(size_t) MagickMin(cache_info->columns*cache_info->number_channels,
+ clone_info->columns*clone_info->number_channels);
status=MagickTrue;
- p=blob;
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+ #pragma omp parallel for schedule(static,4) shared(status) \
+ cache_threads(cache_info,clone_info,cache_info->rows)
+#endif
for (y=0; y < (ssize_t) cache_info->rows; y++)
{
- for (x=0; x < (ssize_t) cache_info->columns; x++)
- {
- register ssize_t
- i;
+ const int
+ id = GetOpenMPThreadId();
- /*
- Read a set of pixel channels.
- */
- length=cache_info->number_channels*sizeof(Quantum);
- if (cache_info->type != DiskCache)
- p=(unsigned char *) cache_info->pixels+cache_offset;
- else
- {
- count=ReadPixelCacheRegion(cache_info,cache_offset,length,p);
- if ((MagickSizeType) count != length)
- {
- status=MagickFalse;
- break;
- }
- }
- cache_offset+=length;
- if ((y < (ssize_t) clone_info->rows) &&
- (x < (ssize_t) clone_info->columns))
- for (i=0; i < (ssize_t) clone_info->number_channels; i++)
- {
- PixelChannel
- channel;
+ Quantum
+ *pixels;
- PixelTrait
- traits;
+ RectangleInfo
+ region;
- ssize_t
- offset;
+ register ssize_t
+ x;
- /*
- Write a set of pixel channels.
- */
- channel=clone_info->channel_map[i].channel;
- traits=cache_info->channel_map[channel].traits;
- if (traits == UndefinedPixelTrait)
- {
- clone_offset+=sizeof(Quantum);
- continue;
- }
- offset=cache_info->channel_map[channel].offset;
- if ((clone_info->type == MemoryCache) ||
- (clone_info->type == MapCache))
- (void) memcpy((unsigned char *) clone_info->pixels+clone_offset,p+
- offset*sizeof(Quantum),sizeof(Quantum));
- else
- {
- count=WritePixelCacheRegion(clone_info,clone_offset,
- sizeof(Quantum),p+offset*sizeof(Quantum));
- if ((MagickSizeType) count != sizeof(Quantum))
- {
- status=MagickFalse;
- break;
- }
- }
- clone_offset+=sizeof(Quantum);
- }
- }
- if (y < (ssize_t) clone_info->rows)
+ if (status == MagickFalse)
+ continue;
+ if (y >= (ssize_t) clone_info->rows)
+ continue;
+ region.width=cache_info->columns;
+ region.height=1;
+ region.x=0;
+ region.y=y;
+ pixels=SetPixelCacheNexusPixels(cache_info,ReadMode,®ion,cache_nexus[id],
+ exception);
+ if (pixels == (Quantum *) NULL)
+ continue;
+ status=ReadPixelCachePixels(cache_info,cache_nexus[id],exception);
+ if (status == MagickFalse)
+ continue;
+ region.width=clone_info->columns;
+ pixels=SetPixelCacheNexusPixels(clone_info,WriteMode,®ion,
+ clone_nexus[id],exception);
+ if (pixels == (Quantum *) NULL)
+ continue;
+ (void) ResetMagickMemory(clone_nexus[id]->pixels,0,clone_nexus[id]->length);
+ if (optimize != MagickFalse)
+ (void) memcpy(clone_nexus[id]->pixels,cache_nexus[id]->pixels,length*
+ sizeof(Quantum));
+ else
{
+ register const Quantum
+ *restrict p;
+
+ register Quantum
+ *restrict q;
+
/*
- Set remaining columns as undefined.
+ Mismatched pixel channel map.
*/
- length=clone_info->number_channels*sizeof(Quantum);
- (void) ResetMagickMemory(blob,0,length*sizeof(*blob));
- for ( ; x < (ssize_t) clone_info->columns; x++)
+ p=cache_nexus[id]->pixels;
+ q=clone_nexus[id]->pixels;
+ for (x=0; x < (ssize_t) cache_info->columns; x++)
{
- if ((clone_info->type == MemoryCache) ||
- (clone_info->type == MapCache))
- (void) memcpy((unsigned char *) clone_info->pixels+clone_offset,
- blob,length);
- else
- {
- count=WritePixelCacheRegion(clone_info,clone_offset,length,blob);
- if ((MagickSizeType) count != length)
- {
- status=MagickFalse;
- break;
- }
- }
- clone_offset+=length;
+ register ssize_t
+ i;
+
+ if (x == (ssize_t) clone_info->columns)
+ break;
+ for (i=0; i < (ssize_t) clone_info->number_channels; i++)
+ {
+ PixelChannel
+ channel;
+
+ PixelTrait
+ traits;
+
+ channel=clone_info->channel_map[i].channel;
+ traits=cache_info->channel_map[channel].traits;
+ if (traits != UndefinedPixelTrait)
+ (void) memcpy(q,p+cache_info->channel_map[channel].offset,
+ sizeof(Quantum));
+ q++;
+ }
+ p+=cache_info->number_channels;
}
}
+ status=WritePixelCachePixels(clone_info,clone_nexus[id],exception);
}
- length=clone_info->number_channels*sizeof(Quantum);
- (void) ResetMagickMemory(blob,0,length*sizeof(*blob));
- for ( ; y < (ssize_t) clone_info->rows; y++)
- {
- /*
- Set remaining rows as undefined.
- */
- for (x=0; x < (ssize_t) clone_info->columns; x++)
- {
- if (clone_info->type != DiskCache)
- (void) memcpy((unsigned char *) clone_info->pixels+clone_offset,blob,
- length);
- else
- {
- count=WritePixelCacheRegion(clone_info,clone_offset,length,blob);
- if ((MagickSizeType) count != length)
- {
- status=MagickFalse;
- break;
- }
- }
- clone_offset+=length;
- }
- }
- if ((cache_info->metacontent_extent != 0) ||
+ if ((cache_info->metacontent_extent != 0) &&
(clone_info->metacontent_extent != 0))
{
/*
Clone metacontent.
*/
+ length=(size_t) MagickMin(cache_info->metacontent_extent,
+ clone_info->metacontent_extent);
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+ #pragma omp parallel for schedule(static,4) shared(status) \
+ cache_threads(cache_info,clone_info,cache_info->rows)
+#endif
for (y=0; y < (ssize_t) cache_info->rows; y++)
{
- for (x=0; x < (ssize_t) cache_info->columns; x++)
- {
- /*
- Read a set of metacontent.
- */
- length=cache_info->metacontent_extent;
- if (cache_info->type != DiskCache)
- p=(unsigned char *) cache_info->pixels+cache_offset;
- else
- {
- count=ReadPixelCacheRegion(cache_info,cache_offset,length,p);
- if ((MagickSizeType) count != length)
- {
- status=MagickFalse;
- break;
- }
- }
- cache_offset+=length;
- if ((y < (ssize_t) clone_info->rows) &&
- (x < (ssize_t) clone_info->columns))
- {
- /*
- Write a set of metacontent.
- */
- length=clone_info->metacontent_extent;
- if ((clone_info->type == MemoryCache) ||
- (clone_info->type == MapCache))
- (void) memcpy((unsigned char *) clone_info->pixels+clone_offset,
- p,length);
- else
- {
- count=WritePixelCacheRegion(clone_info,clone_offset,length,p);
- if ((MagickSizeType) count != length)
- {
- status=MagickFalse;
- break;
- }
- }
- clone_offset+=length;
- }
- }
- length=clone_info->metacontent_extent;
- (void) ResetMagickMemory(blob,0,length*sizeof(*blob));
- for ( ; x < (ssize_t) clone_info->columns; x++)
- {
- /*
- Set remaining columns as undefined.
- */
- if ((clone_info->type == MemoryCache) ||
- (clone_info->type == MapCache))
- (void) memcpy((unsigned char *) clone_info->pixels+clone_offset,
- blob,length);
- else
- {
- count=WritePixelCacheRegion(clone_info,clone_offset,length,blob);
- if ((MagickSizeType) count != length)
- {
- status=MagickFalse;
- break;
- }
- }
- clone_offset+=length;
- }
- }
- if (y < (ssize_t) clone_info->rows)
- {
- /*
- Set remaining rows as undefined.
- */
- length=clone_info->metacontent_extent;
- (void) ResetMagickMemory(blob,0,length*sizeof(*blob));
- for ( ; y < (ssize_t) clone_info->rows; y++)
- {
- for (x=0; x < (ssize_t) clone_info->columns; x++)
- {
- if ((clone_info->type == MemoryCache) ||
- (clone_info->type == MapCache))
- (void) memcpy((unsigned char *) clone_info->pixels+clone_offset,
- blob,length);
- else
- {
- count=WritePixelCacheRegion(clone_info,clone_offset,length,
- blob);
- if ((MagickSizeType) count != length)
- {
- status=MagickFalse;
- break;
- }
- }
- clone_offset+=length;
- }
- }
- }
- }
- if (clone_info->type == DiskCache)
- (void) ClosePixelCacheOnDisk(clone_info);
- if (cache_info->type == DiskCache)
- (void) ClosePixelCacheOnDisk(cache_info);
- blob=(unsigned char *) RelinquishMagickMemory(blob);
- return(status);
-}
+ const int
+ id = GetOpenMPThreadId();
-static MagickBooleanType ClonePixelCachePixels(CacheInfo *clone_info,
- CacheInfo *cache_info,ExceptionInfo *exception)
-{
- PixelChannelMap
- *p,
- *q;
+ Quantum
+ *pixels;
+
+ RectangleInfo
+ region;
+ if (status == MagickFalse)
+ continue;
+ if (y >= (ssize_t) clone_info->rows)
+ continue;
+ region.width=cache_info->columns;
+ region.height=1;
+ region.x=0;
+ region.y=y;
+ pixels=SetPixelCacheNexusPixels(cache_info,ReadMode,®ion,
+ cache_nexus[id],exception);
+ if (pixels == (Quantum *) NULL)
+ continue;
+ status=ReadPixelCacheMetacontent(cache_info,cache_nexus[id],exception);
+ if (status == MagickFalse)
+ continue;
+ region.width=clone_info->columns;
+ pixels=SetPixelCacheNexusPixels(clone_info,WriteMode,®ion,
+ clone_nexus[id],exception);
+ if (pixels == (Quantum *) NULL)
+ continue;
+ if (clone_nexus[id]->metacontent != (void *) NULL)
+ (void) memcpy(clone_nexus[id]->metacontent,
+ cache_nexus[id]->metacontent,length*
+ sizeof(cache_nexus[id]->metacontent));
+ status=WritePixelCacheMetacontent(clone_info,clone_nexus[id],exception);
+ }
+ }
+ cache_nexus=DestroyPixelCacheNexus(cache_nexus,MaxCacheThreads);
+ clone_nexus=DestroyPixelCacheNexus(clone_nexus,MaxCacheThreads);
if (cache_info->debug != MagickFalse)
{
char
(void) FormatLocaleString(message,MaxTextExtent,"%s => %s",
CommandOptionToMnemonic(MagickCacheOptions,(ssize_t) cache_info->type),
CommandOptionToMnemonic(MagickCacheOptions,(ssize_t) clone_info->type));
- (void) LogMagickEvent(CacheEvent,GetMagickModule(),message);
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),"%s",message);
}
- if (cache_info->type == PingCache)
- return(MagickTrue);
- if (cache_info->type == DistributedCache)
- return(PixelCacheCloneUnoptimized(clone_info,cache_info,exception));
- p=cache_info->channel_map;
- q=clone_info->channel_map;
- if ((cache_info->columns == clone_info->columns) &&
- (cache_info->rows == clone_info->rows) &&
- (cache_info->number_channels == clone_info->number_channels) &&
- (memcmp(p,q,cache_info->number_channels*sizeof(*p)) == 0) &&
- (cache_info->metacontent_extent == clone_info->metacontent_extent))
- return(PixelCacheCloneOptimized(clone_info,cache_info,exception));
- return(PixelCacheCloneUnoptimized(clone_info,cache_info,exception));
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% %
-% %
-% %
-+ C l o n e P i x e l C a c h e M e t h o d s %
-% %
-% %
-% %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% ClonePixelCacheMethods() clones the pixel cache methods from one cache to
-% another.
-%
-% The format of the ClonePixelCacheMethods() method is:
-%
-% void ClonePixelCacheMethods(Cache clone,const Cache cache)
-%
-% A description of each parameter follows:
-%
-% o clone: Specifies a pointer to a Cache structure.
-%
-% o cache: the pixel cache.
-%
-*/
-MagickPrivate void ClonePixelCacheMethods(Cache clone,const Cache cache)
-{
- CacheInfo
- *cache_info,
- *source_info;
-
- assert(clone != (Cache) NULL);
- source_info=(CacheInfo *) clone;
- assert(source_info->signature == MagickSignature);
- if (source_info->debug != MagickFalse)
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
- source_info->filename);
- assert(cache != (Cache) NULL);
- cache_info=(CacheInfo *) cache;
- assert(cache_info->signature == MagickSignature);
- source_info->methods=cache_info->methods;
+ return(status);
}
\f
/*
MagickExport void DestroyImagePixels(Image *image)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
%
*/
+static MagickBooleanType ClosePixelCacheOnDisk(CacheInfo *cache_info)
+{
+ int
+ status;
+
+ status=(-1);
+ if (cache_info->file != -1)
+ {
+ status=close(cache_info->file);
+ cache_info->file=(-1);
+ RelinquishMagickResource(FileResource,1);
+ }
+ return(status == -1 ? MagickFalse : MagickTrue);
+}
+
static inline void RelinquishPixelCachePixels(CacheInfo *cache_info)
{
switch (cache_info->type)
cache_info->pixels=(Quantum *) RelinquishAlignedMemory(
cache_info->pixels);
else
- cache_info->pixels=(Quantum *) UnmapBlob(cache_info->pixels,
- (size_t) cache_info->length);
+ {
+ (void) UnmapBlob(cache_info->pixels,(size_t) cache_info->length);
+ cache_info->pixels=(Quantum *) NULL;
+ }
RelinquishMagickResource(MemoryResource,cache_info->length);
break;
}
case MapCache:
{
- cache_info->pixels=(Quantum *) UnmapBlob(cache_info->pixels,(size_t)
- cache_info->length);
+ (void) UnmapBlob(cache_info->pixels,(size_t) cache_info->length);
+ cache_info->pixels=(Quantum *) NULL;
if (cache_info->mode != ReadMode)
(void) RelinquishUniqueFileResource(cache_info->cache_filename);
*cache_info->cache_filename='\0';
}
case DistributedCache:
{
- (void) RelinquishDistributePixelCache(cache_info->distribute_cache_info);
+ *cache_info->cache_filename='\0';
+ (void) RelinquishDistributePixelCache((DistributeCacheInfo *)
+ cache_info->server_info);
break;
}
default:
MagickPrivate Cache DestroyPixelCache(Cache cache)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
assert(cache != (Cache) NULL);
cache_info=(CacheInfo *) cache;
(void) LogMagickEvent(CacheEvent,GetMagickModule(),"%s",message);
}
RelinquishPixelCachePixels(cache_info);
- if (cache_info->distribute_cache_info != (DistributeCacheInfo *) NULL)
- cache_info->distribute_cache_info=DestroyDistributeCacheInfo(
- cache_info->distribute_cache_info);
+ if (cache_info->server_info != (DistributeCacheInfo *) NULL)
+ cache_info->server_info=DestroyDistributeCacheInfo((DistributeCacheInfo *)
+ cache_info->server_info);
if (cache_info->nexus_info != (NexusInfo **) NULL)
cache_info->nexus_info=DestroyPixelCacheNexus(cache_info->nexus_info,
cache_info->number_threads);
if (cache_info->random_info != (RandomInfo *) NULL)
cache_info->random_info=DestroyRandomInfo(cache_info->random_info);
if (cache_info->file_semaphore != (SemaphoreInfo *) NULL)
- DestroySemaphoreInfo(&cache_info->file_semaphore);
+ RelinquishSemaphoreInfo(&cache_info->file_semaphore);
if (cache_info->semaphore != (SemaphoreInfo *) NULL)
- DestroySemaphoreInfo(&cache_info->semaphore);
+ RelinquishSemaphoreInfo(&cache_info->semaphore);
cache_info->signature=(~MagickSignature);
cache_info=(CacheInfo *) RelinquishMagickMemory(cache_info);
cache=(Cache) NULL;
MagickExport void *GetAuthenticMetacontent(const Image *image)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
- void
- *metacontent;
-
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
assert(image->cache != (Cache) NULL);
if (cache_info->methods.get_authentic_metacontent_from_handler !=
(GetAuthenticMetacontentFromHandler) NULL)
{
+ void
+ *metacontent;
+
metacontent=cache_info->methods.
get_authentic_metacontent_from_handler(image);
return(metacontent);
}
- assert(id < (int) cache_info->number_threads);
- metacontent=GetPixelCacheNexusMetacontent(cache_info,
- cache_info->nexus_info[id]);
- return(metacontent);
+ assert(id < (int) cache_info->number_threads);
+ return(cache_info->nexus_info[id]->metacontent);
}
\f
/*
static void *GetAuthenticMetacontentFromCache(const Image *image)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
- void
- *metacontent;
-
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
assert(image->cache != (Cache) NULL);
cache_info=(CacheInfo *) image->cache;
assert(cache_info->signature == MagickSignature);
assert(id < (int) cache_info->number_threads);
- metacontent=GetPixelCacheNexusMetacontent(image->cache,
- cache_info->nexus_info[id]);
- return(metacontent);
+ return(cache_info->nexus_info[id]->metacontent);
}
\f
/*
%
*/
-static inline MagickBooleanType IsPixelAuthentic(
- const CacheInfo *restrict cache_info,const NexusInfo *restrict nexus_info)
-{
- MagickBooleanType
- status;
-
- MagickOffsetType
- offset;
-
- if (cache_info->type == PingCache)
- return(MagickTrue);
- offset=(MagickOffsetType) nexus_info->region.y*cache_info->columns+
- nexus_info->region.x;
- status=nexus_info->pixels == (cache_info->pixels+offset*
- cache_info->number_channels) ? MagickTrue : MagickFalse;
- return(status);
-}
-
-MagickPrivate Quantum *GetAuthenticPixelCacheNexus(Image *image,
- const ssize_t x,const ssize_t y,const size_t columns,const size_t rows,
- NexusInfo *nexus_info,ExceptionInfo *exception)
+MagickPrivate Quantum *GetAuthenticPixelCacheNexus(Image *image,const ssize_t x,
+ const ssize_t y,const size_t columns,const size_t rows,NexusInfo *nexus_info,
+ ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
Quantum
- *q;
+ *restrict pixels;
/*
Transfer pixels from the cache.
*/
assert(image != (Image *) NULL);
assert(image->signature == MagickSignature);
- q=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickTrue,nexus_info,
- exception);
- if (q == (Quantum *) NULL)
+ pixels=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickTrue,
+ nexus_info,exception);
+ if (pixels == (Quantum *) NULL)
return((Quantum *) NULL);
cache_info=(CacheInfo *) image->cache;
assert(cache_info->signature == MagickSignature);
- if (IsPixelAuthentic(cache_info,nexus_info) != MagickFalse)
- return(q);
+ if (nexus_info->authentic_pixel_cache != MagickFalse)
+ return(pixels);
if (ReadPixelCachePixels(cache_info,nexus_info,exception) == MagickFalse)
return((Quantum *) NULL);
if (cache_info->metacontent_extent != 0)
if (ReadPixelCacheMetacontent(cache_info,nexus_info,exception) == MagickFalse)
return((Quantum *) NULL);
- return(q);
+ return(pixels);
}
\f
/*
static Quantum *GetAuthenticPixelsFromCache(const Image *image)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
cache_info=(CacheInfo *) image->cache;
assert(cache_info->signature == MagickSignature);
assert(id < (int) cache_info->number_threads);
- return(GetPixelCacheNexusPixels(image->cache,cache_info->nexus_info[id]));
+ return(cache_info->nexus_info[id]->pixels);
}
\f
/*
MagickExport Quantum *GetAuthenticPixelQueue(const Image *image)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
(GetAuthenticPixelsFromHandler) NULL)
return(cache_info->methods.get_authentic_pixels_from_handler(image));
assert(id < (int) cache_info->number_threads);
- return(GetPixelCacheNexusPixels(cache_info,cache_info->nexus_info[id]));
+ return(cache_info->nexus_info[id]->pixels);
}
\f
/*
ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
Quantum
- *q;
+ *pixels;
assert(image != (Image *) NULL);
assert(image->signature == MagickSignature);
if (cache_info->methods.get_authentic_pixels_handler !=
(GetAuthenticPixelsHandler) NULL)
{
- q=cache_info->methods.get_authentic_pixels_handler(image,x,y,columns,rows,
- exception);
- return(q);
+ pixels=cache_info->methods.get_authentic_pixels_handler(image,x,y,columns,
+ rows,exception);
+ return(pixels);
}
assert(id < (int) cache_info->number_threads);
- q=GetAuthenticPixelCacheNexus(image,x,y,columns,rows,
+ pixels=GetAuthenticPixelCacheNexus(image,x,y,columns,rows,
cache_info->nexus_info[id],exception);
- return(q);
+ return(pixels);
}
\f
/*
ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
Quantum
- *q;
+ *restrict pixels;
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
return((Quantum *) NULL);
assert(cache_info->signature == MagickSignature);
assert(id < (int) cache_info->number_threads);
- q=GetAuthenticPixelCacheNexus(image,x,y,columns,rows,
+ pixels=GetAuthenticPixelCacheNexus(image,x,y,columns,rows,
cache_info->nexus_info[id],exception);
- return(q);
+ return(pixels);
}
\f
/*
MagickExport MagickSizeType GetImageExtent(const Image *image)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
if ((image->storage_class != cache_info->storage_class) ||
(image->colorspace != cache_info->colorspace) ||
(image->alpha_trait != cache_info->alpha_trait) ||
- (image->mask != cache_info->mask) ||
+ (image->read_mask != cache_info->read_mask) ||
+ (image->write_mask != cache_info->write_mask) ||
(image->columns != cache_info->columns) ||
(image->rows != cache_info->rows) ||
(image->number_channels != cache_info->number_channels) ||
ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
MagickBooleanType
destroy,
status=MagickTrue;
LockSemaphoreInfo(image->semaphore);
if (cpu_throttle == 0)
- {
- char
- *limit;
-
- /*
- Set CPU throttle in milleseconds.
- */
- cpu_throttle=MagickResourceInfinity;
- limit=GetEnvironmentValue("MAGICK_THROTTLE");
- if (limit == (char *) NULL)
- limit=GetPolicyValue("throttle");
- if (limit != (char *) NULL)
- {
- cpu_throttle=(MagickSizeType) StringToInteger(limit);
- limit=DestroyString(limit);
- }
- }
+ cpu_throttle=GetMagickResourceLimit(ThrottleResource);
if ((cpu_throttle != MagickResourceInfinity) && ((cycles++ % 32) == 0))
MagickDelay(cpu_throttle);
if (time_limit == 0)
}
if ((time_limit != MagickResourceInfinity) &&
((MagickSizeType) (time((time_t *) NULL)-cache_timestamp) >= time_limit))
- ThrowFatalException(ResourceLimitFatalError,"TimeLimitExceeded");
+ {
+#if defined(ECANCELED)
+ errno=ECANCELED;
+#endif
+ ThrowFatalException(ResourceLimitFatalError,"TimeLimitExceeded");
+ }
assert(image->cache != (Cache) NULL);
cache_info=(CacheInfo *) image->cache;
destroy=MagickFalse;
Clone pixel cache.
*/
clone_image=(*image);
- clone_image.semaphore=AllocateSemaphoreInfo();
+ clone_image.semaphore=AcquireSemaphoreInfo();
clone_image.reference_count=1;
clone_image.cache=ClonePixelCache(cache_info);
clone_info=(CacheInfo *) clone_image.cache;
if (status != MagickFalse)
{
if (clone != MagickFalse)
- status=ClonePixelCachePixels(clone_info,cache_info,exception);
+ status=ClonePixelCacheRepository(clone_info,cache_info,
+ exception);
if (status != MagickFalse)
{
if (cache_info->reference_count == 1)
image->cache=clone_image.cache;
}
}
- DestroySemaphoreInfo(&clone_image.semaphore);
+ RelinquishSemaphoreInfo(&clone_image.semaphore);
}
UnlockSemaphoreInfo(cache_info->semaphore);
}
MagickExport CacheType GetImagePixelCacheType(const Image *image)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
assert(image != (Image *) NULL);
assert(image->signature == MagickSignature);
const ssize_t x,const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
register Quantum
- *q;
+ *restrict q;
register ssize_t
i;
}
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
- PixelChannel
- channel;
-
- channel=GetPixelChannelChannel(image,i);
+ PixelChannel channel=GetPixelChannelChannel(image,i);
pixel[channel]=q[i];
}
return(MagickTrue);
const ssize_t x,const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
register Quantum
- *q;
+ *restrict q;
register ssize_t
i;
}
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
- PixelChannel
- channel;
-
- channel=GetPixelChannelChannel(image,i);
+ PixelChannel channel=GetPixelChannelChannel(image,i);
pixel[channel]=q[i];
}
return(MagickTrue);
const ssize_t x,const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
}
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
- PixelChannel
- channel;
-
- channel=GetPixelChannelChannel(image,i);
+ PixelChannel channel=GetPixelChannelChannel(image,i);
pixel[channel]=p[i];
}
return(MagickTrue);
Quantum *pixel,ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
}
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
- PixelChannel
- channel;
-
- channel=GetPixelChannelChannel(image,i);
+ PixelChannel channel=GetPixelChannelChannel(image,i);
pixel[channel]=p[i];
}
return(MagickTrue);
PixelInfo *pixel,ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
register const Quantum
- *p;
+ *restrict p;
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
MagickPrivate ColorspaceType GetPixelCacheColorspace(const Cache cache)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
assert(cache != (Cache) NULL);
cache_info=(CacheInfo *) cache;
%
*/
MagickPrivate MagickSizeType GetPixelCacheNexusExtent(const Cache cache,
- NexusInfo *nexus_info)
+ NexusInfo *restrict nexus_info)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
MagickSizeType
extent;
% %
% %
% %
-+ G e t P i x e l C a c h e N e x u s M e t a c o n t e n t %
-% %
-% %
-% %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% GetPixelCacheNexusMetacontent() returns the meta-content for the specified
-% cache nexus.
-%
-% The format of the GetPixelCacheNexusMetacontent() method is:
-%
-% void *GetPixelCacheNexusMetacontent(const Cache cache,
-% NexusInfo *nexus_info)
-%
-% A description of each parameter follows:
-%
-% o cache: the pixel cache.
-%
-% o nexus_info: the cache nexus to return the meta-content.
-%
-*/
-MagickPrivate void *GetPixelCacheNexusMetacontent(const Cache cache,
- NexusInfo *nexus_info)
-{
- CacheInfo
- *cache_info;
-
- assert(cache != NULL);
- cache_info=(CacheInfo *) cache;
- assert(cache_info->signature == MagickSignature);
- if (cache_info->storage_class == UndefinedClass)
- return((void *) NULL);
- return(nexus_info->metacontent);
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% %
-% %
-% %
-+ G e t P i x e l C a c h e N e x u s P i x e l s %
-% %
-% %
-% %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% GetPixelCacheNexusPixels() returns the pixels associated with the specified
-% cache nexus.
-%
-% The format of the GetPixelCacheNexusPixels() method is:
-%
-% Quantum *GetPixelCacheNexusPixels(const Cache cache,
-% NexusInfo *nexus_info)
-%
-% A description of each parameter follows:
-%
-% o cache: the pixel cache.
-%
-% o nexus_info: the cache nexus to return the pixels.
-%
-*/
-MagickPrivate Quantum *GetPixelCacheNexusPixels(const Cache cache,
- NexusInfo *nexus_info)
-{
- CacheInfo
- *cache_info;
-
- assert(cache != NULL);
- cache_info=(CacheInfo *) cache;
- assert(cache_info->signature == MagickSignature);
- if (cache_info->storage_class == UndefinedClass)
- return((Quantum *) NULL);
- return(nexus_info->pixels);
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% %
-% %
-% %
+ G e t P i x e l C a c h e P i x e l s %
% %
% %
ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
MagickPrivate ClassType GetPixelCacheStorageClass(const Cache cache)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
assert(cache != (Cache) NULL);
cache_info=(CacheInfo *) cache;
size_t *height)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
assert(image != (Image *) NULL);
assert(image->signature == MagickSignature);
MagickPrivate VirtualPixelMethod GetPixelCacheVirtualMethod(const Image *image)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
assert(image != (Image *) NULL);
assert(image->signature == MagickSignature);
static const void *GetVirtualMetacontentFromCache(const Image *image)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
const void
- *metacontent;
+ *restrict metacontent;
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
%
*/
MagickPrivate const void *GetVirtualMetacontentFromNexus(const Cache cache,
- NexusInfo *nexus_info)
+ NexusInfo *restrict nexus_info)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
assert(cache != (Cache) NULL);
cache_info=(CacheInfo *) cache;
MagickExport const void *GetVirtualMetacontent(const Image *image)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
const void
- *metacontent;
+ *restrict metacontent;
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
MagickOffsetType
offset;
number_pixels;
NexusInfo
- **virtual_nexus;
+ **restrict virtual_nexus;
Quantum
- *pixels,
- virtual_pixel[CompositePixelChannel];
+ *restrict pixels,
+ virtual_pixel[MaxPixelChannels];
RectangleInfo
region;
v;
void
- *virtual_metacontent;
+ *restrict virtual_metacontent;
/*
Acquire pixels.
region.y=y;
region.width=columns;
region.height=rows;
- pixels=SetPixelCacheNexusPixels(image,ReadMode,®ion,nexus_info,exception);
+ pixels=SetPixelCacheNexusPixels(cache_info,ReadMode,®ion,nexus_info,
+ exception);
if (pixels == (Quantum *) NULL)
return((const Quantum *) NULL);
q=pixels;
/*
Pixel request is inside cache extents.
*/
- if (IsPixelAuthentic(cache_info,nexus_info) != MagickFalse)
+ if (nexus_info->authentic_pixel_cache != MagickFalse)
return(q);
status=ReadPixelCachePixels(cache_info,nexus_info,exception);
if (status == MagickFalse)
/*
Pixel request is outside cache extents.
*/
- s=(unsigned char *) GetPixelCacheNexusMetacontent(cache_info,nexus_info);
+ s=(unsigned char *) nexus_info->metacontent;
virtual_nexus=AcquirePixelCacheNexus(1);
if (virtual_nexus == (NexusInfo **) NULL)
{
}
for (v=0; v < (ssize_t) rows; v++)
{
+ ssize_t
+ y_offset;
+
+ y_offset=y+v;
+ if ((virtual_pixel_method == EdgeVirtualPixelMethod) ||
+ (virtual_pixel_method == UndefinedVirtualPixelMethod))
+ y_offset=EdgeY(y_offset,cache_info->rows);
for (u=0; u < (ssize_t) columns; u+=length)
{
- length=(MagickSizeType) MagickMin(cache_info->columns-(x+u),columns-u);
- if ((((x+u) < 0) || ((x+u) >= (ssize_t) cache_info->columns)) ||
- (((y+v) < 0) || ((y+v) >= (ssize_t) cache_info->rows)) ||
+ ssize_t
+ x_offset;
+
+ x_offset=x+u;
+ length=(MagickSizeType) MagickMin(cache_info->columns-x_offset,columns-u);
+ if (((x_offset < 0) || (x_offset >= (ssize_t) cache_info->columns)) ||
+ ((y_offset < 0) || (y_offset >= (ssize_t) cache_info->rows)) ||
(length == 0))
{
MagickModulo
length=(MagickSizeType) 1;
switch (virtual_pixel_method)
{
+ case EdgeVirtualPixelMethod:
default:
{
p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,
- EdgeX(x+u,cache_info->columns),EdgeY(y+v,cache_info->rows),
- 1UL,1UL,*virtual_nexus,exception);
+ EdgeX(x_offset,cache_info->columns),
+ EdgeY(y_offset,cache_info->rows),1UL,1UL,*virtual_nexus,
+ exception);
r=GetVirtualMetacontentFromNexus(cache_info,*virtual_nexus);
break;
}
case DitherVirtualPixelMethod:
{
p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,
- DitherX(x+u,cache_info->columns),DitherY(y+v,cache_info->rows),
- 1UL,1UL,*virtual_nexus,exception);
+ DitherX(x_offset,cache_info->columns),
+ DitherY(y_offset,cache_info->rows),1UL,1UL,*virtual_nexus,
+ exception);
r=GetVirtualMetacontentFromNexus(cache_info,*virtual_nexus);
break;
}
case TileVirtualPixelMethod:
{
- x_modulo=VirtualPixelModulo(x+u,cache_info->columns);
- y_modulo=VirtualPixelModulo(y+v,cache_info->rows);
+ x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
+ y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,
x_modulo.remainder,y_modulo.remainder,1UL,1UL,*virtual_nexus,
exception);
}
case MirrorVirtualPixelMethod:
{
- x_modulo=VirtualPixelModulo(x+u,cache_info->columns);
+ x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
if ((x_modulo.quotient & 0x01) == 1L)
x_modulo.remainder=(ssize_t) cache_info->columns-
x_modulo.remainder-1L;
- y_modulo=VirtualPixelModulo(y+v,cache_info->rows);
+ y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
if ((y_modulo.quotient & 0x01) == 1L)
y_modulo.remainder=(ssize_t) cache_info->rows-
y_modulo.remainder-1L;
}
case HorizontalTileEdgeVirtualPixelMethod:
{
- x_modulo=VirtualPixelModulo(x+u,cache_info->columns);
+ x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,
- x_modulo.remainder,EdgeY(y+v,cache_info->rows),1UL,1UL,
+ x_modulo.remainder,EdgeY(y_offset,cache_info->rows),1UL,1UL,
*virtual_nexus,exception);
r=GetVirtualMetacontentFromNexus(cache_info,*virtual_nexus);
break;
}
case VerticalTileEdgeVirtualPixelMethod:
{
- y_modulo=VirtualPixelModulo(y+v,cache_info->rows);
+ y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,
- EdgeX(x+u,cache_info->columns),y_modulo.remainder,1UL,1UL,
+ EdgeX(x_offset,cache_info->columns),y_modulo.remainder,1UL,1UL,
*virtual_nexus,exception);
r=GetVirtualMetacontentFromNexus(cache_info,*virtual_nexus);
break;
r=virtual_metacontent;
break;
}
- case EdgeVirtualPixelMethod:
case CheckerTileVirtualPixelMethod:
{
- x_modulo=VirtualPixelModulo(x+u,cache_info->columns);
- y_modulo=VirtualPixelModulo(y+v,cache_info->rows);
+ x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
+ y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
if (((x_modulo.quotient ^ y_modulo.quotient) & 0x01) != 0L)
{
p=virtual_pixel;
}
case HorizontalTileVirtualPixelMethod:
{
- if (((y+v) < 0) || ((y+v) >= (ssize_t) cache_info->rows))
+ if ((y_offset < 0) || (y_offset >= (ssize_t) cache_info->rows))
{
p=virtual_pixel;
r=virtual_metacontent;
break;
}
- x_modulo=VirtualPixelModulo(x+u,cache_info->columns);
- y_modulo=VirtualPixelModulo(y+v,cache_info->rows);
+ x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
+ y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,
x_modulo.remainder,y_modulo.remainder,1UL,1UL,*virtual_nexus,
exception);
}
case VerticalTileVirtualPixelMethod:
{
- if (((x+u) < 0) || ((x+u) >= (ssize_t) cache_info->columns))
+ if ((x_offset < 0) || (x_offset >= (ssize_t) cache_info->columns))
{
p=virtual_pixel;
r=virtual_metacontent;
break;
}
- x_modulo=VirtualPixelModulo(x+u,cache_info->columns);
- y_modulo=VirtualPixelModulo(y+v,cache_info->rows);
+ x_modulo=VirtualPixelModulo(x_offset,cache_info->columns);
+ y_modulo=VirtualPixelModulo(y_offset,cache_info->rows);
p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,
x_modulo.remainder,y_modulo.remainder,1UL,1UL,*virtual_nexus,
exception);
/*
Transfer a run of pixels.
*/
- p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,x+u,y+v,(size_t)
- length,1UL,*virtual_nexus,exception);
+ p=GetVirtualPixelsFromNexus(image,virtual_pixel_method,x_offset,y_offset,
+ (size_t) length,1UL,*virtual_nexus,exception);
if (p == (const Quantum *) NULL)
break;
r=GetVirtualMetacontentFromNexus(cache_info,*virtual_nexus);
const size_t columns,const size_t rows,ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
const Quantum
- *p;
+ *restrict p;
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
MagickExport const Quantum *GetVirtualPixelQueue(const Image *image)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
const Quantum
- *p;
+ *restrict p;
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
static const Quantum *GetVirtualPixelsCache(const Image *image)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
%
*/
MagickPrivate const Quantum *GetVirtualPixelsNexus(const Cache cache,
- NexusInfo *nexus_info)
+ NexusInfo *restrict nexus_info)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
assert(cache != (Cache) NULL);
cache_info=(CacheInfo *) cache;
return((Quantum *) NULL);
return((const Quantum *) nexus_info->pixels);
}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% %
-% %
-% %
-+ O p e n P i x e l C a c h e %
-% %
-% %
-% %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% OpenPixelCache() allocates the pixel cache. This includes defining the cache
-% dimensions, allocating space for the image pixels and optionally the
-% metacontent, and memory mapping the cache if it is disk based. The cache
-% nexus array is initialized as well.
-%
-% The format of the OpenPixelCache() method is:
-%
-% MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
-% ExceptionInfo *exception)
-%
-% A description of each parameter follows:
-%
-% o image: the image.
-%
-% o mode: ReadMode, WriteMode, or IOMode.
-%
-% o exception: return any errors or warnings in this structure.
-%
-*/
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ O p e n P i x e l C a c h e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% OpenPixelCache() allocates the pixel cache. This includes defining the cache
+% dimensions, allocating space for the image pixels and optionally the
+% metacontent, and memory mapping the cache if it is disk based. The cache
+% nexus array is initialized as well.
+%
+% The format of the OpenPixelCache() method is:
+%
+% MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: the image.
+%
+% o mode: ReadMode, WriteMode, or IOMode.
+%
+% o exception: return any errors or warnings in this structure.
+%
+*/
+
+static inline void AllocatePixelCachePixels(CacheInfo *cache_info)
+{
+ cache_info->mapped=MagickFalse;
+ cache_info->pixels=(Quantum *) MagickAssumeAligned(AcquireAlignedMemory(1,
+ (size_t) cache_info->length));
+ if (cache_info->pixels == (Quantum *) NULL)
+ {
+ cache_info->mapped=MagickTrue;
+ cache_info->pixels=(Quantum *) MapBlob(-1,IOMode,0,(size_t)
+ cache_info->length);
+ }
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#if defined(SIGBUS)
+static void CacheSignalHandler(int status)
+{
+ ThrowFatalException(CacheFatalError,"UnableToExtendPixelCache");
+}
+#endif
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+static MagickBooleanType OpenPixelCacheOnDisk(CacheInfo *cache_info,
+ const MapMode mode)
+{
+ int
+ file;
+
+ /*
+ Open pixel cache on disk.
+ */
+ if (cache_info->file != -1)
+ return(MagickTrue); /* cache already open */
+ if (*cache_info->cache_filename == '\0')
+ file=AcquireUniqueFileResource(cache_info->cache_filename);
+ else
+ switch (mode)
+ {
+ case ReadMode:
+ {
+ file=open_utf8(cache_info->cache_filename,O_RDONLY | O_BINARY,0);
+ break;
+ }
+ case WriteMode:
+ {
+ file=open_utf8(cache_info->cache_filename,O_WRONLY | O_CREAT |
+ O_BINARY | O_EXCL,S_MODE);
+ if (file == -1)
+ file=open_utf8(cache_info->cache_filename,O_WRONLY | O_BINARY,S_MODE);
+ break;
+ }
+ case IOMode:
+ default:
+ {
+ file=open_utf8(cache_info->cache_filename,O_RDWR | O_CREAT | O_BINARY |
+ O_EXCL,S_MODE);
+ if (file == -1)
+ file=open_utf8(cache_info->cache_filename,O_RDWR | O_BINARY,S_MODE);
+ break;
+ }
+ }
+ if (file == -1)
+ return(MagickFalse);
+ (void) AcquireMagickResource(FileResource,1);
+ cache_info->file=file;
+ cache_info->mode=mode;
+ return(MagickTrue);
+}
-static inline void AllocatePixelCachePixels(CacheInfo *cache_info)
+static inline MagickOffsetType WritePixelCacheRegion(
+ const CacheInfo *restrict cache_info,const MagickOffsetType offset,
+ const MagickSizeType length,const unsigned char *restrict buffer)
{
- cache_info->mapped=MagickFalse;
- cache_info->pixels=(Quantum *) MagickAssumeAligned(AcquireAlignedMemory(1,
- (size_t) cache_info->length));
- if (cache_info->pixels == (Quantum *) NULL)
- {
- cache_info->mapped=MagickTrue;
- cache_info->pixels=(Quantum *) MapBlob(-1,IOMode,0,(size_t)
- cache_info->length);
- }
+ register MagickOffsetType
+ i;
+
+ ssize_t
+ count;
+
+#if !defined(MAGICKCORE_HAVE_PWRITE)
+ if (lseek(cache_info->file,offset,SEEK_SET) < 0)
+ return((MagickOffsetType) -1);
+#endif
+ count=0;
+ for (i=0; i < (MagickOffsetType) length; i+=count)
+ {
+#if !defined(MAGICKCORE_HAVE_PWRITE)
+ count=write(cache_info->file,buffer+i,(size_t) MagickMin(length-i,
+ (MagickSizeType) SSIZE_MAX));
+#else
+ count=pwrite(cache_info->file,buffer+i,(size_t) MagickMin(length-i,
+ (MagickSizeType) SSIZE_MAX),(off_t) (offset+i));
+#endif
+ if (count <= 0)
+ {
+ count=0;
+ if (errno != EINTR)
+ break;
+ }
+ }
+ return(i);
}
static MagickBooleanType SetPixelCacheExtent(Image *image,MagickSizeType length)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
MagickOffsetType
count,
if (status != 0)
return(MagickFalse);
}
+#endif
+#if defined(SIGBUS)
+ (void) signal(SIGBUS,CacheSignalHandler);
#endif
return(count != (MagickOffsetType) 1 ? MagickFalse : MagickTrue);
}
ExceptionInfo *exception)
{
CacheInfo
- *cache_info,
+ *restrict cache_info,
source_info;
char
format[MaxTextExtent],
message[MaxTextExtent];
+ const char
+ *type;
+
MagickBooleanType
status;
cache_info->storage_class=image->storage_class;
cache_info->colorspace=image->colorspace;
cache_info->alpha_trait=image->alpha_trait;
- cache_info->mask=image->mask;
+ cache_info->read_mask=image->read_mask;
+ cache_info->write_mask=image->write_mask;
cache_info->rows=image->rows;
cache_info->columns=image->columns;
InitializePixelChannelMap(image);
if ((source_info.storage_class != UndefinedClass) &&
(mode != ReadMode))
{
- status=ClonePixelCachePixels(cache_info,&source_info,
+ status=ClonePixelCacheRepository(cache_info,&source_info,
exception);
RelinquishPixelCachePixels(&source_info);
}
if (image->debug != MagickFalse)
{
(void) FormatMagickSize(cache_info->length,MagickTrue,format);
+ type=CommandOptionToMnemonic(MagickCacheOptions,(ssize_t)
+ cache_info->type);
(void) FormatLocaleString(message,MaxTextExtent,
- "open %s (%s memory, %.20gx%.20gx%.20g %s)",
+ "open %s (%s %s, %.20gx%.20gx%.20g %s)",
cache_info->filename,cache_info->mapped != MagickFalse ?
- "anonymous" : "heap",(double) cache_info->columns,(double)
- cache_info->rows,(double) cache_info->number_channels,
- format);
+ "Anonymous" : "Heap",type,(double) cache_info->columns,
+ (double) cache_info->rows,(double)
+ cache_info->number_channels,format);
(void) LogMagickEvent(CacheEvent,GetMagickModule(),"%s",
message);
}
Create pixel cache on disk.
*/
status=AcquireMagickResource(DiskResource,cache_info->length);
- if (status == MagickFalse)
+ if ((status == MagickFalse) || (cache_info->type == DistributedCache))
{
- cache_info->distribute_cache_info=AcquireDistributeCacheInfo(exception);
- if (cache_info->distribute_cache_info != (DistributeCacheInfo *) NULL)
+ DistributeCacheInfo
+ *server_info;
+
+ if (cache_info->type == DistributedCache)
+ RelinquishMagickResource(DiskResource,cache_info->length);
+ server_info=AcquireDistributeCacheInfo(exception);
+ if (server_info != (DistributeCacheInfo *) NULL)
{
- status=OpenDistributePixelCache(cache_info->distribute_cache_info,
- image);
- if (status != MagickFalse)
+ status=OpenDistributePixelCache(server_info,image);
+ if (status == MagickFalse)
+ {
+ ThrowFileException(exception,CacheError,"UnableToOpenPixelCache",
+ GetDistributeCacheHostname(server_info));
+ server_info=DestroyDistributeCacheInfo(server_info);
+ }
+ else
{
+ /*
+ Create a distributed pixel cache.
+ */
cache_info->type=DistributedCache;
+ cache_info->server_info=server_info;
+ (void) FormatLocaleString(cache_info->cache_filename,
+ MaxTextExtent,"%s:%d",GetDistributeCacheHostname(
+ (DistributeCacheInfo *) cache_info->server_info),
+ GetDistributeCachePort((DistributeCacheInfo *)
+ cache_info->server_info));
if ((source_info.storage_class != UndefinedClass) &&
(mode != ReadMode))
{
- status=ClonePixelCachePixels(cache_info,&source_info,
+ status=ClonePixelCacheRepository(cache_info,&source_info,
exception);
RelinquishPixelCachePixels(&source_info);
}
{
(void) FormatMagickSize(cache_info->length,MagickFalse,
format);
+ type=CommandOptionToMnemonic(MagickCacheOptions,(ssize_t)
+ cache_info->type);
(void) FormatLocaleString(message,MaxTextExtent,
- "open %s (%d[%d], distribute, %.20gx%.20gx%.20g %s)",
- GetDistributeCacheHostname(cache_info->distribute_cache_info),
- GetDistributeCachePort(cache_info->distribute_cache_info),
- GetDistributeCacheFile(cache_info->distribute_cache_info),
- (double) cache_info->columns,(double) cache_info->rows,
- (double) cache_info->number_channels,format);
+ "open %s (%s[%d], %s, %.20gx%.20gx%.20g %s)",
+ cache_info->filename,cache_info->cache_filename,
+ GetDistributeCacheFile((DistributeCacheInfo *)
+ cache_info->server_info),type,(double) cache_info->columns,
+ (double) cache_info->rows,(double)
+ cache_info->number_channels,format);
(void) LogMagickEvent(CacheEvent,GetMagickModule(),"%s",
message);
}
return(MagickTrue);
}
}
+ RelinquishMagickResource(DiskResource,cache_info->length);
(void) ThrowMagickException(exception,GetMagickModule(),CacheError,
"CacheResourcesExhausted","`%s'",image->filename);
return(MagickFalse);
if ((source_info.storage_class != UndefinedClass) &&
(mode != ReadMode))
{
- status=ClonePixelCachePixels(cache_info,&source_info,
+ status=ClonePixelCacheRepository(cache_info,&source_info,
exception);
RelinquishPixelCachePixels(&source_info);
}
if (image->debug != MagickFalse)
{
(void) FormatMagickSize(cache_info->length,MagickTrue,format);
+ type=CommandOptionToMnemonic(MagickCacheOptions,(ssize_t)
+ cache_info->type);
(void) FormatLocaleString(message,MaxTextExtent,
- "open %s (%s[%d], memory-mapped, %.20gx%.20gx%.20g %s)",
+ "open %s (%s[%d], %s, %.20gx%.20gx%.20g %s)",
cache_info->filename,cache_info->cache_filename,
- cache_info->file,(double) cache_info->columns,(double)
+ cache_info->file,type,(double) cache_info->columns,(double)
cache_info->rows,(double) cache_info->number_channels,
format);
(void) LogMagickEvent(CacheEvent,GetMagickModule(),"%s",
status=MagickTrue;
if ((source_info.storage_class != UndefinedClass) && (mode != ReadMode))
{
- status=ClonePixelCachePixels(cache_info,&source_info,exception);
+ status=ClonePixelCacheRepository(cache_info,&source_info,exception);
RelinquishPixelCachePixels(&source_info);
}
if (image->debug != MagickFalse)
{
(void) FormatMagickSize(cache_info->length,MagickFalse,format);
+ type=CommandOptionToMnemonic(MagickCacheOptions,(ssize_t)
+ cache_info->type);
(void) FormatLocaleString(message,MaxTextExtent,
- "open %s (%s[%d], disk, %.20gx%.20gx%.20g %s)",cache_info->filename,
- cache_info->cache_filename,cache_info->file,(double)
+ "open %s (%s[%d], %s, %.20gx%.20gx%.20g %s)",cache_info->filename,
+ cache_info->cache_filename,cache_info->file,type,(double)
cache_info->columns,(double) cache_info->rows,(double)
cache_info->number_channels,format);
(void) LogMagickEvent(CacheEvent,GetMagickModule(),"%s",message);
ExceptionInfo *exception)
{
CacheInfo
- *cache_info,
- *clone_info;
+ *restrict cache_info,
+ *restrict clone_info;
Image
clone_image;
*offset+=cache_info->length+page_size-(cache_info->length % page_size);
return(MagickTrue);
}
- if ((cache_info->mode != ReadMode) && (cache_info->type != MemoryCache) &&
+ if ((cache_info->mode != ReadMode) &&
+ ((cache_info->type == DiskCache) || (cache_info->type == MapCache)) &&
(cache_info->reference_count == 1))
{
LockSemaphoreInfo(cache_info->semaphore);
- if ((cache_info->mode != ReadMode) && (cache_info->type != MemoryCache) &&
+ if ((cache_info->mode != ReadMode) &&
+ ((cache_info->type == DiskCache) || (cache_info->type == MapCache)) &&
(cache_info->reference_count == 1))
{
int
cache_info=(CacheInfo *) image->cache;
status=OpenPixelCache(image,IOMode,exception);
if (status != MagickFalse)
- status=ClonePixelCachePixels(cache_info,clone_info,exception);
+ status=ClonePixelCacheRepository(cache_info,clone_info,exception);
*offset+=cache_info->length+page_size-(cache_info->length % page_size);
clone_info=(CacheInfo *) DestroyPixelCache(clone_info);
return(status);
const MagickBooleanType clone,NexusInfo *nexus_info,ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
MagickOffsetType
offset;
MagickSizeType
number_pixels;
+ Quantum
+ *restrict pixels;
+
RectangleInfo
region;
if (cache_info == (Cache) NULL)
return((Quantum *) NULL);
assert(cache_info->signature == MagickSignature);
- if ((cache_info->columns == 0) && (cache_info->rows == 0))
- {
- (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
- "NoPixelsDefinedInCache","`%s'",image->filename);
- return((Quantum *) NULL);
- }
- if ((x < 0) || (y < 0) || (x >= (ssize_t) cache_info->columns) ||
+ if ((cache_info->columns == 0) || (cache_info->rows == 0) || (x < 0) ||
+ (y < 0) || (x >= (ssize_t) cache_info->columns) ||
(y >= (ssize_t) cache_info->rows))
{
(void) ThrowMagickException(exception,GetMagickModule(),CacheError,
region.y=y;
region.width=columns;
region.height=rows;
- return(SetPixelCacheNexusPixels(image,WriteMode,®ion,nexus_info,exception));
+ pixels=SetPixelCacheNexusPixels(cache_info,WriteMode,®ion,nexus_info,
+ exception);
+ return(pixels);
}
\f
/*
ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
Quantum
- *q;
+ *restrict pixels;
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
cache_info=(CacheInfo *) image->cache;
assert(cache_info->signature == MagickSignature);
assert(id < (int) cache_info->number_threads);
- q=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickFalse,
+ pixels=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickFalse,
cache_info->nexus_info[id],exception);
- return(q);
+ return(pixels);
}
\f
/*
ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
Quantum
- *q;
+ *restrict pixels;
assert(image != (Image *) NULL);
assert(image->signature == MagickSignature);
if (cache_info->methods.queue_authentic_pixels_handler !=
(QueueAuthenticPixelsHandler) NULL)
{
- q=cache_info->methods.queue_authentic_pixels_handler(image,x,y,columns,
- rows,exception);
- return(q);
+ pixels=cache_info->methods.queue_authentic_pixels_handler(image,x,y,
+ columns,rows,exception);
+ return(pixels);
}
assert(id < (int) cache_info->number_threads);
- q=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickFalse,
+ pixels=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickFalse,
cache_info->nexus_info[id],exception);
- return(q);
+ return(pixels);
}
\f
/*
% o exception: return any errors or warnings in this structure.
%
*/
-static MagickBooleanType ReadPixelCacheMetacontent(CacheInfo *cache_info,
- NexusInfo *nexus_info,ExceptionInfo *exception)
+
+static inline MagickOffsetType ReadPixelCacheRegion(
+ const CacheInfo *restrict cache_info,const MagickOffsetType offset,
+ const MagickSizeType length,unsigned char *restrict buffer)
+{
+ register MagickOffsetType
+ i;
+
+ ssize_t
+ count;
+
+#if !defined(MAGICKCORE_HAVE_PREAD)
+ if (lseek(cache_info->file,offset,SEEK_SET) < 0)
+ return((MagickOffsetType) -1);
+#endif
+ count=0;
+ for (i=0; i < (MagickOffsetType) length; i+=count)
+ {
+#if !defined(MAGICKCORE_HAVE_PREAD)
+ count=read(cache_info->file,buffer+i,(size_t) MagickMin(length-i,
+ (MagickSizeType) SSIZE_MAX));
+#else
+ count=pread(cache_info->file,buffer+i,(size_t) MagickMin(length-i,
+ (MagickSizeType) SSIZE_MAX),(off_t) (offset+i));
+#endif
+ if (count <= 0)
+ {
+ count=0;
+ if (errno != EINTR)
+ break;
+ }
+ }
+ return(i);
+}
+
+static MagickBooleanType ReadPixelCacheMetacontent(
+ CacheInfo *restrict cache_info,NexusInfo *restrict nexus_info,
+ ExceptionInfo *exception)
{
MagickOffsetType
count,
if (cache_info->metacontent_extent == 0)
return(MagickFalse);
- if (IsPixelAuthentic(cache_info,nexus_info) != MagickFalse)
+ if (nexus_info->authentic_pixel_cache != MagickFalse)
return(MagickTrue);
offset=(MagickOffsetType) nexus_info->region.y*cache_info->columns+
nexus_info->region.x;
length=(MagickSizeType) nexus_info->region.width*
cache_info->metacontent_extent;
+ extent=length*nexus_info->region.height;
rows=nexus_info->region.height;
- extent=length*rows;
+ y=0;
q=(unsigned char *) nexus_info->metacontent;
switch (cache_info->type)
{
count=ReadPixelCacheRegion(cache_info,cache_info->offset+extent*
cache_info->number_channels*sizeof(Quantum)+offset*
cache_info->metacontent_extent,length,(unsigned char *) q);
- if ((MagickSizeType) count != length)
+ if (count != (MagickOffsetType) length)
break;
offset+=cache_info->columns;
q+=cache_info->metacontent_extent*nexus_info->region.width;
if (IsFileDescriptorLimitExceeded() != MagickFalse)
(void) ClosePixelCacheOnDisk(cache_info);
UnlockSemaphoreInfo(cache_info->file_semaphore);
- if (y < (ssize_t) rows)
- {
- ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
- cache_info->cache_filename);
- return(MagickFalse);
- }
break;
}
case DistributedCache:
{
- MagickBooleanType
- status;
+ RectangleInfo
+ region;
/*
Read metacontent from distributed cache.
*/
LockSemaphoreInfo(cache_info->file_semaphore);
- status=ReadDistributePixelCacheMetacontent(
- cache_info->distribute_cache_info,&nexus_info->region,length,
- (unsigned char *) nexus_info->pixels);
- UnlockSemaphoreInfo(cache_info->file_semaphore);
- if (status == MagickFalse)
+ region=nexus_info->region;
+ if ((cache_info->columns != nexus_info->region.width) ||
+ (extent > MagickMaxBufferExtent))
+ region.height=1UL;
+ else
{
- ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
- GetDistributeCacheHostname(cache_info->distribute_cache_info));
- return(MagickFalse);
+ length=extent;
+ rows=1UL;
}
+ for (y=0; y < (ssize_t) rows; y++)
+ {
+ count=ReadDistributePixelCacheMetacontent((DistributeCacheInfo *)
+ cache_info->server_info,®ion,length,(unsigned char *) q);
+ if (count != (MagickOffsetType) length)
+ break;
+ q+=cache_info->metacontent_extent*nexus_info->region.width;
+ region.y++;
+ }
+ UnlockSemaphoreInfo(cache_info->file_semaphore);
break;
}
default:
break;
}
+ if (y < (ssize_t) rows)
+ {
+ ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
+ cache_info->cache_filename);
+ return(MagickFalse);
+ }
if ((cache_info->debug != MagickFalse) &&
(CacheTick(nexus_info->region.y,cache_info->rows) != MagickFalse))
(void) LogMagickEvent(CacheEvent,GetMagickModule(),
% o exception: return any errors or warnings in this structure.
%
*/
-static MagickBooleanType ReadPixelCachePixels(CacheInfo *cache_info,
- NexusInfo *nexus_info,ExceptionInfo *exception)
+static MagickBooleanType ReadPixelCachePixels(CacheInfo *restrict cache_info,
+ NexusInfo *restrict nexus_info,ExceptionInfo *exception)
{
MagickOffsetType
count,
size_t
rows;
- if (IsPixelAuthentic(cache_info,nexus_info) != MagickFalse)
+ if (nexus_info->authentic_pixel_cache != MagickFalse)
return(MagickTrue);
offset=(MagickOffsetType) nexus_info->region.y*cache_info->columns+
nexus_info->region.x;
- length=(MagickSizeType) nexus_info->region.width*cache_info->number_channels*
+ length=(MagickSizeType) cache_info->number_channels*nexus_info->region.width*
sizeof(Quantum);
+ extent=length*nexus_info->region.height;
rows=nexus_info->region.height;
- extent=length*rows;
+ y=0;
q=nexus_info->pixels;
switch (cache_info->type)
{
{
count=ReadPixelCacheRegion(cache_info,cache_info->offset+offset*
cache_info->number_channels*sizeof(*q),length,(unsigned char *) q);
- if ((MagickSizeType) count != length)
+ if (count != (MagickOffsetType) length)
break;
offset+=cache_info->columns;
q+=cache_info->number_channels*nexus_info->region.width;
if (IsFileDescriptorLimitExceeded() != MagickFalse)
(void) ClosePixelCacheOnDisk(cache_info);
UnlockSemaphoreInfo(cache_info->file_semaphore);
- if (y < (ssize_t) rows)
- {
- ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
- cache_info->cache_filename);
- return(MagickFalse);
- }
break;
}
case DistributedCache:
{
- MagickBooleanType
- status;
+ RectangleInfo
+ region;
/*
Read pixels from distributed cache.
*/
LockSemaphoreInfo(cache_info->file_semaphore);
- status=ReadDistributePixelCachePixels(cache_info->distribute_cache_info,
- &nexus_info->region,length,(unsigned char *) nexus_info->pixels);
- UnlockSemaphoreInfo(cache_info->file_semaphore);
- if (status == MagickFalse)
+ region=nexus_info->region;
+ if ((cache_info->columns != nexus_info->region.width) ||
+ (extent > MagickMaxBufferExtent))
+ region.height=1UL;
+ else
{
- ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
- GetDistributeCacheHostname(cache_info->distribute_cache_info));
- return(MagickFalse);
+ length=extent;
+ rows=1UL;
}
+ for (y=0; y < (ssize_t) rows; y++)
+ {
+ count=ReadDistributePixelCachePixels((DistributeCacheInfo *)
+ cache_info->server_info,®ion,length,(unsigned char *) q);
+ if (count != (MagickOffsetType) length)
+ break;
+ q+=cache_info->number_channels*nexus_info->region.width;
+ region.y++;
+ }
+ UnlockSemaphoreInfo(cache_info->file_semaphore);
break;
}
default:
break;
}
+ if (y < (ssize_t) rows)
+ {
+ ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
+ cache_info->cache_filename);
+ return(MagickFalse);
+ }
if ((cache_info->debug != MagickFalse) &&
(CacheTick(nexus_info->region.y,cache_info->rows) != MagickFalse))
(void) LogMagickEvent(CacheEvent,GetMagickModule(),
MagickPrivate Cache ReferencePixelCache(Cache cache)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
assert(cache != (Cache *) NULL);
cache_info=(CacheInfo *) cache;
MagickPrivate void SetPixelCacheMethods(Cache cache,CacheMethods *cache_methods)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
GetOneAuthenticPixelFromHandler
get_one_authentic_pixel_from_handler;
%
% The format of the SetPixelCacheNexusPixels() method is:
%
-% Quantum SetPixelCacheNexusPixels(const Image *image,const MapMode mode,
-% const RectangleInfo *region,NexusInfo *nexus_info,
+% Quantum SetPixelCacheNexusPixels(const CacheInfo *cache_info,
+% const MapMode mode,const RectangleInfo *region,NexusInfo *nexus_info,
% ExceptionInfo *exception)
%
% A description of each parameter follows:
%
-% o image: the image.
+% o cache_info: the pixel cache.
%
% o mode: ReadMode, WriteMode, or IOMode.
%
return(MagickTrue);
}
+static inline MagickBooleanType IsPixelCacheAuthentic(
+ const CacheInfo *restrict cache_info,const NexusInfo *restrict nexus_info)
+{
+ MagickBooleanType
+ status;
+
+ MagickOffsetType
+ offset;
+
+ /*
+ Does nexus pixels point directly to in-core cache pixels or is it buffered?
+ */
+ if (cache_info->type == PingCache)
+ return(MagickTrue);
+ offset=(MagickOffsetType) nexus_info->region.y*cache_info->columns+
+ nexus_info->region.x;
+ status=nexus_info->pixels == (cache_info->pixels+offset*
+ cache_info->number_channels) ? MagickTrue : MagickFalse;
+ return(status);
+}
+
static inline void PrefetchPixelCacheNexusPixels(const NexusInfo *nexus_info,
const MapMode mode)
{
MagickCachePrefetch((unsigned char *) nexus_info->pixels,1,1);
}
-static Quantum *SetPixelCacheNexusPixels(const Image *image,const MapMode mode,
- const RectangleInfo *region,NexusInfo *nexus_info,ExceptionInfo *exception)
+static Quantum *SetPixelCacheNexusPixels(const CacheInfo *cache_info,
+ const MapMode mode,const RectangleInfo *region,NexusInfo *nexus_info,
+ ExceptionInfo *exception)
{
- CacheInfo
- *cache_info;
-
MagickBooleanType
status;
length,
number_pixels;
- cache_info=(CacheInfo *) image->cache;
+ assert(cache_info != (const CacheInfo *) NULL);
assert(cache_info->signature == MagickSignature);
if (cache_info->type == UndefinedCache)
return((Quantum *) NULL);
nexus_info->metacontent=(unsigned char *) cache_info->metacontent+
offset*cache_info->metacontent_extent;
PrefetchPixelCacheNexusPixels(nexus_info,mode);
+ nexus_info->authentic_pixel_cache=IsPixelCacheAuthentic(cache_info,
+ nexus_info);
return(nexus_info->pixels);
}
}
/*
- Pixels are stored in a cache region until they are synced to the cache.
+ Pixels are stored in a staging region until they are synced to the cache.
*/
number_pixels=(MagickSizeType) nexus_info->region.width*
nexus_info->region.height;
}
}
else
- if (nexus_info->length != length)
+ if (nexus_info->length < length)
{
RelinquishCacheNexusPixels(nexus_info);
nexus_info->length=length;
nexus_info->metacontent=(void *) (nexus_info->pixels+number_pixels*
cache_info->number_channels);
PrefetchPixelCacheNexusPixels(nexus_info,mode);
+ nexus_info->authentic_pixel_cache=IsPixelCacheAuthentic(cache_info,
+ nexus_info);
return(nexus_info->pixels);
}
\f
ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
CacheView
- *image_view;
+ *restrict image_view;
MagickBooleanType
status;
const VirtualPixelMethod virtual_pixel_method,ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
VirtualPixelMethod
method;
(void) SetCacheAlphaChannel(image,OpaqueAlpha,exception);
if ((IsPixelInfoGray(&image->background_color) == MagickFalse) &&
(IsGrayColorspace(image->colorspace) != MagickFalse))
- (void) TransformImageColorspace(image,RGBColorspace,exception);
+ (void) SetImageColorspace(image,sRGBColorspace,exception);
break;
}
case TransparentVirtualPixelMethod:
%
*/
MagickPrivate MagickBooleanType SyncAuthenticPixelCacheNexus(Image *image,
- NexusInfo *nexus_info,ExceptionInfo *exception)
+ NexusInfo *restrict nexus_info,ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
MagickBooleanType
status;
assert(cache_info->signature == MagickSignature);
if (cache_info->type == UndefinedCache)
return(MagickFalse);
- if (IsPixelAuthentic(cache_info,nexus_info) != MagickFalse)
+ if (nexus_info->authentic_pixel_cache != MagickFalse)
return(MagickTrue);
assert(cache_info->signature == MagickSignature);
status=WritePixelCachePixels(cache_info,nexus_info,exception);
ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
const int
id = GetOpenMPThreadId();
ExceptionInfo *exception)
{
CacheInfo
- *cache_info;
+ *restrict cache_info;
assert(image != (Image *) NULL);
assert(exception != (ExceptionInfo *) NULL);
%
*/
static MagickBooleanType WritePixelCacheMetacontent(CacheInfo *cache_info,
- NexusInfo *nexus_info,ExceptionInfo *exception)
+ NexusInfo *restrict nexus_info,ExceptionInfo *exception)
{
MagickOffsetType
count,
if (cache_info->metacontent_extent == 0)
return(MagickFalse);
- if (IsPixelAuthentic(cache_info,nexus_info) != MagickFalse)
+ if (nexus_info->authentic_pixel_cache != MagickFalse)
return(MagickTrue);
offset=(MagickOffsetType) nexus_info->region.y*cache_info->columns+
nexus_info->region.x;
length=(MagickSizeType) nexus_info->region.width*
cache_info->metacontent_extent;
+ extent=(MagickSizeType) length*nexus_info->region.height;
rows=nexus_info->region.height;
- extent=(MagickSizeType) length*rows;
+ y=0;
p=(unsigned char *) nexus_info->metacontent;
switch (cache_info->type)
{
count=WritePixelCacheRegion(cache_info,cache_info->offset+extent*
cache_info->number_channels*sizeof(Quantum)+offset*
cache_info->metacontent_extent,length,(const unsigned char *) p);
- if ((MagickSizeType) count != length)
+ if (count != (MagickOffsetType) length)
break;
- p+=nexus_info->region.width*cache_info->metacontent_extent;
+ p+=cache_info->metacontent_extent*nexus_info->region.width;
offset+=cache_info->columns;
}
if (IsFileDescriptorLimitExceeded() != MagickFalse)
(void) ClosePixelCacheOnDisk(cache_info);
UnlockSemaphoreInfo(cache_info->file_semaphore);
- if (y < (ssize_t) rows)
- {
- ThrowFileException(exception,CacheError,"UnableToWritePixelCache",
- cache_info->cache_filename);
- return(MagickFalse);
- }
break;
}
case DistributedCache:
{
- MagickBooleanType
- status;
+ RectangleInfo
+ region;
/*
Write metacontent to distributed cache.
*/
LockSemaphoreInfo(cache_info->file_semaphore);
- status=WriteDistributePixelCacheMetacontent(
- cache_info->distribute_cache_info,&nexus_info->region,length,
- (const unsigned char *) nexus_info->metacontent);
- UnlockSemaphoreInfo(cache_info->file_semaphore);
- if (status == MagickFalse)
+ region=nexus_info->region;
+ if ((cache_info->columns != nexus_info->region.width) ||
+ (extent > MagickMaxBufferExtent))
+ region.height=1UL;
+ else
{
- ThrowFileException(exception,CacheError,"UnableToWritePixelCache",
- GetDistributeCacheHostname(cache_info->distribute_cache_info));
- return(MagickFalse);
+ length=extent;
+ rows=1UL;
}
+ for (y=0; y < (ssize_t) rows; y++)
+ {
+ count=WriteDistributePixelCacheMetacontent((DistributeCacheInfo *)
+ cache_info->server_info,®ion,length,(const unsigned char *) p);
+ if (count != (MagickOffsetType) length)
+ break;
+ p+=cache_info->metacontent_extent*nexus_info->region.width;
+ region.y++;
+ }
+ UnlockSemaphoreInfo(cache_info->file_semaphore);
break;
}
default:
break;
}
+ if (y < (ssize_t) rows)
+ {
+ ThrowFileException(exception,CacheError,"UnableToWritePixelCache",
+ cache_info->cache_filename);
+ return(MagickFalse);
+ }
if ((cache_info->debug != MagickFalse) &&
(CacheTick(nexus_info->region.y,cache_info->rows) != MagickFalse))
(void) LogMagickEvent(CacheEvent,GetMagickModule(),
% o exception: return any errors or warnings in this structure.
%
*/
-static MagickBooleanType WritePixelCachePixels(CacheInfo *cache_info,
- NexusInfo *nexus_info,ExceptionInfo *exception)
+static MagickBooleanType WritePixelCachePixels(CacheInfo *restrict cache_info,
+ NexusInfo *restrict nexus_info,ExceptionInfo *exception)
{
MagickOffsetType
count,
size_t
rows;
- if (IsPixelAuthentic(cache_info,nexus_info) != MagickFalse)
+ if (nexus_info->authentic_pixel_cache != MagickFalse)
return(MagickTrue);
offset=(MagickOffsetType) nexus_info->region.y*cache_info->columns+
nexus_info->region.x;
- length=(MagickSizeType) nexus_info->region.width*cache_info->number_channels*
+ length=(MagickSizeType) cache_info->number_channels*nexus_info->region.width*
sizeof(Quantum);
+ extent=length*nexus_info->region.height;
rows=nexus_info->region.height;
- extent=length*rows;
+ y=0;
p=nexus_info->pixels;
switch (cache_info->type)
{
for (y=0; y < (ssize_t) rows; y++)
{
(void) memcpy(q,p,(size_t) length);
- p+=nexus_info->region.width*cache_info->number_channels;
+ p+=cache_info->number_channels*nexus_info->region.width;
q+=cache_info->columns*cache_info->number_channels;
}
break;
count=WritePixelCacheRegion(cache_info,cache_info->offset+offset*
cache_info->number_channels*sizeof(*p),length,(const unsigned char *)
p);
- if ((MagickSizeType) count != length)
+ if (count != (MagickOffsetType) length)
break;
- p+=nexus_info->region.width*cache_info->number_channels;
+ p+=cache_info->number_channels*nexus_info->region.width;
offset+=cache_info->columns;
}
if (IsFileDescriptorLimitExceeded() != MagickFalse)
(void) ClosePixelCacheOnDisk(cache_info);
UnlockSemaphoreInfo(cache_info->file_semaphore);
- if (y < (ssize_t) rows)
- {
- ThrowFileException(exception,CacheError,"UnableToWritePixelCache",
- cache_info->cache_filename);
- return(MagickFalse);
- }
break;
}
case DistributedCache:
{
- MagickBooleanType
- status;
+ RectangleInfo
+ region;
/*
Write pixels to distributed cache.
*/
LockSemaphoreInfo(cache_info->file_semaphore);
- status=WriteDistributePixelCachePixels(cache_info->distribute_cache_info,
- &nexus_info->region,length,(const unsigned char *) nexus_info->pixels);
- UnlockSemaphoreInfo(cache_info->file_semaphore);
- if (status == MagickFalse)
+ region=nexus_info->region;
+ if ((cache_info->columns != nexus_info->region.width) ||
+ (extent > MagickMaxBufferExtent))
+ region.height=1UL;
+ else
{
- ThrowFileException(exception,CacheError,"UnableToWritePixelCache",
- GetDistributeCacheHostname(cache_info->distribute_cache_info));
- return(MagickFalse);
+ length=extent;
+ rows=1UL;
}
+ for (y=0; y < (ssize_t) rows; y++)
+ {
+ count=WriteDistributePixelCachePixels((DistributeCacheInfo *)
+ cache_info->server_info,®ion,length,(const unsigned char *) p);
+ if (count != (MagickOffsetType) length)
+ break;
+ p+=cache_info->number_channels*nexus_info->region.width;
+ region.y++;
+ }
+ UnlockSemaphoreInfo(cache_info->file_semaphore);
break;
}
default:
break;
}
+ if (y < (ssize_t) rows)
+ {
+ ThrowFileException(exception,CacheError,"UnableToWritePixelCache",
+ cache_info->cache_filename);
+ return(MagickFalse);
+ }
if ((cache_info->debug != MagickFalse) &&
(CacheTick(nexus_info->region.y,cache_info->rows) != MagickFalse))
(void) LogMagickEvent(CacheEvent,GetMagickModule(),