%
% The format of the AcquirePixelChannelMap() method is:
%
-% PixelChannelMap **AcquirePixelChannelMap(void)
+% PixelChannelMap *AcquirePixelChannelMap(void)
%
*/
-MagickExport PixelChannelMap **AcquirePixelChannelMap(void)
+MagickExport PixelChannelMap *AcquirePixelChannelMap(void)
{
PixelChannelMap
- **channel_map;
+ *channel_map;
register ssize_t
i;
- channel_map=(PixelChannelMap **) AcquireAlignedMemory(MaxPixelChannelMaps,
- sizeof(**channel_map));
- if (channel_map == (PixelChannelMap **) NULL)
+ channel_map=(PixelChannelMap *) AcquireQuantumMemory(MaxPixelChannels,
+ sizeof(*channel_map));
+ if (channel_map == (PixelChannelMap *) NULL)
ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
- for (i=0; i < MaxPixelChannelMaps; i++)
- {
- register ssize_t
- j;
-
- channel_map[i]=(PixelChannelMap *) AcquireQuantumMemory(MaxPixelChannels,
- sizeof(*channel_map[i]));
- if (channel_map[i] == (PixelChannelMap *) NULL)
- ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
- (void) ResetMagickMemory(channel_map[i],0,MaxPixelChannels*
- sizeof(*channel_map[i]));
- for (j=0; j < MaxPixelChannels; j++)
- channel_map[i][j].channel=(PixelChannel) j;
- }
+ (void) ResetMagickMemory(channel_map,0,MaxPixelChannels*sizeof(*channel_map));
+ for (i=0; i < MaxPixelChannels; i++)
+ channel_map[i].channel=(PixelChannel) i;
return(channel_map);
}
\f
%
% The format of the ClonePixelChannelMap() method is:
%
-% PixelChannelMap **ClonePixelChannelMap(
-% PixelChannelMap **channel_map)
+% PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
%
% A description of each parameter follows:
%
% o channel_map: the pixel component map.
%
*/
-MagickExport PixelChannelMap **ClonePixelChannelMap(
- PixelChannelMap **channel_map)
+MagickExport PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
{
PixelChannelMap
- **clone_map;
-
- register ssize_t
- i;
+ *clone_map;
- assert(channel_map != (PixelChannelMap **) NULL);
+ assert(channel_map != (PixelChannelMap *) NULL);
clone_map=AcquirePixelChannelMap();
- if (clone_map == (PixelChannelMap **) NULL)
- return((PixelChannelMap **) NULL);
- for (i=0; i < MaxPixelChannelMaps; i++)
- (void) CopyMagickMemory(clone_map[i],channel_map[i],MaxPixelChannels*
- sizeof(*channel_map[i]));
+ if (clone_map == (PixelChannelMap *) NULL)
+ return((PixelChannelMap *) NULL);
+ (void) CopyMagickMemory(clone_map,channel_map,MaxPixelChannels*
+ sizeof(*channel_map));
return(clone_map);
}
\f
%
% The format of the DestroyPixelChannelMap() method is:
%
-% PixelChannelMap **DestroyPixelChannelMap(PixelChannelMap **channel_map)
+% PixelChannelMap *DestroyPixelChannelMap(PixelChannelMap *channel_map)
%
% A description of each parameter follows:
%
% o channel_map: the pixel component map.
%
*/
-MagickExport PixelChannelMap **DestroyPixelChannelMap(
- PixelChannelMap **channel_map)
+MagickExport PixelChannelMap *DestroyPixelChannelMap(
+ PixelChannelMap *channel_map)
{
- register ssize_t
- i;
-
- assert(channel_map != (PixelChannelMap **) NULL);
- for (i=0; i < MaxPixelChannelMaps; i++)
- channel_map[i]=(PixelChannelMap *) RelinquishMagickMemory(channel_map[i]);
- return((PixelChannelMap **) RelinquishMagickMemory(channel_map));
+ assert(channel_map != (PixelChannelMap *) NULL);
+ channel_map=(PixelChannelMap *) RelinquishMagickMemory(channel_map);
+ return((PixelChannelMap *) RelinquishMagickMemory(channel_map));
}
\f
/*
% MagickBooleanType ImportImagePixels(Image *image,const ssize_t x_offset,
% const ssize_t y_offset,const size_t columns,
% const size_t rows,const char *map,const StorageType type,
-% const void *pixels)
+% const void *pixels,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% map and type. You must preallocate this array where the expected
% length varies depending on the values of width, height, map, and type.
%
+% o exception: return any errors or warnings in this structure.
+%
*/
MagickExport MagickBooleanType ImportImagePixels(Image *image,
const ssize_t x_offset,const ssize_t y_offset,const size_t columns,
const size_t rows,const char *map,const StorageType type,
- const void *pixels)
+ const void *pixels,ExceptionInfo *exception)
{
- ExceptionInfo
- *exception;
-
QuantumType
*quantum_map;
case 'c':
{
quantum_map[i]=CyanQuantum;
- (void) SetImageColorspace(image,CMYKColorspace);
+ (void) SetImageColorspace(image,CMYKColorspace,exception);
break;
}
case 'g':
case 'k':
{
quantum_map[i]=BlackQuantum;
- (void) SetImageColorspace(image,CMYKColorspace);
+ (void) SetImageColorspace(image,CMYKColorspace,exception);
break;
}
case 'I':
case 'M':
{
quantum_map[i]=MagentaQuantum;
- (void) SetImageColorspace(image,CMYKColorspace);
+ (void) SetImageColorspace(image,CMYKColorspace,exception);
break;
}
case 'O':
case 'y':
{
quantum_map[i]=YellowQuantum;
- (void) SetImageColorspace(image,CMYKColorspace);
+ (void) SetImageColorspace(image,CMYKColorspace,exception);
break;
}
default:
{
quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
- (void) ThrowMagickException(&image->exception,GetMagickModule(),
- OptionError,"UnrecognizedPixelMap","`%s'",map);
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "UnrecognizedPixelMap","`%s'",map);
return(MagickFalse);
}
}
}
- if (SetImageStorageClass(image,DirectClass) == MagickFalse)
+ if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
return(MagickFalse);
/*
Transfer the pixels from the pixel datarray to the image.
*/
- exception=(&image->exception);
switch (type)
{
case CharPixel:
% %
% %
% %
-% I n t e r p o l a t e M a g i c k P i x e l P a c k e t %
++ I n i t i a l i z e P i x e l C h a n n e l M a p %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% InterpolatePixelInfo() applies bi-linear or tri-linear interpolation
-% between a floating point coordinate and the pixels surrounding that
-% coordinate. No pixel area resampling, or scaling of the result is
-% performed.
+% InitializePixelChannelMap() defines the standard pixel component map.
%
-% The format of the InterpolatePixelInfo method is:
+% The format of the InitializePixelChannelMap() method is:
%
-% MagickBooleanType InterpolatePixelInfo(const Image *image,
-% const CacheView *image_view,const InterpolatePixelMethod method,
-% const double x,const double y,PixelInfo *pixel,
-% ExceptionInfo *exception)
+% void InitializePixelChannelMap(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: the image.
+%
+*/
+MagickExport void InitializePixelChannelMap(Image *image)
+{
+ PixelChannel
+ alpha_channel;
+
+ register ssize_t
+ i;
+
+ for (i=0; i < (ssize_t) MaxPixelChannels; i++)
+ {
+ SetPixelChannelMapChannel(image,(PixelChannel) i,(PixelChannel) i);
+ SetPixelChannelMapTraits(image,(PixelChannel) i,UndefinedPixelTrait);
+ }
+ image->sync=MagickTrue;
+ image->number_channels=4;
+ if (0 && image->colorspace == GRAYColorspace)
+ image->number_channels=2;
+ if (image->colorspace == CMYKColorspace)
+ image->number_channels++;
+ if (image->storage_class == PseudoClass)
+ image->number_channels++;
+ for (i=0; i < (ssize_t) image->number_channels; i++)
+ SetPixelChannelMapTraits(image,(PixelChannel) i,(PixelTrait)
+ UpdatePixelTrait);
+ alpha_channel=GetPixelChannelMapChannel(image,AlphaPixelChannel);
+ if (image->matte == MagickFalse)
+ SetPixelChannelMapTraits(image,AlphaPixelChannel,CopyPixelTrait);
+ else
+ for (i=0; i < (ssize_t) image->number_channels; i++)
+ if ((PixelChannel) i != alpha_channel)
+ SetPixelChannelMapTraits(image,(PixelChannel) i,(PixelTrait)
+ (UpdatePixelTrait | BlendPixelTrait));
+ if (0 && image->colorspace == GRAYColorspace)
+ {
+ image->number_channels=2;
+ SetPixelChannelMapChannel(image,GreenPixelChannel,RedPixelChannel);
+ SetPixelChannelMapChannel(image,BluePixelChannel,RedPixelChannel);
+ }
+ if (image->storage_class == PseudoClass)
+ {
+ SetPixelChannelMapChannel(image,IndexPixelChannel,IndexPixelChannel);
+ SetPixelChannelMapTraits(image,IndexPixelChannel,CopyPixelTrait);
+ }
+ image->number_channels+=image->number_meta_channels;
+ for ( ; i < (ssize_t) image->number_channels; i++)
+ SetPixelChannelMapTraits(image,(PixelChannel) i,CopyPixelTrait);
+ (void) SetPixelChannelMask(image,image->channel_mask);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I n t e r p o l a t e P i x e l C h a n n e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% InterpolatePixelChannel() applies a pixel interpolation method between a
+% floating point coordinate and the pixels surrounding that coordinate. No
+% pixel area resampling, or scaling of the result is performed.
+%
+% The format of the InterpolatePixelChannel method is:
+%
+% MagickBooleanType InterpolatePixelChannel(const Image *image,
+% const CacheView *image_view,const PixelChannel channel,
+% const PixelInterpolateMethod method,const double x,const double y,
+% double *pixel,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
%
% o image_view: the image view.
%
+% o channel: the pixel channel to interpolate.
+%
% o method: the pixel color interpolation method.
%
% o x,y: A double representing the current (x,y) position of the pixel.
%
*/
-static inline void AlphaBlendPixelInfo(const Image *image,
- const Quantum *pixel,PixelInfo *pixel_info,MagickRealType *alpha)
-{
- if (image->matte == MagickFalse)
- {
- *alpha=1.0;
- pixel_info->red=(MagickRealType) GetPixelRed(image,pixel);
- pixel_info->green=(MagickRealType) GetPixelGreen(image,pixel);
- pixel_info->blue=(MagickRealType) GetPixelBlue(image,pixel);
- pixel_info->black=0.0;
- if (image->colorspace == CMYKColorspace)
- pixel_info->black=(MagickRealType) GetPixelBlack(image,pixel);
- pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
- return;
- }
- *alpha=QuantumScale*GetPixelAlpha(image,pixel);
- pixel_info->red=(*alpha*GetPixelRed(image,pixel));
- pixel_info->green=(*alpha*GetPixelGreen(image,pixel));
- pixel_info->blue=(*alpha*GetPixelBlue(image,pixel));
- pixel_info->black=0.0;
- if (image->colorspace == CMYKColorspace)
- pixel_info->black=(*alpha*GetPixelBlack(image,pixel));
- pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
-}
-
-static void BicubicInterpolate(const PixelInfo *pixels,const double dx,
- PixelInfo *pixel)
-{
- MagickRealType
- dx2,
- p,
- q,
- r,
- s;
-
- dx2=dx*dx;
- p=(pixels[3].red-pixels[2].red)-(pixels[0].red-pixels[1].red);
- q=(pixels[0].red-pixels[1].red)-p;
- r=pixels[2].red-pixels[0].red;
- s=pixels[1].red;
- pixel->red=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
- p=(pixels[3].green-pixels[2].green)-(pixels[0].green-pixels[1].green);
- q=(pixels[0].green-pixels[1].green)-p;
- r=pixels[2].green-pixels[0].green;
- s=pixels[1].green;
- pixel->green=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
- p=(pixels[3].blue-pixels[2].blue)-(pixels[0].blue-pixels[1].blue);
- q=(pixels[0].blue-pixels[1].blue)-p;
- r=pixels[2].blue-pixels[0].blue;
- s=pixels[1].blue;
- pixel->blue=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
- p=(pixels[3].alpha-pixels[2].alpha)-(pixels[0].alpha-pixels[1].alpha);
- q=(pixels[0].alpha-pixels[1].alpha)-p;
- r=pixels[2].alpha-pixels[0].alpha;
- s=pixels[1].alpha;
- pixel->alpha=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
- if (pixel->colorspace == CMYKColorspace)
- {
- p=(pixels[3].black-pixels[2].black)-(pixels[0].black-pixels[1].black);
- q=(pixels[0].black-pixels[1].black)-p;
- r=pixels[2].black-pixels[0].black;
- s=pixels[1].black;
- pixel->black=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
- }
-}
-
static inline double MagickMax(const MagickRealType x,const MagickRealType y)
{
if (x > y)
return((ssize_t) (x-0.5));
}
-MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
- const CacheView *image_view,const InterpolatePixelMethod method,
- const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception)
+MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
+ const CacheView *image_view,const PixelChannel channel,
+ const PixelInterpolateMethod method,const double x,const double y,
+ double *pixel,ExceptionInfo *exception)
{
MagickBooleanType
status;
MagickRealType
alpha[16],
- gamma;
-
- PixelInfo
+ gamma,
pixels[16];
+ PixelTrait
+ traits;
+
register const Quantum
*p;
x_offset,
y_offset;
+ assert(image != (Image *) NULL);
assert(image != (Image *) NULL);
assert(image->signature == MagickSignature);
assert(image_view != (CacheView *) NULL);
status=MagickTrue;
+ *pixel=0.0;
+ traits=GetPixelChannelMapTraits(image,channel);
x_offset=(ssize_t) floor(x);
y_offset=(ssize_t) floor(y);
switch (method == UndefinedInterpolatePixel ? image->interpolate : method)
status=MagickFalse;
break;
}
- AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
- AlphaBlendPixelInfo(image,p+1*GetPixelChannels(image),pixels+1,alpha+1);
- AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
- AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
- AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
- AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
- AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
- AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
- AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
- AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
- AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
- 10);
- AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
- 11);
- AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
- 12);
- AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
- 13);
- AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
- 14);
- AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
- 15);
- pixel->red=0.0;
- pixel->green=0.0;
- pixel->blue=0.0;
- pixel->black=0.0;
- pixel->alpha=0.0;
- for (i=0; i < 16L; i++)
+ if ((traits & BlendPixelTrait) == 0)
+ for (i=0; i < 16; i++)
+ {
+ alpha[i]=1.0;
+ pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
+ }
+ else
+ for (i=0; i < 16; i++)
+ {
+ alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
+ GetPixelChannels(image));
+ pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
+ }
+ for (i=0; i < 16; i++)
{
gamma=1.0/(fabs((double) alpha[i]) <= MagickEpsilon ? 1.0 : alpha[i]);
- pixel->red+=gamma*0.0625*pixels[i].red;
- pixel->green+=gamma*0.0625*pixels[i].green;
- pixel->blue+=gamma*0.0625*pixels[i].blue;
- if (image->colorspace == CMYKColorspace)
- pixel->black+=gamma*0.0625*pixels[i].black;
- pixel->alpha+=0.0625*pixels[i].alpha;
+ *pixel+=gamma*0.0625*pixels[i];
}
break;
}
case BicubicInterpolatePixel:
{
- PixelInfo
- u[4];
+ MagickRealType
+ u[4],
+ v[4];
PointInfo
delta;
status=MagickFalse;
break;
}
- AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
- AlphaBlendPixelInfo(image,p+1*GetPixelChannels(image),pixels+1,alpha+1);
- AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
- AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
- AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
- AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
- AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
- AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
- AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
- AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
- AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
- 10);
- AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
- 11);
- AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
- 12);
- AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
- 13);
- AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
- 14);
- AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
- 15);
+ if ((traits & BlendPixelTrait) == 0)
+ for (i=0; i < 16; i++)
+ {
+ alpha[i]=1.0;
+ pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
+ }
+ else
+ for (i=0; i < 16; i++)
+ {
+ alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
+ GetPixelChannels(image));
+ pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
+ }
delta.x=x-x_offset;
delta.y=y-y_offset;
- for (i=0; i < 4L; i++)
- BicubicInterpolate(pixels+4*i,delta.x,u+i);
- BicubicInterpolate(u,delta.y,pixel);
+ for (i=0; i < 4; i++)
+ {
+ u[0]=(pixels[4*i+3]-pixels[4*i+2])-(pixels[4*i+0]-pixels[4*i+1]);
+ u[1]=(pixels[4*i+0]-pixels[4*i+1])-u[0];
+ u[2]=pixels[4*i+2]-pixels[4*i+0];
+ u[3]=pixels[4*i+1];
+ v[i]=(delta.x*delta.x*delta.x*u[0])+(delta.x*delta.x*u[1])+(delta.x*
+ u[2])+u[3];
+ }
+ u[0]=(v[3]-v[2])-(v[0]-v[1]);
+ u[1]=(v[0]-v[1])-u[0];
+ u[2]=v[2]-v[0];
+ u[3]=v[1];
+ *pixel=(delta.y*delta.y*delta.y*u[0])+(delta.y*delta.y*u[1])+(delta.y*
+ u[2])+u[3];
break;
}
case BilinearInterpolatePixel:
status=MagickFalse;
break;
}
- AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
- AlphaBlendPixelInfo(image,p+1*GetPixelChannels(image),pixels+1,alpha+1);
- AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
- AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
+ if ((traits & BlendPixelTrait) == 0)
+ for (i=0; i < 4; i++)
+ {
+ alpha[i]=1.0;
+ pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
+ }
+ else
+ for (i=0; i < 4; i++)
+ {
+ alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
+ GetPixelChannels(image));
+ pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
+ }
delta.x=x-x_offset;
delta.y=y-y_offset;
epsilon.x=1.0-delta.x;
gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
(epsilon.x*alpha[2]+delta.x*alpha[3])));
gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
- pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x*
- pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red));
- pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x*
- pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x*
- pixels[3].green));
- pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x*
- pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x*
- pixels[3].blue));
- if (image->colorspace == CMYKColorspace)
- pixel->black=gamma*(epsilon.y*(epsilon.x*pixels[0].black+delta.x*
- pixels[1].black)+delta.y*(epsilon.x*pixels[2].black+delta.x*
- pixels[3].black));
- pixel->alpha=(epsilon.y*(epsilon.x*pixels[0].alpha+delta.x*
- pixels[1].alpha)+delta.y*(epsilon.x*pixels[2].alpha+delta.x*
- pixels[3].alpha));
+ *pixel=gamma*(epsilon.y*(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*
+ (epsilon.x*pixels[2]+delta.x*pixels[3]));
break;
}
case FilterInterpolatePixel:
break;
filter_view=AcquireCacheView(filter_image);
p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
- if (p != (const Quantum *) NULL)
- SetPixelInfo(image,p,pixel);
+ if (p == (const Quantum *) NULL)
+ status=MagickFalse;
+ else
+ *pixel=(double) p[channel];
filter_view=DestroyCacheView(filter_view);
filter_image=DestroyImage(filter_image);
break;
status=MagickFalse;
break;
}
- SetPixelInfo(image,p,pixel);
+ *pixel=(double) p[channel];
+ break;
+ }
+ case NearestNeighborInterpolatePixel:
+ {
+ p=GetCacheViewVirtualPixels(image_view,NearestNeighbor(x),
+ NearestNeighbor(y),1,1,exception);
+ if (p == (const Quantum *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ *pixel=(double) p[channel];
break;
}
case MeshInterpolatePixel:
delta,
luminance;
- p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,
- exception);
+ p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
if (p == (const Quantum *) NULL)
{
status=MagickFalse;
break;
}
- AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
- AlphaBlendPixelInfo(image,p+1*GetPixelChannels(image),pixels+1,alpha+1);
- AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
- AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
+ if ((traits & BlendPixelTrait) == 0)
+ for (i=0; i < 4; i++)
+ {
+ alpha[i]=1.0;
+ pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
+ }
+ else
+ for (i=0; i < 4; i++)
+ {
+ alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
+ GetPixelChannels(image));
+ pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
+ }
delta.x=x-x_offset;
delta.y=y-y_offset;
- luminance.x=GetPixelInfoLuminance(pixels+0)-(double)
- GetPixelInfoLuminance(pixels+3);
- luminance.y=GetPixelInfoLuminance(pixels+1)-(double)
- GetPixelInfoLuminance(pixels+2);
+ luminance.x=GetPixelLuminance(image,p)-(double)
+ GetPixelLuminance(image,p+3*GetPixelChannels(image));
+ luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
+ GetPixelLuminance(image,p+2*GetPixelChannels(image));
if (fabs(luminance.x) < fabs(luminance.y))
{
/*
if (delta.x <= delta.y)
{
/*
- Bottom-left triangle (pixel:2, diagonal: 0-3).
+ Bottom-left triangle (pixel: 2, diagonal: 0-3).
+ */
+ delta.y=1.0-delta.y;
+ gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ *pixel=gamma*MeshInterpolate(&delta,pixels[2],pixels[3],
+ pixels[0]);
+ }
+ else
+ {
+ /*
+ Top-right triangle (pixel: 1, diagonal: 0-3).
+ */
+ delta.x=1.0-delta.x;
+ gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ *pixel=gamma*MeshInterpolate(&delta,pixels[1],pixels[0],
+ pixels[3]);
+ }
+ }
+ else
+ {
+ /*
+ Diagonal 1-2 NE-SW.
+ */
+ if (delta.x <= (1.0-delta.y))
+ {
+ /*
+ Top-left triangle (pixel: 0, diagonal: 1-2).
+ */
+ gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ *pixel=gamma*MeshInterpolate(&delta,pixels[0],pixels[1],
+ pixels[2]);
+ }
+ else
+ {
+ /*
+ Bottom-right triangle (pixel: 3, diagonal: 1-2).
+ */
+ delta.x=1.0-delta.x;
+ delta.y=1.0-delta.y;
+ gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ *pixel=gamma*MeshInterpolate(&delta,pixels[3],pixels[2],
+ pixels[1]);
+ }
+ }
+ break;
+ }
+ case SplineInterpolatePixel:
+ {
+ MagickRealType
+ dx,
+ dy;
+
+ PointInfo
+ delta;
+
+ ssize_t
+ j,
+ n;
+
+ p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
+ exception);
+ if (p == (const Quantum *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ if ((traits & BlendPixelTrait) == 0)
+ for (i=0; i < 16; i++)
+ {
+ alpha[i]=1.0;
+ pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
+ }
+ else
+ for (i=0; i < 16; i++)
+ {
+ alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
+ GetPixelChannels(image));
+ pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
+ }
+ delta.x=x-x_offset;
+ delta.y=y-y_offset;
+ n=0;
+ for (i=(-1); i < 3L; i++)
+ {
+ dy=CubicWeightingFunction((MagickRealType) i-delta.y);
+ for (j=(-1); j < 3L; j++)
+ {
+ dx=CubicWeightingFunction(delta.x-(MagickRealType) j);
+ gamma=1.0/(fabs((double) alpha[n]) <= MagickEpsilon ? 1.0 : alpha[n]);
+ *pixel+=gamma*dx*dy*pixels[n];
+ n++;
+ }
+ }
+ break;
+ }
+ }
+ return(status);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I n t e r p o l a t e P i x e l C h a n n e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% InterpolatePixelChannels() applies a pixel interpolation method between a
+% floating point coordinate and the pixels surrounding that coordinate. No
+% pixel area resampling, or scaling of the result is performed.
+%
+% The format of the InterpolatePixelChannels method is:
+%
+% MagickBooleanType InterpolatePixelChannels(const Image *source,
+% const CacheView *source_view,const Image *destination,
+% const PixelInterpolateMethod method,const double x,const double y,
+% Quantum *pixel,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o source: the source.
+%
+% o source_view: the source view.
+%
+% o destination: the destination image.
+%
+% o method: the pixel color interpolation method.
+%
+% o x,y: A double representing the current (x,y) position of the pixel.
+%
+% o pixel: return the interpolated pixel here.
+%
+% o exception: return any errors or warnings in this structure.
+%
+*/
+MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
+ const CacheView *source_view,const Image *destination,
+ const PixelInterpolateMethod method,const double x,const double y,
+ Quantum *pixel,ExceptionInfo *exception)
+{
+ MagickBooleanType
+ status;
+
+ MagickRealType
+ alpha[16],
+ gamma,
+ pixels[16];
+
+ PixelChannel
+ channel;
+
+ PixelTrait
+ destination_traits,
+ traits;
+
+ register const Quantum
+ *p;
+
+ register ssize_t
+ i;
+
+ ssize_t
+ x_offset,
+ y_offset;
+
+ assert(source != (Image *) NULL);
+ assert(source != (Image *) NULL);
+ assert(source->signature == MagickSignature);
+ assert(source_view != (CacheView *) NULL);
+ status=MagickTrue;
+ x_offset=(ssize_t) floor(x);
+ y_offset=(ssize_t) floor(y);
+ switch (method == UndefinedInterpolatePixel ? source->interpolate : method)
+ {
+ case AverageInterpolatePixel:
+ {
+ p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
+ exception);
+ if (p == (const Quantum *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
+ {
+ double
+ sum;
+
+ register ssize_t
+ j;
+
+ traits=GetPixelChannelMapTraits(source,(PixelChannel) i);
+ channel=GetPixelChannelMapChannel(source,(PixelChannel) i);
+ destination_traits=GetPixelChannelMapTraits(destination,channel);
+ if ((traits == UndefinedPixelTrait) ||
+ (destination_traits == UndefinedPixelTrait))
+ continue;
+ for (j=0; j < 16; j++)
+ pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
+ if ((traits & BlendPixelTrait) == 0)
+ {
+ for (j=0; j < 16; j++)
+ pixel[channel]+=0.0625*pixels[j];
+ continue;
+ }
+ sum=0.0;
+ for (j=0; j < 16; j++)
+ {
+ alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
+ GetPixelChannels(source));
+ pixels[j]*=alpha[j];
+ gamma=1.0/(fabs((double) alpha[j]) <= MagickEpsilon ? 1.0 : alpha[j]);
+ sum+=gamma*0.0625*pixels[j];
+ }
+ pixel[channel]=ClampToQuantum(sum);
+ }
+ break;
+ }
+ case BicubicInterpolatePixel:
+ {
+ MagickRealType
+ u[4],
+ v[4];
+
+ PointInfo
+ delta;
+
+ p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
+ exception);
+ if (p == (const Quantum *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
+ {
+ register ssize_t
+ j;
+
+ traits=GetPixelChannelMapTraits(source,(PixelChannel) i);
+ channel=GetPixelChannelMapChannel(source,(PixelChannel) i);
+ destination_traits=GetPixelChannelMapTraits(destination,channel);
+ if ((traits == UndefinedPixelTrait) ||
+ (destination_traits == UndefinedPixelTrait))
+ continue;
+ if ((traits & BlendPixelTrait) == 0)
+ for (j=0; j < 16; j++)
+ {
+ alpha[j]=1.0;
+ pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
+ }
+ else
+ for (j=0; j < 16; j++)
+ {
+ alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
+ GetPixelChannels(source));
+ pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
+ }
+ delta.x=x-x_offset;
+ delta.y=y-y_offset;
+ for (j=0; j < 4; j++)
+ {
+ u[0]=(pixels[4*j+3]-pixels[4*j+2])-(pixels[4*j+0]-pixels[4*j+1]);
+ u[1]=(pixels[4*j+0]-pixels[4*j+1])-u[0];
+ u[2]=pixels[4*j+2]-pixels[4*j+0];
+ u[3]=pixels[4*j+1];
+ v[j]=(delta.x*delta.x*delta.x*u[0])+(delta.x*delta.x*u[1])+(delta.x*
+ u[2])+u[3];
+ }
+ u[0]=(v[3]-v[2])-(v[0]-v[1]);
+ u[1]=(v[0]-v[1])-u[0];
+ u[2]=v[2]-v[0];
+ u[3]=v[1];
+ pixel[channel]=ClampToQuantum((delta.y*delta.y*delta.y*u[0])+(delta.y*
+ delta.y*u[1])+(delta.y*u[2])+u[3]);
+ }
+ break;
+ }
+ case BilinearInterpolatePixel:
+ default:
+ {
+ p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
+ if (p == (const Quantum *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
+ {
+ PointInfo
+ delta,
+ epsilon;
+
+ traits=GetPixelChannelMapTraits(source,(PixelChannel) i);
+ channel=GetPixelChannelMapChannel(source,(PixelChannel) i);
+ destination_traits=GetPixelChannelMapTraits(destination,channel);
+ if ((traits == UndefinedPixelTrait) ||
+ (destination_traits == UndefinedPixelTrait))
+ continue;
+ delta.x=x-x_offset;
+ delta.y=y-y_offset;
+ epsilon.x=1.0-delta.x;
+ epsilon.y=1.0-delta.y;
+ pixels[0]=(MagickRealType) p[i];
+ pixels[1]=(MagickRealType) p[GetPixelChannels(source)+i];
+ pixels[2]=(MagickRealType) p[2*GetPixelChannels(source)+i];
+ pixels[3]=(MagickRealType) p[3*GetPixelChannels(source)+i];
+ if ((traits & BlendPixelTrait) == 0)
+ {
+ gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ pixel[channel]=ClampToQuantum(gamma*(epsilon.y*(epsilon.x*pixels[0]+
+ delta.x*pixels[1])+delta.y*(epsilon.x*pixels[2]+delta.x*
+ pixels[3])));
+ continue;
+ }
+ alpha[0]=QuantumScale*GetPixelAlpha(source,p);
+ alpha[1]=QuantumScale*GetPixelAlpha(source,p+GetPixelChannels(source));
+ alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
+ GetPixelChannels(source));
+ alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
+ GetPixelChannels(source));
+ pixels[0]*=alpha[0];
+ pixels[1]*=alpha[1];
+ pixels[2]*=alpha[2];
+ pixels[3]*=alpha[3];
+ gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
+ (epsilon.x*alpha[2]+delta.x*alpha[3])));
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ pixel[channel]=ClampToQuantum(gamma*(epsilon.y*(epsilon.x*pixels[0]+
+ delta.x*pixels[1])+delta.y*(epsilon.x*pixels[2]+delta.x*pixels[3])));
+ }
+ break;
+ }
+ case FilterInterpolatePixel:
+ {
+ for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
+ {
+ CacheView
+ *filter_view;
+
+ Image
+ *excerpt_source,
+ *filter_source;
+
+ RectangleInfo
+ geometry;
+
+ traits=GetPixelChannelMapTraits(source,(PixelChannel) i);
+ channel=GetPixelChannelMapChannel(source,(PixelChannel) i);
+ destination_traits=GetPixelChannelMapTraits(destination,channel);
+ if ((traits == UndefinedPixelTrait) ||
+ (destination_traits == UndefinedPixelTrait))
+ continue;
+ geometry.width=4L;
+ geometry.height=4L;
+ geometry.x=x_offset-1;
+ geometry.y=y_offset-1;
+ excerpt_source=ExcerptImage(source,&geometry,exception);
+ if (excerpt_source == (Image *) NULL)
+ {
+ status=MagickFalse;
+ continue;
+ }
+ filter_source=ResizeImage(excerpt_source,1,1,source->filter,
+ source->blur,exception);
+ excerpt_source=DestroyImage(excerpt_source);
+ if (filter_source == (Image *) NULL)
+ continue;
+ filter_view=AcquireCacheView(filter_source);
+ p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
+ if (p == (const Quantum *) NULL)
+ status=MagickFalse;
+ else
+ pixel[channel]=p[i];
+ filter_view=DestroyCacheView(filter_view);
+ filter_source=DestroyImage(filter_source);
+ }
+ break;
+ }
+ case IntegerInterpolatePixel:
+ {
+ p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
+ if (p == (const Quantum *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
+ {
+ traits=GetPixelChannelMapTraits(source,(PixelChannel) i);
+ channel=GetPixelChannelMapChannel(source,(PixelChannel) i);
+ destination_traits=GetPixelChannelMapTraits(destination,channel);
+ if ((traits == UndefinedPixelTrait) ||
+ (destination_traits == UndefinedPixelTrait))
+ continue;
+ pixel[channel]=p[i];
+ }
+ break;
+ }
+ case NearestNeighborInterpolatePixel:
+ {
+ p=GetCacheViewVirtualPixels(source_view,NearestNeighbor(x),
+ NearestNeighbor(y),1,1,exception);
+ if (p == (const Quantum *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
+ {
+ traits=GetPixelChannelMapTraits(source,(PixelChannel) i);
+ channel=GetPixelChannelMapChannel(source,(PixelChannel) i);
+ destination_traits=GetPixelChannelMapTraits(destination,channel);
+ if ((traits == UndefinedPixelTrait) ||
+ (destination_traits == UndefinedPixelTrait))
+ continue;
+ pixel[channel]=p[i];
+ }
+ break;
+ }
+ case MeshInterpolatePixel:
+ {
+ p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
+ if (p == (const Quantum *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
+ {
+ PointInfo
+ delta,
+ luminance;
+
+ traits=GetPixelChannelMapTraits(source,(PixelChannel) i);
+ channel=GetPixelChannelMapChannel(source,(PixelChannel) i);
+ destination_traits=GetPixelChannelMapTraits(destination,channel);
+ if ((traits == UndefinedPixelTrait) ||
+ (destination_traits == UndefinedPixelTrait))
+ continue;
+ pixels[0]=(MagickRealType) p[i];
+ pixels[1]=(MagickRealType) p[GetPixelChannels(source)+i];
+ pixels[2]=(MagickRealType) p[2*GetPixelChannels(source)+i];
+ pixels[3]=(MagickRealType) p[3*GetPixelChannels(source)+i];
+ if ((traits & BlendPixelTrait) == 0)
+ {
+ alpha[0]=1.0;
+ alpha[1]=1.0;
+ alpha[2]=1.0;
+ alpha[3]=1.0;
+ }
+ else
+ {
+ alpha[0]=QuantumScale*GetPixelAlpha(source,p);
+ alpha[1]=QuantumScale*GetPixelAlpha(source,p+
+ GetPixelChannels(source));
+ alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
+ GetPixelChannels(source));
+ alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
+ GetPixelChannels(source));
+ }
+ delta.x=x-x_offset;
+ delta.y=y-y_offset;
+ luminance.x=GetPixelLuminance(source,p)-(double)
+ GetPixelLuminance(source,p+3*GetPixelChannels(source));
+ luminance.y=GetPixelLuminance(source,p+GetPixelChannels(source))-
+ (double) GetPixelLuminance(source,p+2*GetPixelChannels(source));
+ if (fabs(luminance.x) < fabs(luminance.y))
+ {
+ /*
+ Diagonal 0-3 NW-SE.
+ */
+ if (delta.x <= delta.y)
+ {
+ /*
+ Bottom-left triangle (pixel: 2, diagonal: 0-3).
+ */
+ delta.y=1.0-delta.y;
+ gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ pixel[channel]=ClampToQuantum(gamma*MeshInterpolate(&delta,
+ pixels[2],pixels[3],pixels[0]));
+ }
+ else
+ {
+ /*
+ Top-right triangle (pixel: 1, diagonal: 0-3).
+ */
+ delta.x=1.0-delta.x;
+ gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ pixel[channel]=ClampToQuantum(gamma*MeshInterpolate(&delta,
+ pixels[1],pixels[0],pixels[3]));
+ }
+ }
+ else
+ {
+ /*
+ Diagonal 1-2 NE-SW.
+ */
+ if (delta.x <= (1.0-delta.y))
+ {
+ /*
+ Top-left triangle (pixel: 0, diagonal: 1-2).
+ */
+ gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ pixel[channel]=ClampToQuantum(gamma*MeshInterpolate(&delta,
+ pixels[0],pixels[1],pixels[2]));
+ }
+ else
+ {
+ /*
+ Bottom-right triangle (pixel: 3, diagonal: 1-2).
+ */
+ delta.x=1.0-delta.x;
+ delta.y=1.0-delta.y;
+ gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ pixel[channel]=ClampToQuantum(gamma*MeshInterpolate(&delta,
+ pixels[3],pixels[2],pixels[1]));
+ }
+ }
+ }
+ break;
+ }
+ case SplineInterpolatePixel:
+ {
+ p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
+ exception);
+ if (p == (const Quantum *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
+ {
+ double
+ sum;
+
+ MagickRealType
+ dx,
+ dy;
+
+ PointInfo
+ delta;
+
+ register ssize_t
+ j;
+
+ ssize_t
+ k,
+ n;
+
+ traits=GetPixelChannelMapTraits(source,(PixelChannel) i);
+ channel=GetPixelChannelMapChannel(source,(PixelChannel) i);
+ destination_traits=GetPixelChannelMapTraits(destination,channel);
+ if ((traits == UndefinedPixelTrait) ||
+ (destination_traits == UndefinedPixelTrait))
+ continue;
+ if ((traits & BlendPixelTrait) == 0)
+ for (j=0; j < 16; j++)
+ {
+ alpha[j]=1.0;
+ pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
+ }
+ else
+ for (j=0; j < 16; j++)
+ {
+ alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
+ GetPixelChannels(source));
+ pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
+ }
+ delta.x=x-x_offset;
+ delta.y=y-y_offset;
+ sum=0.0;
+ n=0;
+ for (j=(-1); j < 3L; j++)
+ {
+ dy=CubicWeightingFunction((MagickRealType) j-delta.y);
+ for (k=(-1); k < 3L; k++)
+ {
+ dx=CubicWeightingFunction(delta.x-(MagickRealType) k);
+ gamma=1.0/(fabs((double) alpha[n]) <= MagickEpsilon ? 1.0 :
+ alpha[n]);
+ sum+=gamma*dx*dy*pixels[n];
+ n++;
+ }
+ }
+ pixel[channel]=ClampToQuantum(sum);
+ }
+ break;
+ }
+ }
+ return(status);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I n t e r p o l a t e P i x e l I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% InterpolatePixelInfo() applies a pixel interpolation method between a
+% floating point coordinate and the pixels surrounding that coordinate. No
+% pixel area resampling, or scaling of the result is performed.
+%
+% The format of the InterpolatePixelInfo method is:
+%
+% MagickBooleanType InterpolatePixelInfo(const Image *image,
+% const CacheView *image_view,const PixelInterpolateMethod method,
+% const double x,const double y,PixelInfo *pixel,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: the image.
+%
+% o image_view: the image view.
+%
+% o method: the pixel color interpolation method.
+%
+% o x,y: A double representing the current (x,y) position of the pixel.
+%
+% o pixel: return the interpolated pixel here.
+%
+% o exception: return any errors or warnings in this structure.
+%
+*/
+
+static inline void AlphaBlendPixelInfo(const Image *image,
+ const Quantum *pixel,PixelInfo *pixel_info,MagickRealType *alpha)
+{
+ if (image->matte == MagickFalse)
+ {
+ *alpha=1.0;
+ pixel_info->red=(MagickRealType) GetPixelRed(image,pixel);
+ pixel_info->green=(MagickRealType) GetPixelGreen(image,pixel);
+ pixel_info->blue=(MagickRealType) GetPixelBlue(image,pixel);
+ pixel_info->black=0.0;
+ if (image->colorspace == CMYKColorspace)
+ pixel_info->black=(MagickRealType) GetPixelBlack(image,pixel);
+ pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
+ return;
+ }
+ *alpha=QuantumScale*GetPixelAlpha(image,pixel);
+ pixel_info->red=(*alpha*GetPixelRed(image,pixel));
+ pixel_info->green=(*alpha*GetPixelGreen(image,pixel));
+ pixel_info->blue=(*alpha*GetPixelBlue(image,pixel));
+ pixel_info->black=0.0;
+ if (image->colorspace == CMYKColorspace)
+ pixel_info->black=(*alpha*GetPixelBlack(image,pixel));
+ pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
+}
+
+static void BicubicInterpolate(const PixelInfo *pixels,const double dx,
+ PixelInfo *pixel)
+{
+ MagickRealType
+ dx2,
+ p,
+ q,
+ r,
+ s;
+
+ dx2=dx*dx;
+ p=(pixels[3].red-pixels[2].red)-(pixels[0].red-pixels[1].red);
+ q=(pixels[0].red-pixels[1].red)-p;
+ r=pixels[2].red-pixels[0].red;
+ s=pixels[1].red;
+ pixel->red=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
+ p=(pixels[3].green-pixels[2].green)-(pixels[0].green-pixels[1].green);
+ q=(pixels[0].green-pixels[1].green)-p;
+ r=pixels[2].green-pixels[0].green;
+ s=pixels[1].green;
+ pixel->green=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
+ p=(pixels[3].blue-pixels[2].blue)-(pixels[0].blue-pixels[1].blue);
+ q=(pixels[0].blue-pixels[1].blue)-p;
+ r=pixels[2].blue-pixels[0].blue;
+ s=pixels[1].blue;
+ pixel->blue=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
+ p=(pixels[3].alpha-pixels[2].alpha)-(pixels[0].alpha-pixels[1].alpha);
+ q=(pixels[0].alpha-pixels[1].alpha)-p;
+ r=pixels[2].alpha-pixels[0].alpha;
+ s=pixels[1].alpha;
+ pixel->alpha=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
+ if (pixel->colorspace == CMYKColorspace)
+ {
+ p=(pixels[3].black-pixels[2].black)-(pixels[0].black-pixels[1].black);
+ q=(pixels[0].black-pixels[1].black)-p;
+ r=pixels[2].black-pixels[0].black;
+ s=pixels[1].black;
+ pixel->black=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
+ }
+}
+
+MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
+ const CacheView *image_view,const PixelInterpolateMethod method,
+ const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception)
+{
+ MagickBooleanType
+ status;
+
+ MagickRealType
+ alpha[16],
+ gamma;
+
+ PixelInfo
+ pixels[16];
+
+ register const Quantum
+ *p;
+
+ register ssize_t
+ i;
+
+ ssize_t
+ x_offset,
+ y_offset;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image_view != (CacheView *) NULL);
+ status=MagickTrue;
+ x_offset=(ssize_t) floor(x);
+ y_offset=(ssize_t) floor(y);
+ switch (method == UndefinedInterpolatePixel ? image->interpolate : method)
+ {
+ case AverageInterpolatePixel:
+ {
+ p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
+ exception);
+ if (p == (const Quantum *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
+ AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
+ AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
+ AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
+ AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
+ AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
+ AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
+ AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
+ AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
+ AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
+ AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
+ 10);
+ AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
+ 11);
+ AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
+ 12);
+ AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
+ 13);
+ AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
+ 14);
+ AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
+ 15);
+ pixel->red=0.0;
+ pixel->green=0.0;
+ pixel->blue=0.0;
+ pixel->black=0.0;
+ pixel->alpha=0.0;
+ for (i=0; i < 16L; i++)
+ {
+ gamma=1.0/(fabs((double) alpha[i]) <= MagickEpsilon ? 1.0 : alpha[i]);
+ pixel->red+=gamma*0.0625*pixels[i].red;
+ pixel->green+=gamma*0.0625*pixels[i].green;
+ pixel->blue+=gamma*0.0625*pixels[i].blue;
+ if (image->colorspace == CMYKColorspace)
+ pixel->black+=gamma*0.0625*pixels[i].black;
+ pixel->alpha+=0.0625*pixels[i].alpha;
+ }
+ break;
+ }
+ case BicubicInterpolatePixel:
+ {
+ PixelInfo
+ u[4];
+
+ PointInfo
+ delta;
+
+ p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
+ exception);
+ if (p == (const Quantum *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
+ AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
+ AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
+ AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
+ AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
+ AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
+ AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
+ AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
+ AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
+ AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
+ AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
+ 10);
+ AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
+ 11);
+ AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
+ 12);
+ AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
+ 13);
+ AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
+ 14);
+ AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
+ 15);
+ delta.x=x-x_offset;
+ delta.y=y-y_offset;
+ for (i=0; i < 4L; i++)
+ BicubicInterpolate(pixels+4*i,delta.x,u+i);
+ BicubicInterpolate(u,delta.y,pixel);
+ break;
+ }
+ case BilinearInterpolatePixel:
+ default:
+ {
+ PointInfo
+ delta,
+ epsilon;
+
+ p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
+ if (p == (const Quantum *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
+ AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
+ AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
+ AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
+ delta.x=x-x_offset;
+ delta.y=y-y_offset;
+ epsilon.x=1.0-delta.x;
+ epsilon.y=1.0-delta.y;
+ gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
+ (epsilon.x*alpha[2]+delta.x*alpha[3])));
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x*
+ pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red));
+ pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x*
+ pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x*
+ pixels[3].green));
+ pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x*
+ pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x*
+ pixels[3].blue));
+ if (image->colorspace == CMYKColorspace)
+ pixel->black=gamma*(epsilon.y*(epsilon.x*pixels[0].black+delta.x*
+ pixels[1].black)+delta.y*(epsilon.x*pixels[2].black+delta.x*
+ pixels[3].black));
+ gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ pixel->alpha=(epsilon.y*(epsilon.x*pixels[0].alpha+delta.x*
+ pixels[1].alpha)+delta.y*(epsilon.x*pixels[2].alpha+delta.x*
+ pixels[3].alpha));
+ break;
+ }
+ case FilterInterpolatePixel:
+ {
+ CacheView
+ *filter_view;
+
+ Image
+ *excerpt_image,
+ *filter_image;
+
+ RectangleInfo
+ geometry;
+
+ geometry.width=4L;
+ geometry.height=4L;
+ geometry.x=x_offset-1;
+ geometry.y=y_offset-1;
+ excerpt_image=ExcerptImage(image,&geometry,exception);
+ if (excerpt_image == (Image *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ filter_image=ResizeImage(excerpt_image,1,1,image->filter,image->blur,
+ exception);
+ excerpt_image=DestroyImage(excerpt_image);
+ if (filter_image == (Image *) NULL)
+ break;
+ filter_view=AcquireCacheView(filter_image);
+ p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
+ if (p != (const Quantum *) NULL)
+ SetPixelInfo(image,p,pixel);
+ filter_view=DestroyCacheView(filter_view);
+ filter_image=DestroyImage(filter_image);
+ break;
+ }
+ case IntegerInterpolatePixel:
+ {
+ p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
+ if (p == (const Quantum *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ SetPixelInfo(image,p,pixel);
+ break;
+ }
+ case MeshInterpolatePixel:
+ {
+ PointInfo
+ delta,
+ luminance;
+
+ p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
+ if (p == (const Quantum *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ delta.x=x-x_offset;
+ delta.y=y-y_offset;
+ luminance.x=GetPixelLuminance(image,p)-(double)
+ GetPixelLuminance(image,p+3*GetPixelChannels(image));
+ luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
+ GetPixelLuminance(image,p+2*GetPixelChannels(image));
+ AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
+ AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
+ AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
+ AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
+ if (fabs(luminance.x) < fabs(luminance.y))
+ {
+ /*
+ Diagonal 0-3 NW-SE.
+ */
+ if (delta.x <= delta.y)
+ {
+ /*
+ Bottom-left triangle (pixel: 2, diagonal: 0-3).
*/
delta.y=1.0-delta.y;
gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
if (image->colorspace == CMYKColorspace)
pixel->black=gamma*MeshInterpolate(&delta,pixels[2].black,
pixels[3].black,pixels[0].black);
+ gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
pixel->alpha=gamma*MeshInterpolate(&delta,pixels[2].alpha,
pixels[3].alpha,pixels[0].alpha);
}
else
{
/*
- Top-right triangle (pixel:1, diagonal: 0-3).
+ Top-right triangle (pixel:1 , diagonal: 0-3).
*/
delta.x=1.0-delta.x;
gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
if (image->colorspace == CMYKColorspace)
pixel->black=gamma*MeshInterpolate(&delta,pixels[1].black,
pixels[0].black,pixels[3].black);
+ gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
pixel->alpha=gamma*MeshInterpolate(&delta,pixels[1].alpha,
pixels[0].alpha,pixels[3].alpha);
}
if (delta.x <= (1.0-delta.y))
{
/*
- Top-left triangle (pixel 0, diagonal: 1-2).
+ Top-left triangle (pixel: 0, diagonal: 1-2).
*/
gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
if (image->colorspace == CMYKColorspace)
pixel->black=gamma*MeshInterpolate(&delta,pixels[0].black,
pixels[1].black,pixels[2].black);
+ gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
pixel->alpha=gamma*MeshInterpolate(&delta,pixels[0].alpha,
pixels[1].alpha,pixels[2].alpha);
}
if (image->colorspace == CMYKColorspace)
pixel->black=gamma*MeshInterpolate(&delta,pixels[3].black,
pixels[2].black,pixels[1].black);
+ gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
pixel->alpha=gamma*MeshInterpolate(&delta,pixels[3].alpha,
pixels[2].alpha,pixels[1].alpha);
}
break;
}
AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
- AlphaBlendPixelInfo(image,p+1*GetPixelChannels(image),pixels+1,alpha+1);
+ AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
% %
% %
% %
-% P o p P i x e l C h a n n e l M a p %
-% %
-% %
-% %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% PopPixelChannelMap() pops the pixel component map.
-%
-% The format of the PopPixelChannelMap method is:
-%
-% void PopPixelChannelMap(Image *image)
-%
-% A description of each parameter follows:
-%
-% o image: the image.
-%
-*/
-MagickExport void PopPixelChannelMap(Image *image)
-{
- image->map--;
- if (image->map < 0)
- ThrowFatalException(ResourceLimitFatalError,"PixelChannelMapStack");
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% %
-% %
-% %
-% P u s h P i x e l C h a n n e l M a p %
-% %
-% %
-% %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% PushPixelChannelMap() pushes the pixel channel map from the specified
-% channel mask.
-%
-% The format of the PushPixelChannelMap method is:
-%
-% void PushPixelChannelMap(Image *image,const ChannelType channel_mask)
-%
-% A description of each parameter follows:
-%
-% o image: the image.
-%
-% o channel_mask: the channel mask.
-%
-*/
-MagickExport void PushPixelChannelMap(Image *image,
- const ChannelType channel_mask)
-{
- image->map++;
- if (image->map >= MaxPixelChannelMaps)
- ThrowFatalException(ResourceLimitFatalError,"PixelChannelMapStack");
- SetPixelChannelMap(image,channel_mask);
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% %
-% %
-% %
% S e t P i x e l C h a n n e l M a p %
% %
% %
%
% o image: the image.
%
-% o channel_mask: the channel mask.
+% o mask: the channel mask.
%
*/
MagickExport void SetPixelChannelMap(Image *image,
const ChannelType channel_mask)
{
-#define GetChannelBit(alpha,i) (((size_t) (alpha) >> (size_t) (i)) & 0x01)
+#define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01)
register ssize_t
i;
+ image->sync=channel_mask == DefaultChannels ? MagickTrue : MagickFalse;
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
SetPixelChannelMapTraits(image,(PixelChannel) i,
- GetChannelBit(channel_mask,i) ? UpdatePixelTrait : CopyPixelTrait);
+ GetChannelBit(channel_mask,i) != 0 ? UpdatePixelTrait : CopyPixelTrait);
for ( ; i < MaxPixelChannels; i++)
SetPixelChannelMapTraits(image,(PixelChannel) i,UndefinedPixelTrait);
+ if (image->storage_class == PseudoClass)
+ SetPixelChannelMapTraits(image,IndexPixelChannel,CopyPixelTrait);
}
\f
/*
% %
% %
% %
-+ S t a n d a r d P i x e l C h a n n e l M a p %
+% S e t P i x e l C h a n n e l M a s k %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% StandardPixelChannelMap() defines the standard pixel component map.
+% SetPixelChannelMask() sets the pixel channel mask from the specified
+% channel mask.
%
-% The format of the StandardPixelChannelMap() method is:
+% The format of the SetPixelChannelMask method is:
%
-% void StandardPixelChannelMap(Image *image)
+% ChannelType SetPixelChannelMask(Image *image,
+% const ChannelType channel_mask)
%
% A description of each parameter follows:
%
% o image: the image.
%
+% o channel_mask: the channel mask.
+%
*/
-MagickExport void StandardPixelChannelMap(Image *image)
+MagickExport ChannelType SetPixelChannelMask(Image *image,
+ const ChannelType channel_mask)
{
- register ssize_t
- i;
+ ChannelType
+ mask;
- for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
- SetPixelChannelMapTraits(image,(PixelChannel) i,UndefinedPixelTrait);
- image->number_channels=4;
- SetPixelChannelMapComponent(image,RedPixelChannel,RedPixelChannel);
- SetPixelChannelMapTraits(image,RedPixelChannel,(PixelTrait)
- (UpdatePixelTrait | BlendPixelTrait));
- SetPixelChannelMapComponent(image,GreenPixelChannel,GreenPixelChannel);
- SetPixelChannelMapTraits(image,GreenPixelChannel,(PixelTrait)
- (UpdatePixelTrait | BlendPixelTrait));
- SetPixelChannelMapComponent(image,BluePixelChannel,BluePixelChannel);
- SetPixelChannelMapTraits(image,BluePixelChannel,(PixelTrait)
- (UpdatePixelTrait | BlendPixelTrait));
- SetPixelChannelMapComponent(image,AlphaPixelChannel,AlphaPixelChannel);
- SetPixelChannelMapTraits(image,AlphaPixelChannel,UpdatePixelTrait);
- if (0 && image->colorspace == GRAYColorspace)
- {
- image->number_channels=2;
- SetPixelChannelMapComponent(image,GreenPixelChannel,RedPixelChannel);
- SetPixelChannelMapComponent(image,BluePixelChannel,RedPixelChannel);
- }
- if (image->colorspace == CMYKColorspace)
- {
- image->number_channels++;
- SetPixelChannelMapComponent(image,BlackPixelChannel,BlackPixelChannel);
- SetPixelChannelMapTraits(image,BlackPixelChannel,(PixelTrait)
- (UpdatePixelTrait | BlendPixelTrait));
- }
- if (image->storage_class == PseudoClass)
- {
- image->number_channels++;
- SetPixelChannelMapComponent(image,IndexPixelChannel,IndexPixelChannel);
- SetPixelChannelMapTraits(image,IndexPixelChannel,CopyPixelTrait);
- }
- image->number_channels+=image->number_meta_channels;
+ mask=image->channel_mask;
+ image->channel_mask=channel_mask;
+ SetPixelChannelMap(image,channel_mask);
+ return(mask);
}