#include "MagickCore/log.h"
#include "MagickCore/magick.h"
#include "MagickCore/memory_.h"
+#include "MagickCore/nt-base-private.h"
#include "MagickCore/pixel.h"
#include "MagickCore/pixel-accessor.h"
#include "MagickCore/policy.h"
Define declarations.
*/
#define CacheTick(offset,extent) QuantumTick((MagickOffsetType) offset,extent)
+#define IsFileDescriptorLimitExceeded() (GetMagickResource(FileResource) > \
+ GetMagickResourceLimit(FileResource) ? MagickTrue : MagickFalse)
\f
/*
Typedef declarations.
extern "C" {
#endif
+static Cache
+ GetImagePixelCache(Image *,const MagickBooleanType,ExceptionInfo *)
+ magick_hot_spot;
+
static const Quantum
*GetVirtualPixelCache(const Image *,const VirtualPixelMethod,const ssize_t,
const ssize_t,const size_t,const size_t,ExceptionInfo *),
*QueueAuthenticPixelsCache(Image *,const ssize_t,const ssize_t,const size_t,
const size_t,ExceptionInfo *),
*SetPixelCacheNexusPixels(const Image *,const RectangleInfo *,NexusInfo *,
- ExceptionInfo *);
+ ExceptionInfo *) magick_hot_spot;
#if defined(__cplusplus) || defined(c_plusplus)
}
static SemaphoreInfo
*cache_semaphore = (SemaphoreInfo *) NULL;
-
-static SplayTreeInfo
- *cache_resources = (SplayTreeInfo *) NULL;
\f
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
cache_info->disk_semaphore=AllocateSemaphoreInfo();
cache_info->debug=IsEventLogging();
cache_info->signature=MagickSignature;
- if ((cache_resources == (SplayTreeInfo *) NULL) &&
- (instantiate_cache == MagickFalse))
- {
- if (cache_semaphore == (SemaphoreInfo *) NULL)
- AcquireSemaphoreInfo(&cache_semaphore);
- LockSemaphoreInfo(cache_semaphore);
- if ((cache_resources == (SplayTreeInfo *) NULL) &&
- (instantiate_cache == MagickFalse))
- {
- cache_resources=NewSplayTree((int (*)(const void *,const void *))
- NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
- instantiate_cache=MagickTrue;
- }
- UnlockSemaphoreInfo(cache_semaphore);
- }
- (void) AddValueToSplayTree(cache_resources,cache_info,cache_info);
return((Cache ) cache_info);
}
\f
register ssize_t
i;
- nexus_info=(NexusInfo **) AcquireQuantumMemory(number_threads,
+ nexus_info=(NexusInfo **) AcquireAlignedMemory(number_threads,
sizeof(*nexus_info));
if (nexus_info == (NexusInfo **) NULL)
ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
+ nexus_info[0]=(NexusInfo *) AcquireQuantumMemory(number_threads,
+ sizeof(**nexus_info));
+ if (nexus_info[0] == (NexusInfo *) NULL)
+ ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
+ (void) ResetMagickMemory(nexus_info[0],0,number_threads*sizeof(**nexus_info));
for (i=0; i < (ssize_t) number_threads; i++)
{
- nexus_info[i]=(NexusInfo *) AcquireAlignedMemory(1,sizeof(**nexus_info));
- if (nexus_info[i] == (NexusInfo *) NULL)
- ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
- (void) ResetMagickMemory(nexus_info[i],0,sizeof(*nexus_info[i]));
+ nexus_info[i]=(&nexus_info[0][i]);
nexus_info[i]->signature=MagickSignature;
}
return(nexus_info);
if (cache_semaphore == (SemaphoreInfo *) NULL)
AcquireSemaphoreInfo(&cache_semaphore);
LockSemaphoreInfo(cache_semaphore);
- if (cache_resources != (SplayTreeInfo *) NULL)
- cache_resources=DestroySplayTree(cache_resources);
instantiate_cache=MagickFalse;
UnlockSemaphoreInfo(cache_semaphore);
DestroySemaphoreInfo(&cache_semaphore);
% %
% %
% %
-+ C l i p P i x e l C a c h e N e x u s %
-% %
-% %
-% %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% ClipPixelCacheNexus() clips the cache nexus as defined by the image clip
-% mask. It returns MagickTrue if the pixel region is clipped, otherwise
-% MagickFalse.
-%
-% The format of the ClipPixelCacheNexus() method is:
-%
-% MagickBooleanType ClipPixelCacheNexus(Image *image,NexusInfo *nexus_info,
-% ExceptionInfo *exception)
-%
-% A description of each parameter follows:
-%
-% o image: the image.
-%
-% o nexus_info: the cache nexus to clip.
-%
-% o exception: return any errors or warnings in this structure.
-%
-*/
-static MagickBooleanType ClipPixelCacheNexus(Image *image,
- NexusInfo *nexus_info,ExceptionInfo *exception)
-{
- CacheInfo
- *cache_info;
-
- MagickSizeType
- number_pixels;
-
- NexusInfo
- **clip_nexus,
- **image_nexus;
-
- register const Quantum
- *restrict p,
- *restrict r;
-
- register Quantum
- *restrict q;
-
- register ssize_t
- i;
-
- /*
- Apply clip mask.
- */
- if (image->debug != MagickFalse)
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
- if (image->clip_mask == (Image *) NULL)
- return(MagickFalse);
- cache_info=(CacheInfo *) image->cache;
- if (cache_info == (Cache) NULL)
- return(MagickFalse);
- image_nexus=AcquirePixelCacheNexus(1);
- clip_nexus=AcquirePixelCacheNexus(1);
- if ((image_nexus == (NexusInfo **) NULL) ||
- (clip_nexus == (NexusInfo **) NULL))
- ThrowBinaryException(CacheError,"UnableToGetCacheNexus",image->filename);
- p=(const Quantum *) GetAuthenticPixelCacheNexus(image,
- nexus_info->region.x,nexus_info->region.y,nexus_info->region.width,
- nexus_info->region.height,image_nexus[0],exception);
- q=nexus_info->pixels;
- r=GetVirtualPixelsFromNexus(image->clip_mask,MaskVirtualPixelMethod,
- nexus_info->region.x,nexus_info->region.y,nexus_info->region.width,
- nexus_info->region.height,clip_nexus[0],exception);
- number_pixels=(MagickSizeType) nexus_info->region.width*
- nexus_info->region.height;
- for (i=0; i < (ssize_t) number_pixels; i++)
- {
- if ((p == (const Quantum *) NULL) || (r == (const Quantum *) NULL))
- break;
- if (GetPixelIntensity(image,r) > ((Quantum) QuantumRange/2))
- {
- SetPixelRed(image,GetPixelRed(image,p),q);
- SetPixelGreen(image,GetPixelGreen(image,p),q);
- SetPixelBlue(image,GetPixelBlue(image,p),q);
- if (cache_info->colorspace == CMYKColorspace)
- SetPixelBlack(image,GetPixelBlack(image,p),q);
- SetPixelAlpha(image,GetPixelAlpha(image,p),q);
- }
- p+=GetPixelChannels(image);
- q+=GetPixelChannels(image);
- r+=GetPixelChannels(image->clip_mask);
- }
- clip_nexus=DestroyPixelCacheNexus(clip_nexus,1);
- image_nexus=DestroyPixelCacheNexus(image_nexus,1);
- if (i < (ssize_t) number_pixels)
- return(MagickFalse);
- return(MagickTrue);
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% %
-% %
-% %
+ C l o n e P i x e l C a c h e %
% %
% %
return(status == -1 ? MagickFalse : MagickTrue);
}
-static void LimitPixelCacheDescriptors(void)
-{
- register CacheInfo
- *p,
- *q;
-
- /*
- Limit # of open file descriptors.
- */
- if (GetMagickResource(FileResource) < GetMagickResourceLimit(FileResource))
- return;
- LockSemaphoreInfo(cache_semaphore);
- if (cache_resources == (SplayTreeInfo *) NULL)
- {
- UnlockSemaphoreInfo(cache_semaphore);
- return;
- }
- ResetSplayTreeIterator(cache_resources);
- p=(CacheInfo *) GetNextKeyInSplayTree(cache_resources);
- while (p != (CacheInfo *) NULL)
- {
- if ((p->type == DiskCache) && (p->file != -1))
- break;
- p=(CacheInfo *) GetNextKeyInSplayTree(cache_resources);
- }
- for (q=p; p != (CacheInfo *) NULL; )
- {
- if ((p->type == DiskCache) && (p->file != -1) &&
- (p->timestamp < q->timestamp))
- q=p;
- p=(CacheInfo *) GetNextKeyInSplayTree(cache_resources);
- }
- if (q != (CacheInfo *) NULL)
- {
- /*
- Close least recently used cache.
- */
- (void) close(q->file);
- q->file=(-1);
- }
- UnlockSemaphoreInfo(cache_semaphore);
-}
-
static inline MagickSizeType MagickMax(const MagickSizeType x,
const MagickSizeType y)
{
UnlockSemaphoreInfo(cache_info->disk_semaphore);
return(MagickTrue); /* cache already open */
}
- LimitPixelCacheDescriptors();
if (*cache_info->cache_filename == '\0')
file=AcquireUniqueFileResource(cache_info->cache_filename);
else
return((Cache) NULL);
}
UnlockSemaphoreInfo(cache_info->semaphore);
- if (cache_resources != (SplayTreeInfo *) NULL)
- (void) DeleteNodeByValueFromSplayTree(cache_resources,cache_info);
if (cache_info->debug != MagickFalse)
{
char
if (nexus_info[i]->cache != (Quantum *) NULL)
RelinquishCacheNexusPixels(nexus_info[i]);
nexus_info[i]->signature=(~MagickSignature);
- nexus_info[i]=(NexusInfo *) RelinquishAlignedMemory(nexus_info[i]);
}
- nexus_info=(NexusInfo **) RelinquishMagickMemory(nexus_info);
+ nexus_info[0]=(NexusInfo *) RelinquishMagickMemory(nexus_info[0]);
+ nexus_info=(NexusInfo **) RelinquishAlignedMemory(nexus_info);
return(nexus_info);
}
\f
*/
assert(image != (Image *) NULL);
assert(image->signature == MagickSignature);
- q=QueueAuthenticNexus(image,x,y,columns,rows,MagickTrue,nexus_info,exception);
+ q=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickTrue,nexus_info,
+ exception);
if (q == (Quantum *) NULL)
return((Quantum *) NULL);
cache_info=(CacheInfo *) image->cache;
if ((image->storage_class != cache_info->storage_class) ||
(image->colorspace != cache_info->colorspace) ||
(image->matte != cache_info->matte) ||
+ (image->mask != cache_info->mask) ||
(image->columns != cache_info->columns) ||
(image->rows != cache_info->rows) ||
(image->number_channels != cache_info->number_channels) ||
image->taint=MagickTrue;
image->type=UndefinedType;
if (ValidatePixelCacheMorphology(image) == MagickFalse)
- status=OpenPixelCache(image,IOMode,exception);
+ {
+ status=OpenPixelCache(image,IOMode,exception);
+ cache_info=(CacheInfo *) image->cache;
+ if (cache_info->type == DiskCache)
+ (void) ClosePixelCacheOnDisk(cache_info);
+ }
}
UnlockSemaphoreInfo(image->semaphore);
if (status == MagickFalse)
assert(image->cache != (Cache) NULL);
cache_info=(CacheInfo *) image->cache;
assert(cache_info->signature == MagickSignature);
- if (cache_info->methods.get_virtual_metacontent_from_handler !=
- (GetVirtualMetacontentFromHandler) NULL)
- {
- metacontent=cache_info->methods.
- get_virtual_metacontent_from_handler(image);
- return(metacontent);
- }
+ metacontent=cache_info->methods.get_virtual_metacontent_from_handler(image);
+ if (metacontent != (GetVirtualMetacontentFromHandler) NULL)
+ return(metacontent);
assert(id < (int) cache_info->number_threads);
metacontent=GetVirtualMetacontentFromNexus(cache_info,
cache_info->nexus_info[id]);
virtual_pixel);
SetPixelBlue(image,ClampToQuantum(image->background_color.blue),
virtual_pixel);
- if (image->colorspace == CMYKColorspace)
- SetPixelBlack(image,ClampToQuantum(image->background_color.black),
- virtual_pixel);
+ SetPixelBlack(image,ClampToQuantum(image->background_color.black),
+ virtual_pixel);
SetPixelAlpha(image,ClampToQuantum(image->background_color.alpha),
virtual_pixel);
break;
% %
% %
% %
-+ M a s k P i x e l C a c h e N e x u s %
-% %
-% %
-% %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% MaskPixelCacheNexus() masks the cache nexus as defined by the image mask.
-% The method returns MagickTrue if the pixel region is masked, otherwise
-% MagickFalse.
-%
-% The format of the MaskPixelCacheNexus() method is:
-%
-% MagickBooleanType MaskPixelCacheNexus(Image *image,
-% NexusInfo *nexus_info,ExceptionInfo *exception)
-%
-% A description of each parameter follows:
-%
-% o image: the image.
-%
-% o nexus_info: the cache nexus to clip.
-%
-% o exception: return any errors or warnings in this structure.
-%
-*/
-
-static inline void MaskPixelOver(const PixelInfo *p,const MagickRealType alpha,
- const PixelInfo *q,const MagickRealType beta,PixelInfo *composite)
-{
- MagickRealType
- gamma;
-
- if (fabs(alpha-TransparentAlpha) < MagickEpsilon)
- {
- *composite=(*q);
- return;
- }
- gamma=1.0-QuantumScale*QuantumScale*alpha*beta;
- gamma=1.0/(gamma <= MagickEpsilon ? 1.0 : gamma);
- composite->red=gamma*MagickOver_(p->red,alpha,q->red,beta);
- composite->green=gamma*MagickOver_(p->green,alpha,q->green,beta);
- composite->blue=gamma*MagickOver_(p->blue,alpha,q->blue,beta);
- if ((p->colorspace == CMYKColorspace) && (q->colorspace == CMYKColorspace))
- composite->black=gamma*MagickOver_(p->black,alpha,q->black,beta);
-}
-
-static MagickBooleanType MaskPixelCacheNexus(Image *image,NexusInfo *nexus_info,
- ExceptionInfo *exception)
-{
- CacheInfo
- *cache_info;
-
- PixelInfo
- alpha,
- beta;
-
- MagickSizeType
- number_pixels;
-
- NexusInfo
- **clip_nexus,
- **image_nexus;
-
- register const Quantum
- *restrict p,
- *restrict r;
-
- register Quantum
- *restrict q;
-
- register ssize_t
- i;
-
- /*
- Apply clip mask.
- */
- if (image->debug != MagickFalse)
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
- if (image->mask == (Image *) NULL)
- return(MagickFalse);
- cache_info=(CacheInfo *) image->cache;
- if (cache_info == (Cache) NULL)
- return(MagickFalse);
- image_nexus=AcquirePixelCacheNexus(1);
- clip_nexus=AcquirePixelCacheNexus(1);
- if ((image_nexus == (NexusInfo **) NULL) ||
- (clip_nexus == (NexusInfo **) NULL))
- ThrowBinaryException(CacheError,"UnableToGetCacheNexus",image->filename);
- p=(const Quantum *) GetAuthenticPixelCacheNexus(image,
- nexus_info->region.x,nexus_info->region.y,nexus_info->region.width,
- nexus_info->region.height,image_nexus[0],exception);
- q=nexus_info->pixels;
- r=GetVirtualPixelsFromNexus(image->mask,MaskVirtualPixelMethod,
- nexus_info->region.x,nexus_info->region.y,nexus_info->region.width,
- nexus_info->region.height,clip_nexus[0],exception);
- GetPixelInfo(image,&alpha);
- GetPixelInfo(image,&beta);
- number_pixels=(MagickSizeType) nexus_info->region.width*
- nexus_info->region.height;
- for (i=0; i < (ssize_t) number_pixels; i++)
- {
- if ((p == (const Quantum *) NULL) || (r == (const Quantum *) NULL))
- break;
- GetPixelInfoPixel(image,p,&alpha);
- GetPixelInfoPixel(image,q,&beta);
- MaskPixelOver(&beta,(MagickRealType) GetPixelIntensity(image,r),
- &alpha,alpha.alpha,&beta);
- SetPixelRed(image,ClampToQuantum(beta.red),q);
- SetPixelGreen(image,ClampToQuantum(beta.green),q);
- SetPixelBlue(image,ClampToQuantum(beta.blue),q);
- if (cache_info->colorspace == CMYKColorspace)
- SetPixelBlack(image,ClampToQuantum(beta.black),q);
- SetPixelAlpha(image,ClampToQuantum(beta.alpha),q);
- p++;
- q++;
- r++;
- }
- clip_nexus=DestroyPixelCacheNexus(clip_nexus,1);
- image_nexus=DestroyPixelCacheNexus(image_nexus,1);
- if (i < (ssize_t) number_pixels)
- return(MagickFalse);
- return(MagickTrue);
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% %
-% %
-% %
+ O p e n P i x e l C a c h e %
% %
% %
length,
number_pixels;
- PixelChannelMap
- *p,
- *q;
-
size_t
columns,
packet_size;
cache_info->storage_class=image->storage_class;
cache_info->colorspace=image->colorspace;
cache_info->matte=image->matte;
+ cache_info->mask=image->mask;
cache_info->rows=image->rows;
cache_info->columns=image->columns;
InitializePixelChannelMap(image);
ThrowBinaryException(ResourceLimitError,"PixelCacheAllocationFailed",
image->filename);
cache_info->length=length;
- p=cache_info->channel_map;
- q=source_info.channel_map;
- if ((cache_info->type != UndefinedCache) &&
- (cache_info->columns <= source_info.columns) &&
- (cache_info->rows <= source_info.rows) &&
- (cache_info->number_channels <= source_info.number_channels) &&
- (memcmp(p,q,cache_info->number_channels*sizeof(*p)) == 0) &&
- (cache_info->metacontent_extent <= source_info.metacontent_extent))
- {
- /*
- Inline pixel cache clone optimization.
- */
- if ((cache_info->columns == source_info.columns) &&
- (cache_info->rows == source_info.rows) &&
- (cache_info->number_channels == source_info.number_channels) &&
- (memcmp(p,q,cache_info->number_channels*sizeof(*p)) == 0) &&
- (cache_info->metacontent_extent == source_info.metacontent_extent))
- return(MagickTrue);
- return(ClonePixelCachePixels(cache_info,&source_info,exception));
- }
status=AcquireMagickResource(AreaResource,cache_info->length);
length=number_pixels*(cache_info->number_channels*sizeof(Quantum)+
cache_info->metacontent_extent);
% %
% %
% %
-+ Q u e u e A u t h e n t i c N e x u s %
++ Q u e u e A u t h e n t i c P i x e l C a c h e N e x u s %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% QueueAuthenticNexus() allocates an region to store image pixels as defined
-% by the region rectangle and returns a pointer to the region. This region is
-% subsequently transferred from the pixel cache with
+% QueueAuthenticPixelCacheNexus() allocates an region to store image pixels as
+% defined by the region rectangle and returns a pointer to the region. This
+% region is subsequently transferred from the pixel cache with
% SyncAuthenticPixelsCache(). A pointer to the pixels is returned if the
% pixels are transferred, otherwise a NULL is returned.
%
-% The format of the QueueAuthenticNexus() method is:
+% The format of the QueueAuthenticPixelCacheNexus() method is:
%
-% Quantum *QueueAuthenticNexus(Image *image,const ssize_t x,
+% Quantum *QueueAuthenticPixelCacheNexus(Image *image,const ssize_t x,
% const ssize_t y,const size_t columns,const size_t rows,
% const MagickBooleanType clone,NexusInfo *nexus_info,
% ExceptionInfo *exception)
% o exception: return any errors or warnings in this structure.
%
*/
-MagickPrivate Quantum *QueueAuthenticNexus(Image *image,const ssize_t x,
- const ssize_t y,const size_t columns,const size_t rows,
+MagickPrivate Quantum *QueueAuthenticPixelCacheNexus(Image *image,
+ const ssize_t x,const ssize_t y,const size_t columns,const size_t rows,
const MagickBooleanType clone,NexusInfo *nexus_info,ExceptionInfo *exception)
{
CacheInfo
cache_info=(CacheInfo *) image->cache;
assert(cache_info->signature == MagickSignature);
assert(id < (int) cache_info->number_threads);
- q=QueueAuthenticNexus(image,x,y,columns,rows,MagickFalse,
+ q=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickFalse,
cache_info->nexus_info[id],exception);
return(q);
}
cache_info=(CacheInfo *) image->cache;
assert(cache_info->signature == MagickSignature);
if (cache_info->methods.queue_authentic_pixels_handler !=
- (QueueAuthenticPixelsHandler) NULL)
+ (QueueAuthenticPixelsHandler) NULL)
{
- q=cache_info->methods.queue_authentic_pixels_handler(image,x,y,
- columns,rows,exception);
+ q=cache_info->methods.queue_authentic_pixels_handler(image,x,y,columns,
+ rows,exception);
return(q);
}
assert(id < (int) cache_info->number_threads);
- q=QueueAuthenticNexus(image,x,y,columns,rows,MagickFalse,
+ q=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickFalse,
cache_info->nexus_info[id],exception);
return(q);
}
offset+=cache_info->columns;
q+=cache_info->metacontent_extent*nexus_info->region.width;
}
+ if (IsFileDescriptorLimitExceeded() != MagickFalse)
+ (void) ClosePixelCacheOnDisk(cache_info);
if (y < (ssize_t) rows)
{
ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
offset+=cache_info->columns;
q+=cache_info->number_channels*nexus_info->region.width;
}
+ if (IsFileDescriptorLimitExceeded() != MagickFalse)
+ (void) ClosePixelCacheOnDisk(cache_info);
if (y < (ssize_t) rows)
{
ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
if (nexus_info->length != (MagickSizeType) ((size_t) nexus_info->length))
return(MagickFalse);
nexus_info->mapped=MagickFalse;
- nexus_info->cache=(Quantum *) AcquireQuantumMemory(1,(size_t)
+ nexus_info->cache=(Quantum *) AcquireMagickMemory((size_t)
nexus_info->length);
if (nexus_info->cache == (Quantum *) NULL)
{
if (cache_info->type == UndefinedCache)
return((Quantum *) NULL);
nexus_info->region=(*region);
- if ((cache_info->type != DiskCache) && (cache_info->type != PingCache) &&
- (image->clip_mask == (Image *) NULL) && (image->mask == (Image *) NULL))
+ if ((cache_info->type != DiskCache) && (cache_info->type != PingCache))
{
ssize_t
x,
%
% The format of the SetPixelCacheVirtualMethod() method is:
%
-% VirtualPixelMethod SetPixelCacheVirtualMethod(const Image *image,
-% const VirtualPixelMethod virtual_pixel_method)
+% VirtualPixelMethod SetPixelCacheVirtualMethod(Image *image,
+% const VirtualPixelMethod virtual_pixel_method,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
%
% o virtual_pixel_method: choose the type of virtual pixel.
%
+% o exception: return any errors or warnings in this structure.
+%
*/
-MagickPrivate VirtualPixelMethod SetPixelCacheVirtualMethod(const Image *image,
- const VirtualPixelMethod virtual_pixel_method)
+
+static MagickBooleanType SetCacheAlphaChannel(Image *image,const Quantum alpha,
+ ExceptionInfo *exception)
+{
+ CacheView
+ *image_view;
+
+ CacheInfo
+ *cache_info;
+
+ MagickBooleanType
+ status;
+
+ ssize_t
+ y;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (image->debug != MagickFalse)
+ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
+ assert(image->cache != (Cache) NULL);
+ cache_info=(CacheInfo *) image->cache;
+ assert(cache_info->signature == MagickSignature);
+ image->matte=MagickTrue;
+ status=MagickTrue;
+ image_view=AcquireCacheView(image);
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+ #pragma omp parallel for schedule(static,4) shared(status)
+#endif
+ for (y=0; y < (ssize_t) image->rows; y++)
+ {
+ register Quantum
+ *restrict q;
+
+ register ssize_t
+ x;
+
+ if (status == MagickFalse)
+ continue;
+ q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
+ if (q == (Quantum *) NULL)
+ {
+ status=MagickFalse;
+ continue;
+ }
+ for (x=0; x < (ssize_t) image->columns; x++)
+ {
+ SetPixelAlpha(image,alpha,q);
+ q+=GetPixelChannels(image);
+ }
+ status=SyncCacheViewAuthenticPixels(image_view,exception);
+ }
+ image_view=DestroyCacheView(image_view);
+ return(status);
+}
+
+MagickPrivate VirtualPixelMethod SetPixelCacheVirtualMethod(Image *image,
+ const VirtualPixelMethod virtual_pixel_method,ExceptionInfo *exception)
{
CacheInfo
*cache_info;
assert(cache_info->signature == MagickSignature);
method=cache_info->virtual_pixel_method;
cache_info->virtual_pixel_method=virtual_pixel_method;
+ switch (virtual_pixel_method)
+ {
+ case BackgroundVirtualPixelMethod:
+ {
+ if ((image->background_color.matte != MagickFalse) &&
+ (image->matte == MagickFalse))
+ (void) SetCacheAlphaChannel(image,OpaqueAlpha,exception);
+ break;
+ }
+ case TransparentVirtualPixelMethod:
+ {
+ if (image->matte == MagickFalse)
+ (void) SetCacheAlphaChannel(image,OpaqueAlpha,exception);
+ break;
+ }
+ default:
+ break;
+ }
return(method);
}
\f
assert(cache_info->signature == MagickSignature);
if (cache_info->type == UndefinedCache)
return(MagickFalse);
- if ((image->clip_mask != (Image *) NULL) &&
- (ClipPixelCacheNexus(image,nexus_info,exception) == MagickFalse))
- return(MagickFalse);
- if ((image->mask != (Image *) NULL) &&
- (MaskPixelCacheNexus(image,nexus_info,exception) == MagickFalse))
- return(MagickFalse);
if (IsPixelAuthentic(cache_info,nexus_info) != MagickFalse)
return(MagickTrue);
assert(cache_info->signature == MagickSignature);
p+=nexus_info->region.width*cache_info->metacontent_extent;
offset+=cache_info->columns;
}
+ if (IsFileDescriptorLimitExceeded() != MagickFalse)
+ (void) ClosePixelCacheOnDisk(cache_info);
if (y < (ssize_t) rows)
{
ThrowFileException(exception,CacheError,"UnableToWritePixelCache",
p+=nexus_info->region.width*cache_info->number_channels;
offset+=cache_info->columns;
}
+ if (IsFileDescriptorLimitExceeded() != MagickFalse)
+ (void) ClosePixelCacheOnDisk(cache_info);
if (y < (ssize_t) rows)
{
ThrowFileException(exception,CacheError,"UnableToWritePixelCache",