% October 2002 %
% %
% %
-% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2012 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 %
#include "MagickCore/colormap.h"
#include "MagickCore/colormap-private.h"
#include "MagickCore/colorspace.h"
+#include "MagickCore/colorspace-private.h"
#include "MagickCore/composite.h"
#include "MagickCore/composite-private.h"
#include "MagickCore/constitute.h"
image_view=DestroyCacheView(image_view);
return(bounds);
}
- SetPixelInfo(image,p,&target[0]);
+ GetPixelInfoPixel(image,p,&target[0]);
GetPixelInfo(image,&target[1]);
p=GetCacheViewVirtualPixels(image_view,(ssize_t) image->columns-1,0,1,1,
exception);
- SetPixelInfo(image,p,&target[1]);
+ GetPixelInfoPixel(image,p,&target[1]);
GetPixelInfo(image,&target[2]);
p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) image->rows-1,1,1,
exception);
- SetPixelInfo(image,p,&target[2]);
+ GetPixelInfoPixel(image,p,&target[2]);
status=MagickTrue;
GetPixelInfo(image,&zero);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(status)
+ #pragma omp parallel for schedule(static,4) shared(status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
pixel=zero;
for (x=0; x < (ssize_t) image->columns; x++)
{
- SetPixelInfo(image,p,&pixel);
+ GetPixelInfoPixel(image,p,&pixel);
if ((x < bounding_box.x) &&
(IsFuzzyEquivalencePixelInfo(&pixel,&target[0]) == MagickFalse))
bounding_box.x=x;
% o exception: return any errors or warnings in this structure.
%
*/
-MagickExport size_t GetImageDepth(const Image *image,
- ExceptionInfo *exception)
+MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
{
CacheView
*image_view;
current_depth[id]=1;
if ((image->storage_class == PseudoClass) && (image->matte == MagickFalse))
{
- register const PixelPacket
- *restrict p;
-
register ssize_t
i;
- p=image->colormap;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(status)
+ #pragma omp parallel for schedule(static) shared(status)
#endif
for (i=0; i < (ssize_t) image->colors; i++)
{
status=0;
range=GetQuantumRange(current_depth[id]);
- if ((GetPixelRedTraits(image) & ActivePixelTrait) != 0)
- status|=p->red != ScaleAnyToQuantum(ScaleQuantumToAny(p->red,
- range),range);
- if ((GetPixelGreenTraits(image) & ActivePixelTrait) != 0)
- status|=p->green != ScaleAnyToQuantum(ScaleQuantumToAny(p->green,
- range),range);
- if ((GetPixelBlueTraits(image) & ActivePixelTrait) != 0)
- status|=p->blue != ScaleAnyToQuantum(ScaleQuantumToAny(p->blue,
- range),range);
+ if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
+ status|=ClampToQuantum(image->colormap[i].red) !=
+ ScaleAnyToQuantum(ScaleQuantumToAny(ClampToQuantum(
+ image->colormap[i].red),range),range);
+ if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
+ status|=ClampToQuantum(image->colormap[i].green) !=
+ ScaleAnyToQuantum(ScaleQuantumToAny(ClampToQuantum(
+ image->colormap[i].green),range),range);
+ if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
+ status|=ClampToQuantum(image->colormap[i].blue) !=
+ ScaleAnyToQuantum(ScaleQuantumToAny(ClampToQuantum(
+ image->colormap[i].blue),range),range);
if (status == 0)
break;
current_depth[id]++;
}
- p++;
}
depth=current_depth[0];
for (id=1; id < (ssize_t) number_threads; id++)
return(depth);
}
image_view=AcquireCacheView(image);
+#if !defined(MAGICKCORE_HDRI_SUPPORT)
+ if (QuantumRange <= MaxMap)
+ {
+ register ssize_t
+ i;
+
+ size_t
+ *depth_map;
+
+ /*
+ Scale pixels to desired (optimized with depth map).
+ */
+ depth_map=(size_t *) AcquireQuantumMemory(MaxMap+1,sizeof(*depth_map));
+ if (depth_map == (size_t *) NULL)
+ ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
+ for (i=0; i <= (ssize_t) MaxMap; i++)
+ {
+ unsigned int
+ depth;
+
+ for (depth=1; depth < MAGICKCORE_QUANTUM_DEPTH; depth++)
+ {
+ Quantum
+ pixel;
+
+ QuantumAny
+ range;
+
+ range=GetQuantumRange(depth);
+ pixel=(Quantum) i;
+ if (pixel == ScaleAnyToQuantum(ScaleQuantumToAny(pixel,range),range))
+ break;
+ }
+ depth_map[i]=depth;
+ }
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+ #pragma omp parallel for schedule(static,4) shared(status)
+#endif
+ for (y=0; y < (ssize_t) image->rows; y++)
+ {
+ const int
+ id = GetOpenMPThreadId();
+
+ register const Quantum
+ *restrict p;
+
+ register ssize_t
+ x;
+
+ if (status == MagickFalse)
+ continue;
+ p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
+ if (p == (const Quantum *) NULL)
+ continue;
+ for (x=0; x < (ssize_t) image->columns; x++)
+ {
+ register ssize_t
+ i;
+
+ if (GetPixelMask(image,p) != 0)
+ {
+ p+=GetPixelChannels(image);
+ continue;
+ }
+ for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+ {
+ PixelChannel
+ channel;
+
+ PixelTrait
+ traits;
+
+ channel=GetPixelChannelMapChannel(image,i);
+ traits=GetPixelChannelMapTraits(image,channel);
+ if ((traits == UndefinedPixelTrait) ||
+ (channel == IndexPixelChannel) || (channel == MaskPixelChannel))
+ continue;
+ if (depth_map[ScaleQuantumToMap(p[i])] > current_depth[id])
+ current_depth[id]=depth_map[ScaleQuantumToMap(p[i])];
+ }
+ p+=GetPixelChannels(image);
+ }
+ if (current_depth[id] == MAGICKCORE_QUANTUM_DEPTH)
+ status=MagickFalse;
+ }
+ image_view=DestroyCacheView(image_view);
+ depth=current_depth[0];
+ for (id=1; id < (ssize_t) number_threads; id++)
+ if (depth < current_depth[id])
+ depth=current_depth[id];
+ depth_map=(size_t *) RelinquishMagickMemory(depth_map);
+ current_depth=(size_t *) RelinquishMagickMemory(current_depth);
+ return(depth);
+ }
+#endif
+ /*
+ Compute pixel depth.
+ */
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(status)
+ #pragma omp parallel for schedule(static,4) shared(status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
continue;
for (x=0; x < (ssize_t) image->columns; x++)
{
- while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
+ register ssize_t
+ i;
+
+ if (GetPixelMask(image,p) != 0)
+ {
+ p+=GetPixelChannels(image);
+ continue;
+ }
+ for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
- MagickStatusType
- status;
-
- QuantumAny
- range;
-
- status=0;
- range=GetQuantumRange(current_depth[id]);
- if ((GetPixelRedTraits(image) & ActivePixelTrait) != 0)
- status|=GetPixelRed(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
- GetPixelRed(image,p),range),range);
- if ((GetPixelGreenTraits(image) & ActivePixelTrait) != 0)
- status|=GetPixelGreen(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
- GetPixelGreen(image,p),range),range);
- if ((GetPixelBlueTraits(image) & ActivePixelTrait) != 0)
- status|=GetPixelBlue(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
- GetPixelBlue(image,p),range),range);
- if (((GetPixelAlphaTraits(image) & ActivePixelTrait) != 0) &&
- (image->matte != MagickFalse))
- status|=GetPixelAlpha(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
- GetPixelAlpha(image,p),range),range);
- if (((GetPixelBlackTraits(image) & ActivePixelTrait) != 0) &&
- (image->colorspace == CMYKColorspace))
- status|=GetPixelBlack(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
- GetPixelBlack(image,p),range),range);
- if (status == 0)
- break;
- current_depth[id]++;
+ PixelChannel
+ channel;
+
+ PixelTrait
+ traits;
+
+ channel=GetPixelChannelMapChannel(image,i);
+ traits=GetPixelChannelMapTraits(image,channel);
+ if ((traits == UndefinedPixelTrait) || (channel == IndexPixelChannel) ||
+ (channel == MaskPixelChannel))
+ continue;
+ while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
+ {
+ QuantumAny
+ range;
+
+ range=GetQuantumRange(current_depth[id]);
+ if (p[i] == ScaleAnyToQuantum(ScaleQuantumToAny(p[i],range),range))
+ break;
+ current_depth[id]++;
+ }
}
p+=GetPixelChannels(image);
}
if (depth <= 64)
depth=64;
if (constrain != MagickFalse)
- depth=(size_t) MagickMin((double) depth,(double)
- MAGICKCORE_QUANTUM_DEPTH);
+ depth=(size_t) MagickMin((double) depth,(double) MAGICKCORE_QUANTUM_DEPTH);
return(depth);
}
\f
if ((image->type == BilevelType) || (image->type == GrayscaleType) ||
(image->type == GrayscaleMatteType))
return(MagickTrue);
- if (image->colorspace == CMYKColorspace)
+ if (IsRGBColorspace(image->colorspace) == MagickFalse)
return(MagickFalse);
type=BilevelType;
image_view=AcquireCacheView(image);
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (image->type == BilevelType)
return(MagickTrue);
- if (image->colorspace == CMYKColorspace)
+ if (IsRGBColorspace(image->colorspace) == MagickFalse)
return(MagickFalse);
type=BilevelType;
image_view=AcquireCacheView(image);
%
% The format of the SetImageDepth method is:
%
-% MagickBooleanType SetImageDepth(Image *image,const size_t depth)
-% MagickBooleanType SetImageDepth(Image *image,
-% const ChannelType channel,const size_t depth)
+% MagickBooleanType SetImageDepth(Image *image,const size_t depth,
+% ExceptionInfo *exception)
%
% A description of each parameter follows:
%
%
% o depth: the image depth.
%
+% o exception: return any errors or warnings in this structure.
+%
*/
MagickExport MagickBooleanType SetImageDepth(Image *image,
- const size_t depth)
+ const size_t depth,ExceptionInfo *exception)
{
CacheView
*image_view;
- ExceptionInfo
- *exception;
-
MagickBooleanType
status;
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
assert(image->signature == MagickSignature);
- if (GetImageDepth(image,&image->exception) <= (size_t)
- MagickMin((double) depth,(double) MAGICKCORE_QUANTUM_DEPTH))
+ if (depth >= MAGICKCORE_QUANTUM_DEPTH)
{
- image->depth=depth;
+ image->depth=MAGICKCORE_QUANTUM_DEPTH;
return(MagickTrue);
}
+ range=GetQuantumRange(depth);
+ if (image->storage_class == PseudoClass)
+ {
+ register ssize_t
+ i;
+
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+ #pragma omp parallel for schedule(static) shared(status)
+#endif
+ for (i=0; i < (ssize_t) image->colors; i++)
+ {
+ if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
+ image->colormap[i].red=(double) ScaleAnyToQuantum(ScaleQuantumToAny(
+ ClampToQuantum(image->colormap[i].red),range),range);
+ if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
+ image->colormap[i].green=(double) ScaleAnyToQuantum(ScaleQuantumToAny( ClampToQuantum(image->colormap[i].green),range),range);
+ if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
+ image->colormap[i].blue=(double) ScaleAnyToQuantum(ScaleQuantumToAny(
+ ClampToQuantum(image->colormap[i].blue),range),range);
+ if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
+ image->colormap[i].alpha=(double) ScaleAnyToQuantum(ScaleQuantumToAny(
+ ClampToQuantum(image->colormap[i].alpha),range),range);
+ }
+ status=SyncImage(image,exception);
+ if (status != MagickFalse)
+ image->depth=depth;
+ return(status);
+ }
+ status=MagickTrue;
+ image_view=AcquireCacheView(image);
+#if !defined(MAGICKCORE_HDRI_SUPPORT)
+ if (QuantumRange <= MaxMap)
+ {
+ Quantum
+ *depth_map;
+
+ register ssize_t
+ i;
+
+ /*
+ Scale pixels to desired (optimized with depth map).
+ */
+ depth_map=(Quantum *) AcquireQuantumMemory(MaxMap+1,sizeof(*depth_map));
+ if (depth_map == (Quantum *) NULL)
+ ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
+ for (i=0; i <= (ssize_t) MaxMap; i++)
+ depth_map[i]=ScaleAnyToQuantum(ScaleQuantumToAny((Quantum) i,range),
+ range);
+#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 ssize_t
+ x;
+
+ register Quantum
+ *restrict q;
+
+ 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++)
+ {
+ register ssize_t
+ i;
+
+ if (GetPixelMask(image,q) != 0)
+ {
+ q+=GetPixelChannels(image);
+ continue;
+ }
+ for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+ {
+ PixelChannel
+ channel;
+
+ PixelTrait
+ traits;
+
+ channel=GetPixelChannelMapChannel(image,i);
+ traits=GetPixelChannelMapTraits(image,channel);
+ if ((traits == UndefinedPixelTrait) ||
+ (channel == IndexPixelChannel) || (channel == MaskPixelChannel))
+ continue;
+ q[i]=depth_map[ScaleQuantumToMap(q[i])];
+ }
+ q+=GetPixelChannels(image);
+ }
+ if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
+ {
+ status=MagickFalse;
+ continue;
+ }
+ }
+ image_view=DestroyCacheView(image_view);
+ depth_map=(Quantum *) RelinquishMagickMemory(depth_map);
+ if (status != MagickFalse)
+ image->depth=depth;
+ return(status);
+ }
+#endif
/*
Scale pixels to desired depth.
*/
- status=MagickTrue;
- range=GetQuantumRange(depth);
- exception=(&image->exception);
- image_view=AcquireCacheView(image);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(status)
+ #pragma omp parallel for schedule(static,4) shared(status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
if (status == MagickFalse)
continue;
- q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
- exception);
- if (q == (const Quantum *) NULL)
+ 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++)
{
- if ((GetPixelRedTraits(image) & ActivePixelTrait) != 0)
- SetPixelRed(image,ScaleAnyToQuantum(ScaleQuantumToAny(
- GetPixelRed(image,q),range),range),q);
- if ((GetPixelGreenTraits(image) & ActivePixelTrait) != 0)
- SetPixelGreen(image,ScaleAnyToQuantum(ScaleQuantumToAny(
- GetPixelGreen(image,q),range),range),q);
- if ((GetPixelBlueTraits(image) & ActivePixelTrait) != 0)
- SetPixelBlue(image,ScaleAnyToQuantum(ScaleQuantumToAny(
- GetPixelBlue(image,q),range),range),q);
- if (((GetPixelBlackTraits(image) & ActivePixelTrait) != 0) &&
- (image->colorspace == CMYKColorspace))
- SetPixelBlack(image,ScaleAnyToQuantum(ScaleQuantumToAny(
- GetPixelBlack(image,q),range),range),q);
- if (((GetPixelAlphaTraits(image) & ActivePixelTrait) != 0) &&
- (image->matte != MagickFalse))
- SetPixelAlpha(image,ScaleAnyToQuantum(ScaleQuantumToAny(
- GetPixelAlpha(image,q),range),range),q);
+ register ssize_t
+ i;
+
+ if (GetPixelMask(image,q) != 0)
+ {
+ q+=GetPixelChannels(image);
+ continue;
+ }
+ for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+ {
+ PixelChannel
+ channel;
+
+ PixelTrait
+ traits;
+
+ channel=GetPixelChannelMapChannel(image,i);
+ traits=GetPixelChannelMapTraits(image,channel);
+ if ((traits == UndefinedPixelTrait) || (channel == IndexPixelChannel) ||
+ (channel == MaskPixelChannel))
+ continue;
+ q[i]=ScaleAnyToQuantum(ScaleQuantumToAny(q[i],range),range);
+ }
q+=GetPixelChannels(image);
}
if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
}
}
image_view=DestroyCacheView(image_view);
- if (image->storage_class == PseudoClass)
- {
- register ssize_t
- i;
-
- register PixelPacket
- *restrict p;
-
- p=image->colormap;
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(status)
-#endif
- for (i=0; i < (ssize_t) image->colors; i++)
- {
- if ((GetPixelRedTraits(image) & ActivePixelTrait) != 0)
- p->red=ScaleAnyToQuantum(ScaleQuantumToAny(p->red,range),range);
- if ((GetPixelGreenTraits(image) & ActivePixelTrait) != 0)
- p->green=ScaleAnyToQuantum(ScaleQuantumToAny(p->green,range),range);
- if ((GetPixelBlueTraits(image) & ActivePixelTrait) != 0)
- p->blue=ScaleAnyToQuantum(ScaleQuantumToAny(p->blue,range),range);
- if ((GetPixelAlphaTraits(image) & ActivePixelTrait) != 0)
- p->alpha=ScaleAnyToQuantum(ScaleQuantumToAny(p->alpha,range),range);
- p++;
- }
- }
- image->depth=depth;
+ if (status != MagickFalse)
+ image->depth=depth;
return(status);
}