|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
% PPPP IIIII X X EEEEE L % |
|
|
% P P I X X E L % |
|
|
% PPPP I X EEE L % |
|
|
% P I X X E L % |
|
|
% P IIIII X X EEEEE LLLLL % |
|
|
% % |
|
|
% MagickCore Methods to Import/Export Pixels % |
|
|
% % |
|
|
% Software Design % |
|
|
% Cristy % |
|
|
% October 1998 % |
|
|
% % |
|
|
% % |
|
|
% Copyright 1999-2016 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 % |
|
|
% obtain a copy of the License at % |
|
|
% % |
|
|
% http://www.imagemagick.org/script/license.php % |
|
|
% % |
|
|
% Unless required by applicable law or agreed to in writing, software % |
|
|
% distributed under the License is distributed on an "AS IS" BASIS, % |
|
|
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % |
|
|
% See the License for the specific language governing permissions and % |
|
|
% limitations under the License. % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% |
|
|
*/ |
|
|
|
|
|
/* |
|
|
Include declarations. |
|
|
*/ |
|
|
#include "MagickCore/studio.h" |
|
|
#include "MagickCore/property.h" |
|
|
#include "MagickCore/blob.h" |
|
|
#include "MagickCore/blob-private.h" |
|
|
#include "MagickCore/cache-private.h" |
|
|
#include "MagickCore/color-private.h" |
|
|
#include "MagickCore/colorspace-private.h" |
|
|
#include "MagickCore/draw.h" |
|
|
#include "MagickCore/exception.h" |
|
|
#include "MagickCore/exception-private.h" |
|
|
#include "MagickCore/cache.h" |
|
|
#include "MagickCore/constitute.h" |
|
|
#include "MagickCore/delegate.h" |
|
|
#include "MagickCore/geometry.h" |
|
|
#include "MagickCore/image-private.h" |
|
|
#include "MagickCore/list.h" |
|
|
#include "MagickCore/magick.h" |
|
|
#include "MagickCore/memory_.h" |
|
|
#include "MagickCore/memory-private.h" |
|
|
#include "MagickCore/monitor.h" |
|
|
#include "MagickCore/option.h" |
|
|
#include "MagickCore/pixel.h" |
|
|
#include "MagickCore/pixel-accessor.h" |
|
|
#include "MagickCore/pixel-private.h" |
|
|
#include "MagickCore/quantum.h" |
|
|
#include "MagickCore/quantum-private.h" |
|
|
#include "MagickCore/resource_.h" |
|
|
#include "MagickCore/semaphore.h" |
|
|
#include "MagickCore/statistic.h" |
|
|
#include "MagickCore/stream.h" |
|
|
#include "MagickCore/string_.h" |
|
|
#include "MagickCore/transform.h" |
|
|
#include "MagickCore/utility.h" |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
+ A c q u i r e P i x e l C h a n n e l M a p % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% AcquirePixelChannelMap() acquires a pixel component map. |
|
|
% |
|
|
% The format of the AcquirePixelChannelMap() method is: |
|
|
% |
|
|
% PixelChannelMap *AcquirePixelChannelMap(void) |
|
|
% |
|
|
*/ |
|
|
MagickExport PixelChannelMap *AcquirePixelChannelMap(void) |
|
|
{ |
|
|
PixelChannelMap |
|
|
*channel_map; |
|
|
|
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
channel_map=(PixelChannelMap *) AcquireQuantumMemory(MaxPixelChannels, |
|
|
sizeof(*channel_map)); |
|
|
if (channel_map == (PixelChannelMap *) NULL) |
|
|
ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); |
|
|
(void) ResetMagickMemory(channel_map,0,MaxPixelChannels*sizeof(*channel_map)); |
|
|
for (i=0; i < MaxPixelChannels; i++) |
|
|
channel_map[i].channel=(PixelChannel) i; |
|
|
return(channel_map); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
+ C l o n e P i x e l C h a n n e l M a p % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% ClonePixelChannelMap() clones a pixel component map. |
|
|
% |
|
|
% The format of the ClonePixelChannelMap() method is: |
|
|
% |
|
|
% PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map) |
|
|
% |
|
|
% A description of each parameter follows: |
|
|
% |
|
|
% o channel_map: the pixel component map. |
|
|
% |
|
|
*/ |
|
|
MagickExport PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map) |
|
|
{ |
|
|
PixelChannelMap |
|
|
*clone_map; |
|
|
|
|
|
assert(channel_map != (PixelChannelMap *) NULL); |
|
|
clone_map=AcquirePixelChannelMap(); |
|
|
if (clone_map == (PixelChannelMap *) NULL) |
|
|
return((PixelChannelMap *) NULL); |
|
|
(void) CopyMagickMemory(clone_map,channel_map,MaxPixelChannels* |
|
|
sizeof(*channel_map)); |
|
|
return(clone_map); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
+ C l o n e P i x e l I n f o % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% ClonePixelInfo() makes a duplicate of the given pixel info structure, or if |
|
|
% pixel info is NULL, a new one. |
|
|
% |
|
|
% The format of the ClonePixelInfo method is: |
|
|
% |
|
|
% PixelInfo *ClonePixelInfo(const PixelInfo *pixel) |
|
|
% |
|
|
% A description of each parameter follows: |
|
|
% |
|
|
% o pixel: the pixel info. |
|
|
% |
|
|
*/ |
|
|
MagickExport PixelInfo *ClonePixelInfo(const PixelInfo *pixel) |
|
|
{ |
|
|
PixelInfo |
|
|
*pixel_info; |
|
|
|
|
|
pixel_info=(PixelInfo *) MagickAssumeAligned(AcquireAlignedMemory(1, |
|
|
sizeof(*pixel_info))); |
|
|
if (pixel_info == (PixelInfo *) NULL) |
|
|
ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); |
|
|
*pixel_info=(*pixel); |
|
|
return(pixel_info); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
+ C o n f o r m P i x e l I n f o % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% ConformPixelInfo() ensures the pixel conforms with the colorspace and alpha |
|
|
% attribute of the image. |
|
|
% |
|
|
% The format of the ConformPixelInfo method is: |
|
|
% |
|
|
% void *ConformPixelInfo((Image *image,const PixelInfo *source, |
|
|
% PixelInfo *destination,ExceptionInfo *exception) |
|
|
% |
|
|
% A description of each parameter follows: |
|
|
% |
|
|
% o image: the image. |
|
|
% |
|
|
% o source: the source pixel info. |
|
|
% |
|
|
% o destination: the destination pixel info. |
|
|
% |
|
|
% o exception: return any errors or warnings in this structure. |
|
|
% |
|
|
*/ |
|
|
MagickExport void ConformPixelInfo(Image *image,const PixelInfo *source, |
|
|
PixelInfo *destination,ExceptionInfo *exception) |
|
|
{ |
|
|
assert(image != (Image *) NULL); |
|
|
assert(image->signature == MagickCoreSignature); |
|
|
assert(destination != (const PixelInfo *) NULL); |
|
|
*destination=(*source); |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
{ |
|
|
if (IssRGBCompatibleColorspace(destination->colorspace)) |
|
|
ConvertRGBToCMYK(destination); |
|
|
} |
|
|
else |
|
|
if (destination->colorspace == CMYKColorspace) |
|
|
{ |
|
|
if (IssRGBCompatibleColorspace(image->colorspace)) |
|
|
ConvertCMYKToRGB(destination); |
|
|
} |
|
|
if ((IsPixelInfoGray(&image->background_color) == MagickFalse) && |
|
|
(IsGrayColorspace(image->colorspace) != MagickFalse)) |
|
|
(void) TransformImageColorspace(image,sRGBColorspace,exception); |
|
|
if ((destination->alpha_trait != UndefinedPixelTrait) && |
|
|
(image->alpha_trait == UndefinedPixelTrait)) |
|
|
(void) SetImageAlpha(image,OpaqueAlpha,exception); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
% D e c o d e P i x e l G a m m a % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% DecodePixelGamma() applies the expansive power-law nonlinearity to the pixel. |
|
|
% |
|
|
% The format of the DecodePixelGamma method is: |
|
|
% |
|
|
% double DecodePixelGamma(const MagickRealType pixel) |
|
|
% |
|
|
% A description of each parameter follows: |
|
|
% |
|
|
% o pixel: the pixel. |
|
|
% |
|
|
*/ |
|
|
|
|
|
static inline double DecodeGamma(const double x) |
|
|
{ |
|
|
div_t |
|
|
quotient; |
|
|
|
|
|
double |
|
|
p, |
|
|
term[9]; |
|
|
|
|
|
int |
|
|
exponent; |
|
|
|
|
|
static const double coefficient[] = /* terms for x^(7/5), x=1.5 */ |
|
|
{ |
|
|
1.7917488588043277509, |
|
|
0.82045614371976854984, |
|
|
0.027694100686325412819, |
|
|
-0.00094244335181762134018, |
|
|
0.000064355540911469709545, |
|
|
-5.7224404636060757485e-06, |
|
|
5.8767669437311184313e-07, |
|
|
-6.6139920053589721168e-08, |
|
|
7.9323242696227458163e-09 |
|
|
}; |
|
|
|
|
|
static const double powers_of_two[] = /* (2^x)^(7/5) */ |
|
|
{ |
|
|
1.0, |
|
|
2.6390158215457883983, |
|
|
6.9644045063689921093, |
|
|
1.8379173679952558018e+01, |
|
|
4.8502930128332728543e+01 |
|
|
}; |
|
|
|
|
|
/* |
|
|
Compute x^2.4 == x*x^(7/5) == pow(x,2.4). |
|
|
*/ |
|
|
term[0]=1.0; |
|
|
term[1]=4.0*frexp(x,&exponent)-3.0; |
|
|
term[2]=2.0*term[1]*term[1]-term[0]; |
|
|
term[3]=2.0*term[1]*term[2]-term[1]; |
|
|
term[4]=2.0*term[1]*term[3]-term[2]; |
|
|
term[5]=2.0*term[1]*term[4]-term[3]; |
|
|
term[6]=2.0*term[1]*term[5]-term[4]; |
|
|
term[7]=2.0*term[1]*term[6]-term[5]; |
|
|
term[8]=2.0*term[1]*term[7]-term[6]; |
|
|
p=coefficient[0]*term[0]+coefficient[1]*term[1]+coefficient[2]*term[2]+ |
|
|
coefficient[3]*term[3]+coefficient[4]*term[4]+coefficient[5]*term[5]+ |
|
|
coefficient[6]*term[6]+coefficient[7]*term[7]+coefficient[8]*term[8]; |
|
|
quotient=div(exponent-1,5); |
|
|
if (quotient.rem < 0) |
|
|
{ |
|
|
quotient.quot-=1; |
|
|
quotient.rem+=5; |
|
|
} |
|
|
return(x*ldexp(powers_of_two[quotient.rem]*p,7*quotient.quot)); |
|
|
} |
|
|
|
|
|
MagickExport MagickRealType DecodePixelGamma(const MagickRealType pixel) |
|
|
{ |
|
|
if (pixel <= (0.0404482362771076*QuantumRange)) |
|
|
return(pixel/12.92f); |
|
|
return((MagickRealType) (QuantumRange*DecodeGamma((double) (QuantumScale* |
|
|
pixel+0.055)/1.055))); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
+ D e s t r o y P i x e l C h a n n e l M a p % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% DestroyPixelChannelMap() deallocates memory associated with the pixel |
|
|
% channel map. |
|
|
% |
|
|
% The format of the DestroyPixelChannelMap() method is: |
|
|
% |
|
|
% PixelChannelMap *DestroyPixelChannelMap(PixelChannelMap *channel_map) |
|
|
% |
|
|
% A description of each parameter follows: |
|
|
% |
|
|
% o channel_map: the pixel component map. |
|
|
% |
|
|
*/ |
|
|
MagickExport PixelChannelMap *DestroyPixelChannelMap( |
|
|
PixelChannelMap *channel_map) |
|
|
{ |
|
|
assert(channel_map != (PixelChannelMap *) NULL); |
|
|
channel_map=(PixelChannelMap *) RelinquishMagickMemory(channel_map); |
|
|
return((PixelChannelMap *) RelinquishMagickMemory(channel_map)); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
+ E n c o d e P i x e l G a m m a % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% EncodePixelGamma() cancels any nonlinearity in the pixel. |
|
|
% |
|
|
% The format of the EncodePixelGamma method is: |
|
|
% |
|
|
% MagickRealType EncodePixelGamma(const double MagickRealType) |
|
|
% |
|
|
% A description of each parameter follows: |
|
|
% |
|
|
% o pixel: the pixel. |
|
|
% |
|
|
*/ |
|
|
|
|
|
static inline double EncodeGamma(const double x) |
|
|
{ |
|
|
div_t |
|
|
quotient; |
|
|
|
|
|
double |
|
|
p, |
|
|
term[9]; |
|
|
|
|
|
int |
|
|
exponent; |
|
|
|
|
|
static const double coefficient[] = /* Chebychevi poly: x^(5/12), x=1.5 */ |
|
|
{ |
|
|
1.1758200232996901923, |
|
|
0.16665763094889061230, |
|
|
-0.0083154894939042125035, |
|
|
0.00075187976780420279038, |
|
|
-0.000083240178519391795367, |
|
|
0.000010229209410070008679, |
|
|
-1.3400466409860246e-06, |
|
|
1.8333422241635376682e-07, |
|
|
-2.5878596761348859722e-08 |
|
|
}; |
|
|
|
|
|
static const double powers_of_two[] = /* (2^N)^(5/12) */ |
|
|
{ |
|
|
1.0, |
|
|
1.3348398541700343678, |
|
|
1.7817974362806785482, |
|
|
2.3784142300054420538, |
|
|
3.1748021039363991669, |
|
|
4.2378523774371812394, |
|
|
5.6568542494923805819, |
|
|
7.5509945014535482244, |
|
|
1.0079368399158985525e1, |
|
|
1.3454342644059433809e1, |
|
|
1.7959392772949968275e1, |
|
|
2.3972913230026907883e1 |
|
|
}; |
|
|
|
|
|
/* |
|
|
Compute x^(1/2.4) == x^(5/12) == pow(x,1.0/2.4). |
|
|
*/ |
|
|
term[0]=1.0; |
|
|
term[1]=4.0*frexp(x,&exponent)-3.0; |
|
|
term[2]=2.0*term[1]*term[1]-term[0]; |
|
|
term[3]=2.0*term[1]*term[2]-term[1]; |
|
|
term[4]=2.0*term[1]*term[3]-term[2]; |
|
|
term[5]=2.0*term[1]*term[4]-term[3]; |
|
|
term[6]=2.0*term[1]*term[5]-term[4]; |
|
|
term[7]=2.0*term[1]*term[6]-term[5]; |
|
|
term[8]=2.0*term[1]*term[7]-term[6]; |
|
|
p=coefficient[0]*term[0]+coefficient[1]*term[1]+coefficient[2]*term[2]+ |
|
|
coefficient[3]*term[3]+coefficient[4]*term[4]+coefficient[5]*term[5]+ |
|
|
coefficient[6]*term[6]+coefficient[7]*term[7]+coefficient[8]*term[8]; |
|
|
quotient=div(exponent-1,12); |
|
|
if (quotient.rem < 0) |
|
|
{ |
|
|
quotient.quot-=1; |
|
|
quotient.rem+=12; |
|
|
} |
|
|
return(ldexp(powers_of_two[quotient.rem]*p,5*quotient.quot)); |
|
|
} |
|
|
|
|
|
MagickExport MagickRealType EncodePixelGamma(const MagickRealType pixel) |
|
|
{ |
|
|
if (pixel <= (0.0031306684425005883*QuantumRange)) |
|
|
return(12.92f*pixel); |
|
|
return((MagickRealType) QuantumRange*(1.055*EncodeGamma((double) QuantumScale* |
|
|
pixel)-0.055)); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
% E x p o r t I m a g e P i x e l s % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% ExportImagePixels() extracts pixel data from an image and returns it to you. |
|
|
% The method returns MagickTrue on success otherwise MagickFalse if an error is |
|
|
% encountered. The data is returned as char, short int, Quantum, unsigned int, |
|
|
% unsigned long long, float, or double in the order specified by map. |
|
|
% |
|
|
% Suppose you want to extract the first scanline of a 640x480 image as |
|
|
% character data in red-green-blue order: |
|
|
% |
|
|
% ExportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels,exception); |
|
|
% |
|
|
% The format of the ExportImagePixels method is: |
|
|
% |
|
|
% MagickBooleanType ExportImagePixels(const Image *image,const ssize_t x, |
|
|
% const ssize_t y,const size_t width,const size_t height, |
|
|
% const char *map,const StorageType type,void *pixels, |
|
|
% ExceptionInfo *exception) |
|
|
% |
|
|
% A description of each parameter follows: |
|
|
% |
|
|
% o image: the image. |
|
|
% |
|
|
% o x,y,width,height: These values define the perimeter |
|
|
% of a region of pixels you want to extract. |
|
|
% |
|
|
% o map: This string reflects the expected ordering of the pixel array. |
|
|
% It can be any combination or order of R = red, G = green, B = blue, |
|
|
% A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan, |
|
|
% Y = yellow, M = magenta, K = black, I = intensity (for grayscale), |
|
|
% P = pad. |
|
|
% |
|
|
% o type: Define the data type of the pixels. Float and double types are |
|
|
% normalized to [0..1] otherwise [0..QuantumRange]. Choose from these |
|
|
% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *), |
|
|
% LongPixel (unsigned int *), LongLongPixel (unsigned long long *), |
|
|
% QuantumPixel (Quantum *), or ShortPixel (unsigned short *). |
|
|
% |
|
|
% o pixels: This array of values contain the pixel components as defined by |
|
|
% 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. |
|
|
% |
|
|
*/ |
|
|
|
|
|
static void ExportCharPixel(const Image *image,const RectangleInfo *roi, |
|
|
const char *magick_restrict map,const QuantumType *quantum_map,void *pixels, |
|
|
ExceptionInfo *exception) |
|
|
{ |
|
|
register const Quantum |
|
|
*magick_restrict p; |
|
|
|
|
|
register ssize_t |
|
|
x; |
|
|
|
|
|
register unsigned char |
|
|
*magick_restrict q; |
|
|
|
|
|
size_t |
|
|
length; |
|
|
|
|
|
ssize_t |
|
|
y; |
|
|
|
|
|
q=(unsigned char *) pixels; |
|
|
if (LocaleCompare(map,"BGR") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToChar(GetPixelBlue(image,p)); |
|
|
*q++=ScaleQuantumToChar(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToChar(GetPixelRed(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToChar(GetPixelBlue(image,p)); |
|
|
*q++=ScaleQuantumToChar(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToChar(GetPixelRed(image,p)); |
|
|
*q++=ScaleQuantumToChar(GetPixelAlpha(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToChar(GetPixelBlue(image,p)); |
|
|
*q++=ScaleQuantumToChar(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToChar(GetPixelRed(image,p)); |
|
|
*q++=ScaleQuantumToChar((Quantum) 0); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"I") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p))); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGB") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToChar(GetPixelRed(image,p)); |
|
|
*q++=ScaleQuantumToChar(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToChar(GetPixelBlue(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToChar(GetPixelRed(image,p)); |
|
|
*q++=ScaleQuantumToChar(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToChar(GetPixelBlue(image,p)); |
|
|
*q++=ScaleQuantumToChar(GetPixelAlpha(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToChar(GetPixelRed(image,p)); |
|
|
*q++=ScaleQuantumToChar(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToChar(GetPixelBlue(image,p)); |
|
|
*q++=ScaleQuantumToChar((Quantum) 0); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
length=strlen(map); |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
for (i=0; i < (ssize_t) length; i++) |
|
|
{ |
|
|
*q=0; |
|
|
switch (quantum_map[i]) |
|
|
{ |
|
|
case RedQuantum: |
|
|
case CyanQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToChar(GetPixelRed(image,p)); |
|
|
break; |
|
|
} |
|
|
case GreenQuantum: |
|
|
case MagentaQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToChar(GetPixelGreen(image,p)); |
|
|
break; |
|
|
} |
|
|
case BlueQuantum: |
|
|
case YellowQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToChar(GetPixelBlue(image,p)); |
|
|
break; |
|
|
} |
|
|
case AlphaQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToChar(GetPixelAlpha(image,p)); |
|
|
break; |
|
|
} |
|
|
case OpacityQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToChar(GetPixelAlpha(image,p)); |
|
|
break; |
|
|
} |
|
|
case BlackQuantum: |
|
|
{ |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
*q=ScaleQuantumToChar(GetPixelBlack(image,p)); |
|
|
break; |
|
|
} |
|
|
case IndexQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p))); |
|
|
break; |
|
|
} |
|
|
default: |
|
|
break; |
|
|
} |
|
|
q++; |
|
|
} |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
static void ExportDoublePixel(const Image *image,const RectangleInfo *roi, |
|
|
const char *magick_restrict map,const QuantumType *quantum_map,void *pixels, |
|
|
ExceptionInfo *exception) |
|
|
{ |
|
|
register const Quantum |
|
|
*magick_restrict p; |
|
|
|
|
|
register double |
|
|
*magick_restrict q; |
|
|
|
|
|
register ssize_t |
|
|
x; |
|
|
|
|
|
size_t |
|
|
length; |
|
|
|
|
|
ssize_t |
|
|
y; |
|
|
|
|
|
q=(double *) pixels; |
|
|
if (LocaleCompare(map,"BGR") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=(double) (QuantumScale*GetPixelBlue(image,p)); |
|
|
*q++=(double) (QuantumScale*GetPixelGreen(image,p)); |
|
|
*q++=(double) (QuantumScale*GetPixelRed(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=(double) (QuantumScale*GetPixelBlue(image,p)); |
|
|
*q++=(double) (QuantumScale*GetPixelGreen(image,p)); |
|
|
*q++=(double) (QuantumScale*GetPixelRed(image,p)); |
|
|
*q++=(double) (QuantumScale*GetPixelAlpha(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=(double) (QuantumScale*GetPixelBlue(image,p)); |
|
|
*q++=(double) (QuantumScale*GetPixelGreen(image,p)); |
|
|
*q++=(double) (QuantumScale*GetPixelRed(image,p)); |
|
|
*q++=0.0; |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"I") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=(double) (QuantumScale*GetPixelIntensity(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGB") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=(double) (QuantumScale*GetPixelRed(image,p)); |
|
|
*q++=(double) (QuantumScale*GetPixelGreen(image,p)); |
|
|
*q++=(double) (QuantumScale*GetPixelBlue(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=(double) (QuantumScale*GetPixelRed(image,p)); |
|
|
*q++=(double) (QuantumScale*GetPixelGreen(image,p)); |
|
|
*q++=(double) (QuantumScale*GetPixelBlue(image,p)); |
|
|
*q++=(double) (QuantumScale*GetPixelAlpha(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=(double) (QuantumScale*GetPixelRed(image,p)); |
|
|
*q++=(double) (QuantumScale*GetPixelGreen(image,p)); |
|
|
*q++=(double) (QuantumScale*GetPixelBlue(image,p)); |
|
|
*q++=0.0; |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
length=strlen(map); |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
for (i=0; i < (ssize_t) length; i++) |
|
|
{ |
|
|
*q=0; |
|
|
switch (quantum_map[i]) |
|
|
{ |
|
|
case RedQuantum: |
|
|
case CyanQuantum: |
|
|
{ |
|
|
*q=(double) (QuantumScale*GetPixelRed(image,p)); |
|
|
break; |
|
|
} |
|
|
case GreenQuantum: |
|
|
case MagentaQuantum: |
|
|
{ |
|
|
*q=(double) (QuantumScale*GetPixelGreen(image,p)); |
|
|
break; |
|
|
} |
|
|
case BlueQuantum: |
|
|
case YellowQuantum: |
|
|
{ |
|
|
*q=(double) (QuantumScale*GetPixelBlue(image,p)); |
|
|
break; |
|
|
} |
|
|
case AlphaQuantum: |
|
|
{ |
|
|
*q=(double) (QuantumScale*GetPixelAlpha(image,p)); |
|
|
break; |
|
|
} |
|
|
case OpacityQuantum: |
|
|
{ |
|
|
*q=(double) (QuantumScale*GetPixelAlpha(image,p)); |
|
|
break; |
|
|
} |
|
|
case BlackQuantum: |
|
|
{ |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
*q=(double) (QuantumScale* |
|
|
GetPixelBlack(image,p)); |
|
|
break; |
|
|
} |
|
|
case IndexQuantum: |
|
|
{ |
|
|
*q=(double) (QuantumScale*GetPixelIntensity(image,p)); |
|
|
break; |
|
|
} |
|
|
default: |
|
|
*q=0; |
|
|
} |
|
|
q++; |
|
|
} |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
static void ExportFloatPixel(const Image *image,const RectangleInfo *roi, |
|
|
const char *magick_restrict map,const QuantumType *quantum_map,void *pixels, |
|
|
ExceptionInfo *exception) |
|
|
{ |
|
|
register const Quantum |
|
|
*magick_restrict p; |
|
|
|
|
|
register float |
|
|
*magick_restrict q; |
|
|
|
|
|
register ssize_t |
|
|
x; |
|
|
|
|
|
size_t |
|
|
length; |
|
|
|
|
|
ssize_t |
|
|
y; |
|
|
|
|
|
q=(float *) pixels; |
|
|
if (LocaleCompare(map,"BGR") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=(float) (QuantumScale*GetPixelBlue(image,p)); |
|
|
*q++=(float) (QuantumScale*GetPixelGreen(image,p)); |
|
|
*q++=(float) (QuantumScale*GetPixelRed(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=(float) (QuantumScale*GetPixelBlue(image,p)); |
|
|
*q++=(float) (QuantumScale*GetPixelGreen(image,p)); |
|
|
*q++=(float) (QuantumScale*GetPixelRed(image,p)); |
|
|
*q++=(float) (QuantumScale*GetPixelAlpha(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=(float) (QuantumScale*GetPixelBlue(image,p)); |
|
|
*q++=(float) (QuantumScale*GetPixelGreen(image,p)); |
|
|
*q++=(float) (QuantumScale*GetPixelRed(image,p)); |
|
|
*q++=0.0; |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"I") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=(float) (QuantumScale*GetPixelIntensity(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGB") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=(float) (QuantumScale*GetPixelRed(image,p)); |
|
|
*q++=(float) (QuantumScale*GetPixelGreen(image,p)); |
|
|
*q++=(float) (QuantumScale*GetPixelBlue(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=(float) (QuantumScale*GetPixelRed(image,p)); |
|
|
*q++=(float) (QuantumScale*GetPixelGreen(image,p)); |
|
|
*q++=(float) (QuantumScale*GetPixelBlue(image,p)); |
|
|
*q++=(float) (QuantumScale*GetPixelAlpha(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=(float) (QuantumScale*GetPixelRed(image,p)); |
|
|
*q++=(float) (QuantumScale*GetPixelGreen(image,p)); |
|
|
*q++=(float) (QuantumScale*GetPixelBlue(image,p)); |
|
|
*q++=0.0; |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
length=strlen(map); |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
for (i=0; i < (ssize_t) length; i++) |
|
|
{ |
|
|
*q=0; |
|
|
switch (quantum_map[i]) |
|
|
{ |
|
|
case RedQuantum: |
|
|
case CyanQuantum: |
|
|
{ |
|
|
*q=(float) (QuantumScale*GetPixelRed(image,p)); |
|
|
break; |
|
|
} |
|
|
case GreenQuantum: |
|
|
case MagentaQuantum: |
|
|
{ |
|
|
*q=(float) (QuantumScale*GetPixelGreen(image,p)); |
|
|
break; |
|
|
} |
|
|
case BlueQuantum: |
|
|
case YellowQuantum: |
|
|
{ |
|
|
*q=(float) (QuantumScale*GetPixelBlue(image,p)); |
|
|
break; |
|
|
} |
|
|
case AlphaQuantum: |
|
|
{ |
|
|
*q=(float) (QuantumScale*((Quantum) (GetPixelAlpha(image,p)))); |
|
|
break; |
|
|
} |
|
|
case OpacityQuantum: |
|
|
{ |
|
|
*q=(float) (QuantumScale*GetPixelAlpha(image,p)); |
|
|
break; |
|
|
} |
|
|
case BlackQuantum: |
|
|
{ |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
*q=(float) (QuantumScale* GetPixelBlack(image,p)); |
|
|
break; |
|
|
} |
|
|
case IndexQuantum: |
|
|
{ |
|
|
*q=(float) (QuantumScale*GetPixelIntensity(image,p)); |
|
|
break; |
|
|
} |
|
|
default: |
|
|
*q=0; |
|
|
} |
|
|
q++; |
|
|
} |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
static void ExportLongPixel(const Image *image,const RectangleInfo *roi, |
|
|
const char *magick_restrict map,const QuantumType *quantum_map,void *pixels, |
|
|
ExceptionInfo *exception) |
|
|
{ |
|
|
register const Quantum |
|
|
*magick_restrict p; |
|
|
|
|
|
register ssize_t |
|
|
x; |
|
|
|
|
|
register unsigned int |
|
|
*magick_restrict q; |
|
|
|
|
|
size_t |
|
|
length; |
|
|
|
|
|
ssize_t |
|
|
y; |
|
|
|
|
|
q=(unsigned int *) pixels; |
|
|
if (LocaleCompare(map,"BGR") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToLong(GetPixelBlue(image,p)); |
|
|
*q++=ScaleQuantumToLong(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToLong(GetPixelRed(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToLong(GetPixelBlue(image,p)); |
|
|
*q++=ScaleQuantumToLong(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToLong(GetPixelRed(image,p)); |
|
|
*q++=ScaleQuantumToLong(GetPixelAlpha(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToLong(GetPixelBlue(image,p)); |
|
|
*q++=ScaleQuantumToLong(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToLong(GetPixelRed(image,p)); |
|
|
*q++=0; |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"I") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p))); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGB") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToLong(GetPixelRed(image,p)); |
|
|
*q++=ScaleQuantumToLong(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToLong(GetPixelBlue(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToLong(GetPixelRed(image,p)); |
|
|
*q++=ScaleQuantumToLong(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToLong(GetPixelBlue(image,p)); |
|
|
*q++=ScaleQuantumToLong(GetPixelAlpha(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToLong(GetPixelRed(image,p)); |
|
|
*q++=ScaleQuantumToLong(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToLong(GetPixelBlue(image,p)); |
|
|
*q++=0; |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
length=strlen(map); |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
for (i=0; i < (ssize_t) length; i++) |
|
|
{ |
|
|
*q=0; |
|
|
switch (quantum_map[i]) |
|
|
{ |
|
|
case RedQuantum: |
|
|
case CyanQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToLong(GetPixelRed(image,p)); |
|
|
break; |
|
|
} |
|
|
case GreenQuantum: |
|
|
case MagentaQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToLong(GetPixelGreen(image,p)); |
|
|
break; |
|
|
} |
|
|
case BlueQuantum: |
|
|
case YellowQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToLong(GetPixelBlue(image,p)); |
|
|
break; |
|
|
} |
|
|
case AlphaQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToLong(GetPixelAlpha(image,p)); |
|
|
break; |
|
|
} |
|
|
case OpacityQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToLong(GetPixelAlpha(image,p)); |
|
|
break; |
|
|
} |
|
|
case BlackQuantum: |
|
|
{ |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
*q=ScaleQuantumToLong(GetPixelBlack(image,p)); |
|
|
break; |
|
|
} |
|
|
case IndexQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p))); |
|
|
break; |
|
|
} |
|
|
default: |
|
|
break; |
|
|
} |
|
|
q++; |
|
|
} |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
static void ExportLongLongPixel(const Image *image,const RectangleInfo *roi, |
|
|
const char *magick_restrict map,const QuantumType *quantum_map,void *pixels, |
|
|
ExceptionInfo *exception) |
|
|
{ |
|
|
register const Quantum |
|
|
*magick_restrict p; |
|
|
|
|
|
register ssize_t |
|
|
x; |
|
|
|
|
|
register MagickSizeType |
|
|
*magick_restrict q; |
|
|
|
|
|
size_t |
|
|
length; |
|
|
|
|
|
ssize_t |
|
|
y; |
|
|
|
|
|
q=(MagickSizeType *) pixels; |
|
|
if (LocaleCompare(map,"BGR") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToLongLong(GetPixelBlue(image,p)); |
|
|
*q++=ScaleQuantumToLongLong(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToLongLong(GetPixelRed(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToLongLong(GetPixelBlue(image,p)); |
|
|
*q++=ScaleQuantumToLongLong(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToLongLong(GetPixelRed(image,p)); |
|
|
*q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToLongLong(GetPixelBlue(image,p)); |
|
|
*q++=ScaleQuantumToLongLong(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToLongLong(GetPixelRed(image,p)); |
|
|
*q++=0; |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"I") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToLongLong(ClampToQuantum( |
|
|
GetPixelIntensity(image,p))); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGB") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToLongLong(GetPixelRed(image,p)); |
|
|
*q++=ScaleQuantumToLongLong(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToLongLong(GetPixelBlue(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToLongLong(GetPixelRed(image,p)); |
|
|
*q++=ScaleQuantumToLongLong(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToLongLong(GetPixelBlue(image,p)); |
|
|
*q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToLongLong(GetPixelRed(image,p)); |
|
|
*q++=ScaleQuantumToLongLong(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToLongLong(GetPixelBlue(image,p)); |
|
|
*q++=0; |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
length=strlen(map); |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
for (i=0; i < (ssize_t) length; i++) |
|
|
{ |
|
|
*q=0; |
|
|
switch (quantum_map[i]) |
|
|
{ |
|
|
case RedQuantum: |
|
|
case CyanQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToLongLong(GetPixelRed(image,p)); |
|
|
break; |
|
|
} |
|
|
case GreenQuantum: |
|
|
case MagentaQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToLongLong(GetPixelGreen(image,p)); |
|
|
break; |
|
|
} |
|
|
case BlueQuantum: |
|
|
case YellowQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToLongLong(GetPixelBlue(image,p)); |
|
|
break; |
|
|
} |
|
|
case AlphaQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToLongLong(GetPixelAlpha(image,p)); |
|
|
break; |
|
|
} |
|
|
case OpacityQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToLongLong(GetPixelAlpha(image,p)); |
|
|
break; |
|
|
} |
|
|
case BlackQuantum: |
|
|
{ |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
*q=ScaleQuantumToLongLong(GetPixelBlack(image,p)); |
|
|
break; |
|
|
} |
|
|
case IndexQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToLongLong(ClampToQuantum( |
|
|
GetPixelIntensity(image,p))); |
|
|
break; |
|
|
} |
|
|
default: |
|
|
break; |
|
|
} |
|
|
q++; |
|
|
} |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
static void ExportQuantumPixel(const Image *image,const RectangleInfo *roi, |
|
|
const char *magick_restrict map,const QuantumType *quantum_map,void *pixels, |
|
|
ExceptionInfo *exception) |
|
|
{ |
|
|
register const Quantum |
|
|
*magick_restrict p; |
|
|
|
|
|
register Quantum |
|
|
*magick_restrict q; |
|
|
|
|
|
register ssize_t |
|
|
x; |
|
|
|
|
|
size_t |
|
|
length; |
|
|
|
|
|
ssize_t |
|
|
y; |
|
|
|
|
|
q=(Quantum *) pixels; |
|
|
if (LocaleCompare(map,"BGR") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=GetPixelBlue(image,p); |
|
|
*q++=GetPixelGreen(image,p); |
|
|
*q++=GetPixelRed(image,p); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=GetPixelBlue(image,p); |
|
|
*q++=GetPixelGreen(image,p); |
|
|
*q++=GetPixelRed(image,p); |
|
|
*q++=(Quantum) (GetPixelAlpha(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=GetPixelBlue(image,p); |
|
|
*q++=GetPixelGreen(image,p); |
|
|
*q++=GetPixelRed(image,p); |
|
|
*q++=(Quantum) 0; |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"I") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ClampToQuantum(GetPixelIntensity(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGB") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=GetPixelRed(image,p); |
|
|
*q++=GetPixelGreen(image,p); |
|
|
*q++=GetPixelBlue(image,p); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=GetPixelRed(image,p); |
|
|
*q++=GetPixelGreen(image,p); |
|
|
*q++=GetPixelBlue(image,p); |
|
|
*q++=(Quantum) (GetPixelAlpha(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=GetPixelRed(image,p); |
|
|
*q++=GetPixelGreen(image,p); |
|
|
*q++=GetPixelBlue(image,p); |
|
|
*q++=(Quantum) 0; |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
length=strlen(map); |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
for (i=0; i < (ssize_t) length; i++) |
|
|
{ |
|
|
*q=(Quantum) 0; |
|
|
switch (quantum_map[i]) |
|
|
{ |
|
|
case RedQuantum: |
|
|
case CyanQuantum: |
|
|
{ |
|
|
*q=GetPixelRed(image,p); |
|
|
break; |
|
|
} |
|
|
case GreenQuantum: |
|
|
case MagentaQuantum: |
|
|
{ |
|
|
*q=GetPixelGreen(image,p); |
|
|
break; |
|
|
} |
|
|
case BlueQuantum: |
|
|
case YellowQuantum: |
|
|
{ |
|
|
*q=GetPixelBlue(image,p); |
|
|
break; |
|
|
} |
|
|
case AlphaQuantum: |
|
|
{ |
|
|
*q=GetPixelAlpha(image,p); |
|
|
break; |
|
|
} |
|
|
case OpacityQuantum: |
|
|
{ |
|
|
*q=GetPixelAlpha(image,p); |
|
|
break; |
|
|
} |
|
|
case BlackQuantum: |
|
|
{ |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
*q=GetPixelBlack(image,p); |
|
|
break; |
|
|
} |
|
|
case IndexQuantum: |
|
|
{ |
|
|
*q=ClampToQuantum(GetPixelIntensity(image,p)); |
|
|
break; |
|
|
} |
|
|
default: |
|
|
{ |
|
|
*q=(Quantum) 0; |
|
|
break; |
|
|
} |
|
|
} |
|
|
q++; |
|
|
} |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
static void ExportShortPixel(const Image *image,const RectangleInfo *roi, |
|
|
const char *magick_restrict map,const QuantumType *quantum_map,void *pixels, |
|
|
ExceptionInfo *exception) |
|
|
{ |
|
|
register const Quantum |
|
|
*magick_restrict p; |
|
|
|
|
|
register ssize_t |
|
|
x; |
|
|
|
|
|
register unsigned short |
|
|
*magick_restrict q; |
|
|
|
|
|
size_t |
|
|
length; |
|
|
|
|
|
ssize_t |
|
|
y; |
|
|
|
|
|
q=(unsigned short *) pixels; |
|
|
if (LocaleCompare(map,"BGR") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToShort(GetPixelBlue(image,p)); |
|
|
*q++=ScaleQuantumToShort(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToShort(GetPixelRed(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToShort(GetPixelBlue(image,p)); |
|
|
*q++=ScaleQuantumToShort(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToShort(GetPixelRed(image,p)); |
|
|
*q++=ScaleQuantumToShort(GetPixelAlpha(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToShort(GetPixelBlue(image,p)); |
|
|
*q++=ScaleQuantumToShort(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToShort(GetPixelRed(image,p)); |
|
|
*q++=0; |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"I") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToShort(ClampToQuantum(GetPixelIntensity(image,p))); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGB") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToShort(GetPixelRed(image,p)); |
|
|
*q++=ScaleQuantumToShort(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToShort(GetPixelBlue(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToShort(GetPixelRed(image,p)); |
|
|
*q++=ScaleQuantumToShort(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToShort(GetPixelBlue(image,p)); |
|
|
*q++=ScaleQuantumToShort(GetPixelAlpha(image,p)); |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
*q++=ScaleQuantumToShort(GetPixelRed(image,p)); |
|
|
*q++=ScaleQuantumToShort(GetPixelGreen(image,p)); |
|
|
*q++=ScaleQuantumToShort(GetPixelBlue(image,p)); |
|
|
*q++=0; |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
length=strlen(map); |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
for (i=0; i < (ssize_t) length; i++) |
|
|
{ |
|
|
*q=0; |
|
|
switch (quantum_map[i]) |
|
|
{ |
|
|
case RedQuantum: |
|
|
case CyanQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToShort(GetPixelRed(image,p)); |
|
|
break; |
|
|
} |
|
|
case GreenQuantum: |
|
|
case MagentaQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToShort(GetPixelGreen(image,p)); |
|
|
break; |
|
|
} |
|
|
case BlueQuantum: |
|
|
case YellowQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToShort(GetPixelBlue(image,p)); |
|
|
break; |
|
|
} |
|
|
case AlphaQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToShort(GetPixelAlpha(image,p)); |
|
|
break; |
|
|
} |
|
|
case OpacityQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToShort(GetPixelAlpha(image,p)); |
|
|
break; |
|
|
} |
|
|
case BlackQuantum: |
|
|
{ |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
*q=ScaleQuantumToShort(GetPixelBlack(image,p)); |
|
|
break; |
|
|
} |
|
|
case IndexQuantum: |
|
|
{ |
|
|
*q=ScaleQuantumToShort(ClampToQuantum(GetPixelIntensity(image,p))); |
|
|
break; |
|
|
} |
|
|
default: |
|
|
break; |
|
|
} |
|
|
q++; |
|
|
} |
|
|
p+=GetPixelChannels(image); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
MagickExport MagickBooleanType ExportImagePixels(const Image *image,const ssize_t x, |
|
|
const ssize_t y,const size_t width,const size_t height,const char *map, |
|
|
const StorageType type,void *pixels,ExceptionInfo *exception) |
|
|
{ |
|
|
QuantumType |
|
|
*quantum_map; |
|
|
|
|
|
RectangleInfo |
|
|
roi; |
|
|
|
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
size_t |
|
|
length; |
|
|
|
|
|
assert(image != (Image *) NULL); |
|
|
assert(image->signature == MagickCoreSignature); |
|
|
if (image->debug != MagickFalse) |
|
|
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
|
|
length=strlen(map); |
|
|
quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map)); |
|
|
if (quantum_map == (QuantumType *) NULL) |
|
|
{ |
|
|
(void) ThrowMagickException(exception,GetMagickModule(), |
|
|
ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); |
|
|
return(MagickFalse); |
|
|
} |
|
|
for (i=0; i < (ssize_t) length; i++) |
|
|
{ |
|
|
switch (map[i]) |
|
|
{ |
|
|
case 'A': |
|
|
case 'a': |
|
|
{ |
|
|
quantum_map[i]=AlphaQuantum; |
|
|
break; |
|
|
} |
|
|
case 'B': |
|
|
case 'b': |
|
|
{ |
|
|
quantum_map[i]=BlueQuantum; |
|
|
break; |
|
|
} |
|
|
case 'C': |
|
|
case 'c': |
|
|
{ |
|
|
quantum_map[i]=CyanQuantum; |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
break; |
|
|
quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); |
|
|
(void) ThrowMagickException(exception,GetMagickModule(),ImageError, |
|
|
"ColorSeparatedImageRequired","`%s'",map); |
|
|
return(MagickFalse); |
|
|
} |
|
|
case 'g': |
|
|
case 'G': |
|
|
{ |
|
|
quantum_map[i]=GreenQuantum; |
|
|
break; |
|
|
} |
|
|
case 'I': |
|
|
case 'i': |
|
|
{ |
|
|
quantum_map[i]=IndexQuantum; |
|
|
break; |
|
|
} |
|
|
case 'K': |
|
|
case 'k': |
|
|
{ |
|
|
quantum_map[i]=BlackQuantum; |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
break; |
|
|
quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); |
|
|
(void) ThrowMagickException(exception,GetMagickModule(),ImageError, |
|
|
"ColorSeparatedImageRequired","`%s'",map); |
|
|
return(MagickFalse); |
|
|
} |
|
|
case 'M': |
|
|
case 'm': |
|
|
{ |
|
|
quantum_map[i]=MagentaQuantum; |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
break; |
|
|
quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); |
|
|
(void) ThrowMagickException(exception,GetMagickModule(),ImageError, |
|
|
"ColorSeparatedImageRequired","`%s'",map); |
|
|
return(MagickFalse); |
|
|
} |
|
|
case 'o': |
|
|
case 'O': |
|
|
{ |
|
|
quantum_map[i]=OpacityQuantum; |
|
|
break; |
|
|
} |
|
|
case 'P': |
|
|
case 'p': |
|
|
{ |
|
|
quantum_map[i]=UndefinedQuantum; |
|
|
break; |
|
|
} |
|
|
case 'R': |
|
|
case 'r': |
|
|
{ |
|
|
quantum_map[i]=RedQuantum; |
|
|
break; |
|
|
} |
|
|
case 'Y': |
|
|
case 'y': |
|
|
{ |
|
|
quantum_map[i]=YellowQuantum; |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
break; |
|
|
quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); |
|
|
(void) ThrowMagickException(exception,GetMagickModule(),ImageError, |
|
|
"ColorSeparatedImageRequired","`%s'",map); |
|
|
return(MagickFalse); |
|
|
} |
|
|
default: |
|
|
{ |
|
|
quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); |
|
|
(void) ThrowMagickException(exception,GetMagickModule(),OptionError, |
|
|
"UnrecognizedPixelMap","`%s'",map); |
|
|
return(MagickFalse); |
|
|
} |
|
|
} |
|
|
} |
|
|
roi.width=width; |
|
|
roi.height=height; |
|
|
roi.x=x; |
|
|
roi.y=y; |
|
|
switch (type) |
|
|
{ |
|
|
case CharPixel: |
|
|
{ |
|
|
ExportCharPixel(image,&roi,map,quantum_map,pixels,exception); |
|
|
break; |
|
|
} |
|
|
case DoublePixel: |
|
|
{ |
|
|
ExportDoublePixel(image,&roi,map,quantum_map,pixels,exception); |
|
|
break; |
|
|
} |
|
|
case FloatPixel: |
|
|
{ |
|
|
ExportFloatPixel(image,&roi,map,quantum_map,pixels,exception); |
|
|
break; |
|
|
} |
|
|
case LongPixel: |
|
|
{ |
|
|
ExportLongPixel(image,&roi,map,quantum_map,pixels,exception); |
|
|
break; |
|
|
} |
|
|
case LongLongPixel: |
|
|
{ |
|
|
ExportLongLongPixel(image,&roi,map,quantum_map,pixels,exception); |
|
|
break; |
|
|
} |
|
|
case QuantumPixel: |
|
|
{ |
|
|
ExportQuantumPixel(image,&roi,map,quantum_map,pixels,exception); |
|
|
break; |
|
|
} |
|
|
case ShortPixel: |
|
|
{ |
|
|
ExportShortPixel(image,&roi,map,quantum_map,pixels,exception); |
|
|
break; |
|
|
} |
|
|
default: |
|
|
{ |
|
|
quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); |
|
|
(void) ThrowMagickException(exception,GetMagickModule(),OptionError, |
|
|
"UnrecognizedPixelMap","`%s'",map); |
|
|
break; |
|
|
} |
|
|
} |
|
|
quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); |
|
|
return(MagickTrue); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
% G e t P i x e l I n f o % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% GetPixelInfo() initializes the PixelInfo structure. |
|
|
% |
|
|
% The format of the GetPixelInfo method is: |
|
|
% |
|
|
% GetPixelInfo(const Image *image,PixelInfo *pixel) |
|
|
% |
|
|
% A description of each parameter follows: |
|
|
% |
|
|
% o image: the image. (optional - may be NULL) |
|
|
% |
|
|
% o pixel: Specifies a pointer to a PixelInfo structure. |
|
|
% |
|
|
*/ |
|
|
MagickExport void GetPixelInfo(const Image *image,PixelInfo *pixel) |
|
|
{ |
|
|
pixel->storage_class=DirectClass; |
|
|
pixel->colorspace=sRGBColorspace; |
|
|
pixel->alpha_trait=UndefinedPixelTrait; |
|
|
pixel->fuzz=0.0; |
|
|
pixel->depth=MAGICKCORE_QUANTUM_DEPTH; |
|
|
pixel->red=0.0; |
|
|
pixel->green=0.0; |
|
|
pixel->blue=0.0; |
|
|
pixel->black=0.0; |
|
|
pixel->alpha=(double) OpaqueAlpha; |
|
|
pixel->index=0.0; |
|
|
pixel->count=0; |
|
|
pixel->fuzz=0.0; |
|
|
if (image == (const Image *) NULL) |
|
|
return; |
|
|
pixel->storage_class=image->storage_class; |
|
|
pixel->colorspace=image->colorspace; |
|
|
pixel->alpha_trait=image->alpha_trait; |
|
|
pixel->depth=image->depth; |
|
|
pixel->fuzz=image->fuzz; |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
% G e t P i x e l I n d o I n t e n s i t y % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% GetPixelInfoIntensity() returns a single sample intensity value from the red, |
|
|
% green, and blue components of a pixel based on the selected method: |
|
|
% |
|
|
% Rec601Luma 0.298839R' + 0.586811G' + 0.114350B' |
|
|
% Rec601Luminance 0.298839R + 0.586811G + 0.114350B |
|
|
% Rec709Luma 0.212656R' + 0.715158G' + 0.072186B' |
|
|
% Rec709Luminance 0.212656R + 0.715158G + 0.072186B |
|
|
% Brightness max(R', G', B') |
|
|
% Lightness (min(R', G', B') + max(R', G', B')) / 2.0 |
|
|
% |
|
|
% MS (R^2 + G^2 + B^2) / 3.0 |
|
|
% RMS sqrt((R^2 + G^2 + B^2) / 3.0 |
|
|
% Average (R + G + B') / 3.0 |
|
|
% |
|
|
% The format of the GetPixelInfoIntensity method is: |
|
|
% |
|
|
% MagickRealType GetPixelInfoIntensity(const Image *image, |
|
|
% const Quantum *pixel) |
|
|
% |
|
|
% A description of each parameter follows: |
|
|
% |
|
|
% o image: the image. |
|
|
% |
|
|
% o pixel: Specifies a pointer to a Quantum structure. |
|
|
% |
|
|
*/ |
|
|
MagickExport MagickRealType GetPixelInfoIntensity( |
|
|
const Image *magick_restrict image,const PixelInfo *magick_restrict pixel) |
|
|
{ |
|
|
MagickRealType |
|
|
blue, |
|
|
green, |
|
|
red, |
|
|
intensity; |
|
|
|
|
|
PixelIntensityMethod |
|
|
method; |
|
|
|
|
|
method=Rec709LumaPixelIntensityMethod; |
|
|
if (image != (const Image *) NULL) |
|
|
method=image->intensity; |
|
|
red=pixel->red; |
|
|
green=pixel->green; |
|
|
blue=pixel->blue; |
|
|
switch (method) |
|
|
{ |
|
|
case AveragePixelIntensityMethod: |
|
|
{ |
|
|
intensity=(red+green+blue)/3.0; |
|
|
break; |
|
|
} |
|
|
case BrightnessPixelIntensityMethod: |
|
|
{ |
|
|
intensity=MagickMax(MagickMax(red,green),blue); |
|
|
break; |
|
|
} |
|
|
case LightnessPixelIntensityMethod: |
|
|
{ |
|
|
intensity=(MagickMin(MagickMin(red,green),blue)+ |
|
|
MagickMax(MagickMax(red,green),blue))/2.0; |
|
|
break; |
|
|
} |
|
|
case MSPixelIntensityMethod: |
|
|
{ |
|
|
intensity=(MagickRealType) (((double) red*red+green*green+blue*blue)/ |
|
|
(3.0*QuantumRange)); |
|
|
break; |
|
|
} |
|
|
case Rec601LumaPixelIntensityMethod: |
|
|
{ |
|
|
if (pixel->colorspace == RGBColorspace) |
|
|
{ |
|
|
red=EncodePixelGamma(red); |
|
|
green=EncodePixelGamma(green); |
|
|
blue=EncodePixelGamma(blue); |
|
|
} |
|
|
intensity=0.298839*red+0.586811*green+0.114350*blue; |
|
|
break; |
|
|
} |
|
|
case Rec601LuminancePixelIntensityMethod: |
|
|
{ |
|
|
if (pixel->colorspace == sRGBColorspace) |
|
|
{ |
|
|
red=DecodePixelGamma(red); |
|
|
green=DecodePixelGamma(green); |
|
|
blue=DecodePixelGamma(blue); |
|
|
} |
|
|
intensity=0.298839*red+0.586811*green+0.114350*blue; |
|
|
break; |
|
|
} |
|
|
case Rec709LumaPixelIntensityMethod: |
|
|
default: |
|
|
{ |
|
|
if (pixel->colorspace == RGBColorspace) |
|
|
{ |
|
|
red=EncodePixelGamma(red); |
|
|
green=EncodePixelGamma(green); |
|
|
blue=EncodePixelGamma(blue); |
|
|
} |
|
|
intensity=0.212656*red+0.715158*green+0.072186*blue; |
|
|
break; |
|
|
} |
|
|
case Rec709LuminancePixelIntensityMethod: |
|
|
{ |
|
|
if (pixel->colorspace == sRGBColorspace) |
|
|
{ |
|
|
red=DecodePixelGamma(red); |
|
|
green=DecodePixelGamma(green); |
|
|
blue=DecodePixelGamma(blue); |
|
|
} |
|
|
intensity=0.212656*red+0.715158*green+0.072186*blue; |
|
|
break; |
|
|
} |
|
|
case RMSPixelIntensityMethod: |
|
|
{ |
|
|
intensity=(MagickRealType) (sqrt((double) red*red+green*green+blue*blue)/ |
|
|
sqrt(3.0)); |
|
|
break; |
|
|
} |
|
|
} |
|
|
return(intensity); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
% G e t P i x e l I n t e n s i t y % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% GetPixelIntensity() returns a single sample intensity value from the red, |
|
|
% green, and blue components of a pixel based on the selected method: |
|
|
% |
|
|
% Rec601Luma 0.298839R' + 0.586811G' + 0.114350B' |
|
|
% Rec601Luminance 0.298839R + 0.586811G + 0.114350B |
|
|
% Rec709Luma 0.212656R' + 0.715158G' + 0.072186B' |
|
|
% Rec709Luminance 0.212656R + 0.715158G + 0.072186B |
|
|
% Brightness max(R', G', B') |
|
|
% Lightness (min(R', G', B') + max(R', G', B')) / 2.0 |
|
|
% |
|
|
% MS (R^2 + G^2 + B^2) / 3.0 |
|
|
% RMS sqrt((R^2 + G^2 + B^2) / 3.0 |
|
|
% Average (R + G + B') / 3.0 |
|
|
% |
|
|
% The format of the GetPixelIntensity method is: |
|
|
% |
|
|
% MagickRealType GetPixelIntensity(const Image *image, |
|
|
% const Quantum *pixel) |
|
|
% |
|
|
% A description of each parameter follows: |
|
|
% |
|
|
% o image: the image. |
|
|
% |
|
|
% o pixel: Specifies a pointer to a Quantum structure. |
|
|
% |
|
|
*/ |
|
|
MagickExport MagickRealType GetPixelIntensity(const Image *magick_restrict image, |
|
|
const Quantum *magick_restrict pixel) |
|
|
{ |
|
|
MagickRealType |
|
|
blue, |
|
|
green, |
|
|
red, |
|
|
intensity; |
|
|
|
|
|
red=GetPixelRed(image,pixel); |
|
|
green=GetPixelGreen(image,pixel); |
|
|
blue=GetPixelBlue(image,pixel); |
|
|
switch (image->intensity) |
|
|
{ |
|
|
case AveragePixelIntensityMethod: |
|
|
{ |
|
|
intensity=(red+green+blue)/3.0; |
|
|
break; |
|
|
} |
|
|
case BrightnessPixelIntensityMethod: |
|
|
{ |
|
|
intensity=MagickMax(MagickMax(red,green),blue); |
|
|
break; |
|
|
} |
|
|
case LightnessPixelIntensityMethod: |
|
|
{ |
|
|
intensity=(MagickMin(MagickMin(red,green),blue)+ |
|
|
MagickMax(MagickMax(red,green),blue))/2.0; |
|
|
break; |
|
|
} |
|
|
case MSPixelIntensityMethod: |
|
|
{ |
|
|
intensity=(MagickRealType) (((double) red*red+green*green+blue*blue)/ |
|
|
(3.0*QuantumRange)); |
|
|
break; |
|
|
} |
|
|
case Rec601LumaPixelIntensityMethod: |
|
|
{ |
|
|
if (image->colorspace == RGBColorspace) |
|
|
{ |
|
|
red=EncodePixelGamma(red); |
|
|
green=EncodePixelGamma(green); |
|
|
blue=EncodePixelGamma(blue); |
|
|
} |
|
|
intensity=0.298839*red+0.586811*green+0.114350*blue; |
|
|
break; |
|
|
} |
|
|
case Rec601LuminancePixelIntensityMethod: |
|
|
{ |
|
|
if (image->colorspace == sRGBColorspace) |
|
|
{ |
|
|
red=DecodePixelGamma(red); |
|
|
green=DecodePixelGamma(green); |
|
|
blue=DecodePixelGamma(blue); |
|
|
} |
|
|
intensity=0.298839*red+0.586811*green+0.114350*blue; |
|
|
break; |
|
|
} |
|
|
case Rec709LumaPixelIntensityMethod: |
|
|
default: |
|
|
{ |
|
|
if (image->colorspace == RGBColorspace) |
|
|
{ |
|
|
red=EncodePixelGamma(red); |
|
|
green=EncodePixelGamma(green); |
|
|
blue=EncodePixelGamma(blue); |
|
|
} |
|
|
intensity=0.212656*red+0.715158*green+0.072186*blue; |
|
|
break; |
|
|
} |
|
|
case Rec709LuminancePixelIntensityMethod: |
|
|
{ |
|
|
if (image->colorspace == sRGBColorspace) |
|
|
{ |
|
|
red=DecodePixelGamma(red); |
|
|
green=DecodePixelGamma(green); |
|
|
blue=DecodePixelGamma(blue); |
|
|
} |
|
|
intensity=0.212656*red+0.715158*green+0.072186*blue; |
|
|
break; |
|
|
} |
|
|
case RMSPixelIntensityMethod: |
|
|
{ |
|
|
intensity=(MagickRealType) (sqrt((double) red*red+green*green+blue*blue)/ |
|
|
sqrt(3.0)); |
|
|
break; |
|
|
} |
|
|
} |
|
|
return(intensity); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
% I m p o r t I m a g e P i x e l s % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% ImportImagePixels() accepts pixel data and stores in the image at the |
|
|
% location you specify. The method returns MagickTrue on success otherwise |
|
|
% MagickFalse if an error is encountered. The pixel data can be either char, |
|
|
% Quantum, short int, unsigned int, unsigned long long, float, or double in |
|
|
% the order specified by map. |
|
|
% |
|
|
% Suppose your want to upload the first scanline of a 640x480 image from |
|
|
% character data in red-green-blue order: |
|
|
% |
|
|
% ImportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels); |
|
|
% |
|
|
% The format of the ImportImagePixels method is: |
|
|
% |
|
|
% MagickBooleanType ImportImagePixels(Image *image,const ssize_t x, |
|
|
% const ssize_t y,const size_t width,const size_t height, |
|
|
% const char *map,const StorageType type,const void *pixels, |
|
|
% ExceptionInfo *exception) |
|
|
% |
|
|
% A description of each parameter follows: |
|
|
% |
|
|
% o image: the image. |
|
|
% |
|
|
% o x,y,width,height: These values define the perimeter |
|
|
% of a region of pixels you want to define. |
|
|
% |
|
|
% o map: This string reflects the expected ordering of the pixel array. |
|
|
% It can be any combination or order of R = red, G = green, B = blue, |
|
|
% A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan, |
|
|
% Y = yellow, M = magenta, K = black, I = intensity (for grayscale), |
|
|
% P = pad. |
|
|
% |
|
|
% o type: Define the data type of the pixels. Float and double types are |
|
|
% normalized to [0..1] otherwise [0..QuantumRange]. Choose from these |
|
|
% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *), |
|
|
% LongPixel (unsigned int *), LongLongPixel (unsigned long long *), |
|
|
% QuantumPixel (Quantum *), or ShortPixel (unsigned short *). |
|
|
% |
|
|
% o pixels: This array of values contain the pixel components as defined by |
|
|
% 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. |
|
|
% |
|
|
*/ |
|
|
|
|
|
static void ImportCharPixel(Image *image,const RectangleInfo *roi, |
|
|
const char *magick_restrict map,const QuantumType *quantum_map, |
|
|
const void *pixels,ExceptionInfo *exception) |
|
|
{ |
|
|
register const unsigned char |
|
|
*magick_restrict p; |
|
|
|
|
|
register Quantum |
|
|
*magick_restrict q; |
|
|
|
|
|
register ssize_t |
|
|
x; |
|
|
|
|
|
size_t |
|
|
length; |
|
|
|
|
|
ssize_t |
|
|
y; |
|
|
|
|
|
p=(const unsigned char *) pixels; |
|
|
if (LocaleCompare(map,"BGR") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelRed(image,ScaleCharToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelRed(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelAlpha(image,ScaleCharToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRO") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelRed(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelAlpha(image,ScaleCharToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelRed(image,ScaleCharToQuantum(*p++),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"I") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelGray(image,ScaleCharToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGB") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelBlue(image,ScaleCharToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelBlue(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelAlpha(image,ScaleCharToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBO") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelBlue(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelAlpha(image,ScaleCharToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleCharToQuantum(*p++),q); |
|
|
SetPixelBlue(image,ScaleCharToQuantum(*p++),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
length=strlen(map); |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
for (i=0; i < (ssize_t) length; i++) |
|
|
{ |
|
|
switch (quantum_map[i]) |
|
|
{ |
|
|
case RedQuantum: |
|
|
case CyanQuantum: |
|
|
{ |
|
|
SetPixelRed(image,ScaleCharToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case GreenQuantum: |
|
|
case MagentaQuantum: |
|
|
{ |
|
|
SetPixelGreen(image,ScaleCharToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case BlueQuantum: |
|
|
case YellowQuantum: |
|
|
{ |
|
|
SetPixelBlue(image,ScaleCharToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case AlphaQuantum: |
|
|
{ |
|
|
SetPixelAlpha(image,ScaleCharToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case OpacityQuantum: |
|
|
{ |
|
|
SetPixelAlpha(image,ScaleCharToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case BlackQuantum: |
|
|
{ |
|
|
SetPixelBlack(image,ScaleCharToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case IndexQuantum: |
|
|
{ |
|
|
SetPixelGray(image,ScaleCharToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
default: |
|
|
break; |
|
|
} |
|
|
p++; |
|
|
} |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
static void ImportDoublePixel(Image *image,const RectangleInfo *roi, |
|
|
const char *magick_restrict map,const QuantumType *quantum_map, |
|
|
const void *pixels,ExceptionInfo *exception) |
|
|
{ |
|
|
register const double |
|
|
*magick_restrict p; |
|
|
|
|
|
register Quantum |
|
|
*magick_restrict q; |
|
|
|
|
|
register ssize_t |
|
|
x; |
|
|
|
|
|
size_t |
|
|
length; |
|
|
|
|
|
ssize_t |
|
|
y; |
|
|
|
|
|
p=(const double *) pixels; |
|
|
if (LocaleCompare(map,"BGR") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"I") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGB") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
length=strlen(map); |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
for (i=0; i < (ssize_t) length; i++) |
|
|
{ |
|
|
switch (quantum_map[i]) |
|
|
{ |
|
|
case RedQuantum: |
|
|
case CyanQuantum: |
|
|
{ |
|
|
SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
break; |
|
|
} |
|
|
case GreenQuantum: |
|
|
case MagentaQuantum: |
|
|
{ |
|
|
SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
break; |
|
|
} |
|
|
case BlueQuantum: |
|
|
case YellowQuantum: |
|
|
{ |
|
|
SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
break; |
|
|
} |
|
|
case AlphaQuantum: |
|
|
{ |
|
|
SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
break; |
|
|
} |
|
|
case OpacityQuantum: |
|
|
{ |
|
|
SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
break; |
|
|
} |
|
|
case BlackQuantum: |
|
|
{ |
|
|
SetPixelBlack(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
break; |
|
|
} |
|
|
case IndexQuantum: |
|
|
{ |
|
|
SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
break; |
|
|
} |
|
|
default: |
|
|
break; |
|
|
} |
|
|
p++; |
|
|
} |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
static void ImportFloatPixel(Image *image,const RectangleInfo *roi, |
|
|
const char *magick_restrict map,const QuantumType *quantum_map, |
|
|
const void *pixels,ExceptionInfo *exception) |
|
|
{ |
|
|
register const float |
|
|
*magick_restrict p; |
|
|
|
|
|
register Quantum |
|
|
*magick_restrict q; |
|
|
|
|
|
register ssize_t |
|
|
x; |
|
|
|
|
|
size_t |
|
|
length; |
|
|
|
|
|
ssize_t |
|
|
y; |
|
|
|
|
|
p=(const float *) pixels; |
|
|
if (LocaleCompare(map,"BGR") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"I") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGB") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
length=strlen(map); |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
for (i=0; i < (ssize_t) length; i++) |
|
|
{ |
|
|
switch (quantum_map[i]) |
|
|
{ |
|
|
case RedQuantum: |
|
|
case CyanQuantum: |
|
|
{ |
|
|
SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
break; |
|
|
} |
|
|
case GreenQuantum: |
|
|
case MagentaQuantum: |
|
|
{ |
|
|
SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
break; |
|
|
} |
|
|
case BlueQuantum: |
|
|
case YellowQuantum: |
|
|
{ |
|
|
SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
break; |
|
|
} |
|
|
case AlphaQuantum: |
|
|
{ |
|
|
SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
break; |
|
|
} |
|
|
case OpacityQuantum: |
|
|
{ |
|
|
SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
break; |
|
|
} |
|
|
case BlackQuantum: |
|
|
{ |
|
|
SetPixelBlack(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
break; |
|
|
} |
|
|
case IndexQuantum: |
|
|
{ |
|
|
SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q); |
|
|
break; |
|
|
} |
|
|
default: |
|
|
break; |
|
|
} |
|
|
p++; |
|
|
} |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
static void ImportLongPixel(Image *image,const RectangleInfo *roi, |
|
|
const char *magick_restrict map,const QuantumType *quantum_map, |
|
|
const void *pixels,ExceptionInfo *exception) |
|
|
{ |
|
|
register const unsigned int |
|
|
*magick_restrict p; |
|
|
|
|
|
register Quantum |
|
|
*magick_restrict q; |
|
|
|
|
|
register ssize_t |
|
|
x; |
|
|
|
|
|
size_t |
|
|
length; |
|
|
|
|
|
ssize_t |
|
|
y; |
|
|
|
|
|
p=(const unsigned int *) pixels; |
|
|
if (LocaleCompare(map,"BGR") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ScaleLongToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleLongToQuantum(*p++),q); |
|
|
SetPixelRed(image,ScaleLongToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ScaleLongToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleLongToQuantum(*p++),q); |
|
|
SetPixelRed(image,ScaleLongToQuantum(*p++),q); |
|
|
SetPixelAlpha(image,ScaleLongToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ScaleLongToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleLongToQuantum(*p++),q); |
|
|
SetPixelRed(image,ScaleLongToQuantum(*p++),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"I") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelGray(image,ScaleLongToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGB") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ScaleLongToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleLongToQuantum(*p++),q); |
|
|
SetPixelBlue(image,ScaleLongToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ScaleLongToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleLongToQuantum(*p++),q); |
|
|
SetPixelBlue(image,ScaleLongToQuantum(*p++),q); |
|
|
SetPixelAlpha(image,ScaleLongToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ScaleLongToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleLongToQuantum(*p++),q); |
|
|
SetPixelBlue(image,ScaleLongToQuantum(*p++),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
length=strlen(map); |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
for (i=0; i < (ssize_t) length; i++) |
|
|
{ |
|
|
switch (quantum_map[i]) |
|
|
{ |
|
|
case RedQuantum: |
|
|
case CyanQuantum: |
|
|
{ |
|
|
SetPixelRed(image,ScaleLongToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case GreenQuantum: |
|
|
case MagentaQuantum: |
|
|
{ |
|
|
SetPixelGreen(image,ScaleLongToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case BlueQuantum: |
|
|
case YellowQuantum: |
|
|
{ |
|
|
SetPixelBlue(image,ScaleLongToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case AlphaQuantum: |
|
|
{ |
|
|
SetPixelAlpha(image,ScaleLongToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case OpacityQuantum: |
|
|
{ |
|
|
SetPixelAlpha(image,ScaleLongToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case BlackQuantum: |
|
|
{ |
|
|
SetPixelBlack(image,ScaleLongToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case IndexQuantum: |
|
|
{ |
|
|
SetPixelGray(image,ScaleLongToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
default: |
|
|
break; |
|
|
} |
|
|
p++; |
|
|
} |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
static void ImportLongLongPixel(Image *image,const RectangleInfo *roi, |
|
|
const char *magick_restrict map,const QuantumType *quantum_map, |
|
|
const void *pixels,ExceptionInfo *exception) |
|
|
{ |
|
|
register const MagickSizeType |
|
|
*magick_restrict p; |
|
|
|
|
|
register Quantum |
|
|
*magick_restrict q; |
|
|
|
|
|
register ssize_t |
|
|
x; |
|
|
|
|
|
size_t |
|
|
length; |
|
|
|
|
|
ssize_t |
|
|
y; |
|
|
|
|
|
p=(const MagickSizeType *) pixels; |
|
|
if (LocaleCompare(map,"BGR") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q); |
|
|
SetPixelRed(image,ScaleLongLongToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q); |
|
|
SetPixelRed(image,ScaleLongLongToQuantum(*p++),q); |
|
|
SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q); |
|
|
SetPixelRed(image,ScaleLongLongToQuantum(*p++),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"I") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelGray(image,ScaleLongLongToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGB") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ScaleLongLongToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q); |
|
|
SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ScaleLongLongToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q); |
|
|
SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q); |
|
|
SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ScaleLongLongToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q); |
|
|
SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
length=strlen(map); |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
for (i=0; i < (ssize_t) length; i++) |
|
|
{ |
|
|
switch (quantum_map[i]) |
|
|
{ |
|
|
case RedQuantum: |
|
|
case CyanQuantum: |
|
|
{ |
|
|
SetPixelRed(image,ScaleLongLongToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case GreenQuantum: |
|
|
case MagentaQuantum: |
|
|
{ |
|
|
SetPixelGreen(image,ScaleLongLongToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case BlueQuantum: |
|
|
case YellowQuantum: |
|
|
{ |
|
|
SetPixelBlue(image,ScaleLongLongToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case AlphaQuantum: |
|
|
{ |
|
|
SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case OpacityQuantum: |
|
|
{ |
|
|
SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case BlackQuantum: |
|
|
{ |
|
|
SetPixelBlack(image,ScaleLongLongToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case IndexQuantum: |
|
|
{ |
|
|
SetPixelGray(image,ScaleLongLongToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
default: |
|
|
break; |
|
|
} |
|
|
p++; |
|
|
} |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
static void ImportQuantumPixel(Image *image,const RectangleInfo *roi, |
|
|
const char *magick_restrict map,const QuantumType *quantum_map, |
|
|
const void *pixels,ExceptionInfo *exception) |
|
|
{ |
|
|
register const Quantum |
|
|
*magick_restrict p; |
|
|
|
|
|
register Quantum |
|
|
*magick_restrict q; |
|
|
|
|
|
register ssize_t |
|
|
x; |
|
|
|
|
|
size_t |
|
|
length; |
|
|
|
|
|
ssize_t |
|
|
y; |
|
|
|
|
|
p=(const Quantum *) pixels; |
|
|
if (LocaleCompare(map,"BGR") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,*p++,q); |
|
|
SetPixelGreen(image,*p++,q); |
|
|
SetPixelRed(image,*p++,q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,*p++,q); |
|
|
SetPixelGreen(image,*p++,q); |
|
|
SetPixelRed(image,*p++,q); |
|
|
SetPixelAlpha(image,*p++,q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,*p++,q); |
|
|
SetPixelGreen(image,*p++,q); |
|
|
SetPixelRed(image,*p++,q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"I") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelGray(image,*p++,q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGB") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,*p++,q); |
|
|
SetPixelGreen(image,*p++,q); |
|
|
SetPixelBlue(image,*p++,q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,*p++,q); |
|
|
SetPixelGreen(image,*p++,q); |
|
|
SetPixelBlue(image,*p++,q); |
|
|
SetPixelAlpha(image,*p++,q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,*p++,q); |
|
|
SetPixelGreen(image,*p++,q); |
|
|
SetPixelBlue(image,*p++,q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
length=strlen(map); |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
for (i=0; i < (ssize_t) length; i++) |
|
|
{ |
|
|
switch (quantum_map[i]) |
|
|
{ |
|
|
case RedQuantum: |
|
|
case CyanQuantum: |
|
|
{ |
|
|
SetPixelRed(image,*p,q); |
|
|
break; |
|
|
} |
|
|
case GreenQuantum: |
|
|
case MagentaQuantum: |
|
|
{ |
|
|
SetPixelGreen(image,*p,q); |
|
|
break; |
|
|
} |
|
|
case BlueQuantum: |
|
|
case YellowQuantum: |
|
|
{ |
|
|
SetPixelBlue(image,*p,q); |
|
|
break; |
|
|
} |
|
|
case AlphaQuantum: |
|
|
{ |
|
|
SetPixelAlpha(image,*p,q); |
|
|
break; |
|
|
} |
|
|
case OpacityQuantum: |
|
|
{ |
|
|
SetPixelAlpha(image,*p,q); |
|
|
break; |
|
|
} |
|
|
case BlackQuantum: |
|
|
{ |
|
|
SetPixelBlack(image,*p,q); |
|
|
break; |
|
|
} |
|
|
case IndexQuantum: |
|
|
{ |
|
|
SetPixelGray(image,*p,q); |
|
|
break; |
|
|
} |
|
|
default: |
|
|
break; |
|
|
} |
|
|
p++; |
|
|
} |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
static void ImportShortPixel(Image *image,const RectangleInfo *roi, |
|
|
const char *magick_restrict map,const QuantumType *quantum_map, |
|
|
const void *pixels,ExceptionInfo *exception) |
|
|
{ |
|
|
register const unsigned short |
|
|
*magick_restrict p; |
|
|
|
|
|
register Quantum |
|
|
*magick_restrict q; |
|
|
|
|
|
register ssize_t |
|
|
x; |
|
|
|
|
|
size_t |
|
|
length; |
|
|
|
|
|
ssize_t |
|
|
y; |
|
|
|
|
|
p=(const unsigned short *) pixels; |
|
|
if (LocaleCompare(map,"BGR") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ScaleShortToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleShortToQuantum(*p++),q); |
|
|
SetPixelRed(image,ScaleShortToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ScaleShortToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleShortToQuantum(*p++),q); |
|
|
SetPixelRed(image,ScaleShortToQuantum(*p++),q); |
|
|
SetPixelAlpha(image,ScaleShortToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"BGRP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelBlue(image,ScaleShortToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleShortToQuantum(*p++),q); |
|
|
SetPixelRed(image,ScaleShortToQuantum(*p++),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"I") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelGray(image,ScaleShortToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGB") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ScaleShortToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleShortToQuantum(*p++),q); |
|
|
SetPixelBlue(image,ScaleShortToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBA") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ScaleShortToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleShortToQuantum(*p++),q); |
|
|
SetPixelBlue(image,ScaleShortToQuantum(*p++),q); |
|
|
SetPixelAlpha(image,ScaleShortToQuantum(*p++),q); |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (LocaleCompare(map,"RGBP") == 0) |
|
|
{ |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
SetPixelRed(image,ScaleShortToQuantum(*p++),q); |
|
|
SetPixelGreen(image,ScaleShortToQuantum(*p++),q); |
|
|
SetPixelBlue(image,ScaleShortToQuantum(*p++),q); |
|
|
p++; |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
return; |
|
|
} |
|
|
length=strlen(map); |
|
|
for (y=0; y < (ssize_t) roi->height; y++) |
|
|
{ |
|
|
q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); |
|
|
if (q == (Quantum *) NULL) |
|
|
break; |
|
|
for (x=0; x < (ssize_t) roi->width; x++) |
|
|
{ |
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
for (i=0; i < (ssize_t) length; i++) |
|
|
{ |
|
|
switch (quantum_map[i]) |
|
|
{ |
|
|
case RedQuantum: |
|
|
case CyanQuantum: |
|
|
{ |
|
|
SetPixelRed(image,ScaleShortToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case GreenQuantum: |
|
|
case MagentaQuantum: |
|
|
{ |
|
|
SetPixelGreen(image,ScaleShortToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case BlueQuantum: |
|
|
case YellowQuantum: |
|
|
{ |
|
|
SetPixelBlue(image,ScaleShortToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case AlphaQuantum: |
|
|
{ |
|
|
SetPixelAlpha(image,ScaleShortToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case OpacityQuantum: |
|
|
{ |
|
|
SetPixelAlpha(image,ScaleShortToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case BlackQuantum: |
|
|
{ |
|
|
SetPixelBlack(image,ScaleShortToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
case IndexQuantum: |
|
|
{ |
|
|
SetPixelGray(image,ScaleShortToQuantum(*p),q); |
|
|
break; |
|
|
} |
|
|
default: |
|
|
break; |
|
|
} |
|
|
p++; |
|
|
} |
|
|
q+=GetPixelChannels(image); |
|
|
} |
|
|
if (SyncAuthenticPixels(image,exception) == MagickFalse) |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
MagickExport MagickBooleanType ImportImagePixels(Image *image,const ssize_t x, |
|
|
const ssize_t y,const size_t width,const size_t height,const char *map, |
|
|
const StorageType type,const void *pixels,ExceptionInfo *exception) |
|
|
{ |
|
|
QuantumType |
|
|
*quantum_map; |
|
|
|
|
|
RectangleInfo |
|
|
roi; |
|
|
|
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
size_t |
|
|
length; |
|
|
|
|
|
/* |
|
|
Allocate image structure. |
|
|
*/ |
|
|
assert(image != (Image *) NULL); |
|
|
assert(image->signature == MagickCoreSignature); |
|
|
if (image->debug != MagickFalse) |
|
|
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
|
|
length=strlen(map); |
|
|
quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map)); |
|
|
if (quantum_map == (QuantumType *) NULL) |
|
|
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", |
|
|
image->filename); |
|
|
for (i=0; i < (ssize_t) length; i++) |
|
|
{ |
|
|
switch (map[i]) |
|
|
{ |
|
|
case 'a': |
|
|
case 'A': |
|
|
{ |
|
|
quantum_map[i]=AlphaQuantum; |
|
|
image->alpha_trait=BlendPixelTrait; |
|
|
break; |
|
|
} |
|
|
case 'B': |
|
|
case 'b': |
|
|
{ |
|
|
quantum_map[i]=BlueQuantum; |
|
|
break; |
|
|
} |
|
|
case 'C': |
|
|
case 'c': |
|
|
{ |
|
|
quantum_map[i]=CyanQuantum; |
|
|
(void) SetImageColorspace(image,CMYKColorspace,exception); |
|
|
break; |
|
|
} |
|
|
case 'g': |
|
|
case 'G': |
|
|
{ |
|
|
quantum_map[i]=GreenQuantum; |
|
|
break; |
|
|
} |
|
|
case 'K': |
|
|
case 'k': |
|
|
{ |
|
|
quantum_map[i]=BlackQuantum; |
|
|
(void) SetImageColorspace(image,CMYKColorspace,exception); |
|
|
break; |
|
|
} |
|
|
case 'I': |
|
|
case 'i': |
|
|
{ |
|
|
quantum_map[i]=IndexQuantum; |
|
|
(void) SetImageColorspace(image,GRAYColorspace,exception); |
|
|
break; |
|
|
} |
|
|
case 'm': |
|
|
case 'M': |
|
|
{ |
|
|
quantum_map[i]=MagentaQuantum; |
|
|
(void) SetImageColorspace(image,CMYKColorspace,exception); |
|
|
break; |
|
|
} |
|
|
case 'O': |
|
|
case 'o': |
|
|
{ |
|
|
quantum_map[i]=OpacityQuantum; |
|
|
image->alpha_trait=BlendPixelTrait; |
|
|
break; |
|
|
} |
|
|
case 'P': |
|
|
case 'p': |
|
|
{ |
|
|
quantum_map[i]=UndefinedQuantum; |
|
|
break; |
|
|
} |
|
|
case 'R': |
|
|
case 'r': |
|
|
{ |
|
|
quantum_map[i]=RedQuantum; |
|
|
break; |
|
|
} |
|
|
case 'Y': |
|
|
case 'y': |
|
|
{ |
|
|
quantum_map[i]=YellowQuantum; |
|
|
(void) SetImageColorspace(image,CMYKColorspace,exception); |
|
|
break; |
|
|
} |
|
|
default: |
|
|
{ |
|
|
quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); |
|
|
(void) ThrowMagickException(exception,GetMagickModule(),OptionError, |
|
|
"UnrecognizedPixelMap","`%s'",map); |
|
|
return(MagickFalse); |
|
|
} |
|
|
} |
|
|
} |
|
|
if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) |
|
|
return(MagickFalse); |
|
|
/* |
|
|
Transfer the pixels from the pixel data to the image. |
|
|
*/ |
|
|
roi.width=width; |
|
|
roi.height=height; |
|
|
roi.x=x; |
|
|
roi.y=y; |
|
|
switch (type) |
|
|
{ |
|
|
case CharPixel: |
|
|
{ |
|
|
ImportCharPixel(image,&roi,map,quantum_map,pixels,exception); |
|
|
break; |
|
|
} |
|
|
case DoublePixel: |
|
|
{ |
|
|
ImportDoublePixel(image,&roi,map,quantum_map,pixels,exception); |
|
|
break; |
|
|
} |
|
|
case FloatPixel: |
|
|
{ |
|
|
ImportFloatPixel(image,&roi,map,quantum_map,pixels,exception); |
|
|
break; |
|
|
} |
|
|
case LongPixel: |
|
|
{ |
|
|
ImportLongPixel(image,&roi,map,quantum_map,pixels,exception); |
|
|
break; |
|
|
} |
|
|
case LongLongPixel: |
|
|
{ |
|
|
ImportLongLongPixel(image,&roi,map,quantum_map,pixels,exception); |
|
|
break; |
|
|
} |
|
|
case QuantumPixel: |
|
|
{ |
|
|
ImportQuantumPixel(image,&roi,map,quantum_map,pixels,exception); |
|
|
break; |
|
|
} |
|
|
case ShortPixel: |
|
|
{ |
|
|
ImportShortPixel(image,&roi,map,quantum_map,pixels,exception); |
|
|
break; |
|
|
} |
|
|
default: |
|
|
{ |
|
|
quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); |
|
|
(void) ThrowMagickException(exception,GetMagickModule(),OptionError, |
|
|
"UnrecognizedStorageType","`%d'",type); |
|
|
break; |
|
|
} |
|
|
} |
|
|
quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); |
|
|
return(MagickTrue); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
+ 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 % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% InitializePixelChannelMap() defines the standard pixel component map. |
|
|
% |
|
|
% The format of the InitializePixelChannelMap() method is: |
|
|
% |
|
|
% void InitializePixelChannelMap(Image *image) |
|
|
% |
|
|
% A description of each parameter follows: |
|
|
% |
|
|
% o image: the image. |
|
|
% |
|
|
*/ |
|
|
|
|
|
static void LogPixelChannels(const Image *image) |
|
|
{ |
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
(void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%.20g]", |
|
|
image->filename,(double) image->number_channels); |
|
|
for (i=0; i < (ssize_t) image->number_channels; i++) |
|
|
{ |
|
|
char |
|
|
traits[MagickPathExtent]; |
|
|
|
|
|
const char |
|
|
*name; |
|
|
|
|
|
PixelChannel |
|
|
channel; |
|
|
|
|
|
switch (GetPixelChannelChannel(image,i)) |
|
|
{ |
|
|
case RedPixelChannel: |
|
|
{ |
|
|
name="red"; |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
name="cyan"; |
|
|
if (image->colorspace == GRAYColorspace) |
|
|
name="gray"; |
|
|
break; |
|
|
} |
|
|
case GreenPixelChannel: |
|
|
{ |
|
|
name="green"; |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
name="magenta"; |
|
|
break; |
|
|
} |
|
|
case BluePixelChannel: |
|
|
{ |
|
|
name="blue"; |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
name="yellow"; |
|
|
break; |
|
|
} |
|
|
case BlackPixelChannel: |
|
|
{ |
|
|
name="black"; |
|
|
if (image->storage_class == PseudoClass) |
|
|
name="index"; |
|
|
break; |
|
|
} |
|
|
case IndexPixelChannel: |
|
|
{ |
|
|
name="index"; |
|
|
break; |
|
|
} |
|
|
case AlphaPixelChannel: |
|
|
{ |
|
|
name="alpha"; |
|
|
break; |
|
|
} |
|
|
case ReadMaskPixelChannel: |
|
|
{ |
|
|
name="read-mask"; |
|
|
break; |
|
|
} |
|
|
case WriteMaskPixelChannel: |
|
|
{ |
|
|
name="write-mask"; |
|
|
break; |
|
|
} |
|
|
case MetaPixelChannel: |
|
|
{ |
|
|
name="meta"; |
|
|
break; |
|
|
} |
|
|
default: |
|
|
name="undefined"; |
|
|
} |
|
|
channel=GetPixelChannelChannel(image,i); |
|
|
*traits='\0'; |
|
|
if ((GetPixelChannelTraits(image,channel) & UpdatePixelTrait) != 0) |
|
|
(void) ConcatenateMagickString(traits,"update,",MagickPathExtent); |
|
|
if ((GetPixelChannelTraits(image,channel) & BlendPixelTrait) != 0) |
|
|
(void) ConcatenateMagickString(traits,"blend,",MagickPathExtent); |
|
|
if ((GetPixelChannelTraits(image,channel) & CopyPixelTrait) != 0) |
|
|
(void) ConcatenateMagickString(traits,"copy,",MagickPathExtent); |
|
|
if (*traits == '\0') |
|
|
(void) ConcatenateMagickString(traits,"undefined,",MagickPathExtent); |
|
|
traits[strlen(traits)-1]='\0'; |
|
|
(void) LogMagickEvent(PixelEvent,GetMagickModule()," %.20g: %s (%s)", |
|
|
(double) i,name,traits); |
|
|
} |
|
|
} |
|
|
|
|
|
MagickExport void InitializePixelChannelMap(Image *image) |
|
|
{ |
|
|
PixelTrait |
|
|
trait; |
|
|
|
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
ssize_t |
|
|
n; |
|
|
|
|
|
assert(image != (Image *) NULL); |
|
|
assert(image->signature == MagickCoreSignature); |
|
|
(void) ResetMagickMemory(image->channel_map,0,MaxPixelChannels* |
|
|
sizeof(*image->channel_map)); |
|
|
trait=UpdatePixelTrait; |
|
|
if (image->alpha_trait != UndefinedPixelTrait) |
|
|
trait=(PixelTrait) (trait | BlendPixelTrait); |
|
|
n=0; |
|
|
if (image->colorspace == GRAYColorspace) |
|
|
{ |
|
|
SetPixelChannelAttributes(image,BluePixelChannel,trait,n); |
|
|
SetPixelChannelAttributes(image,GreenPixelChannel,trait,n); |
|
|
SetPixelChannelAttributes(image,RedPixelChannel,trait,n++); |
|
|
} |
|
|
else |
|
|
{ |
|
|
SetPixelChannelAttributes(image,RedPixelChannel,trait,n++); |
|
|
SetPixelChannelAttributes(image,GreenPixelChannel,trait,n++); |
|
|
SetPixelChannelAttributes(image,BluePixelChannel,trait,n++); |
|
|
} |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
SetPixelChannelAttributes(image,BlackPixelChannel,trait,n++); |
|
|
if (image->alpha_trait != UndefinedPixelTrait) |
|
|
SetPixelChannelAttributes(image,AlphaPixelChannel,CopyPixelTrait,n++); |
|
|
if (image->storage_class == PseudoClass) |
|
|
SetPixelChannelAttributes(image,IndexPixelChannel,CopyPixelTrait,n++); |
|
|
if (image->read_mask != MagickFalse) |
|
|
SetPixelChannelAttributes(image,ReadMaskPixelChannel,CopyPixelTrait,n++); |
|
|
if (image->write_mask != MagickFalse) |
|
|
SetPixelChannelAttributes(image,WriteMaskPixelChannel,CopyPixelTrait,n++); |
|
|
assert((n+image->number_meta_channels) < MaxPixelChannels); |
|
|
for (i=0; i < (ssize_t) image->number_meta_channels; i++) |
|
|
SetPixelChannelAttributes(image,(PixelChannel) (MetaPixelChannel+i), |
|
|
CopyPixelTrait,n++); |
|
|
image->number_channels=(size_t) n; |
|
|
if (image->debug != MagickFalse) |
|
|
LogPixelChannels(image); |
|
|
SetImageChannelMask(image,image->channel_mask); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
% 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. |
|
|
% |
|
|
% Interpolation is restricted to just the specified channel. |
|
|
% |
|
|
% 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: the image. |
|
|
% |
|
|
% 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. |
|
|
% |
|
|
% o pixel: return the interpolated pixel here. |
|
|
% |
|
|
% o exception: return any errors or warnings in this structure. |
|
|
% |
|
|
*/ |
|
|
|
|
|
static inline void CatromWeights(const double x,double (*weights)[4]) |
|
|
{ |
|
|
double |
|
|
alpha, |
|
|
beta, |
|
|
gamma; |
|
|
|
|
|
/* |
|
|
Nicolas Robidoux' 10 flops (4* + 5- + 1+) refactoring of the computation |
|
|
of the standard four 1D Catmull-Rom weights. The sampling location is |
|
|
assumed between the second and third input pixel locations, and x is the |
|
|
position relative to the second input pixel location. Formulas originally |
|
|
derived for the VIPS (Virtual Image Processing System) library. |
|
|
*/ |
|
|
alpha=(double) 1.0-x; |
|
|
beta=(double) (-0.5)*x*alpha; |
|
|
(*weights)[0]=alpha*beta; |
|
|
(*weights)[3]=x*beta; |
|
|
/* |
|
|
The following computation of the inner weights from the outer ones work |
|
|
for all Keys cubics. |
|
|
*/ |
|
|
gamma=(*weights)[3]-(*weights)[0]; |
|
|
(*weights)[1]=alpha-(*weights)[0]+gamma; |
|
|
(*weights)[2]=x-(*weights)[3]-gamma; |
|
|
} |
|
|
|
|
|
static inline void SplineWeights(const double x,double (*weights)[4]) |
|
|
{ |
|
|
double |
|
|
alpha, |
|
|
beta; |
|
|
|
|
|
/* |
|
|
Nicolas Robidoux' 12 flops (6* + 5- + 1+) refactoring of the computation |
|
|
of the standard four 1D cubic B-spline smoothing weights. The sampling |
|
|
location is assumed between the second and third input pixel locations, |
|
|
and x is the position relative to the second input pixel location. |
|
|
*/ |
|
|
alpha=(double) 1.0-x; |
|
|
(*weights)[3]=(double) (1.0/6.0)*x*x*x; |
|
|
(*weights)[0]=(double) (1.0/6.0)*alpha*alpha*alpha; |
|
|
beta=(*weights)[3]-(*weights)[0]; |
|
|
(*weights)[1]=alpha-(*weights)[0]+beta; |
|
|
(*weights)[2]=x-(*weights)[3]-beta; |
|
|
} |
|
|
|
|
|
static inline double MeshInterpolate(const PointInfo *delta,const double p, |
|
|
const double x,const double y) |
|
|
{ |
|
|
return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p); |
|
|
} |
|
|
|
|
|
/* |
|
|
static inline ssize_t NearestNeighbor(const double x) |
|
|
{ |
|
|
if (x >= 0.0) |
|
|
return((ssize_t) (x+0.5)); |
|
|
return((ssize_t) (x-0.5)); |
|
|
} |
|
|
*/ |
|
|
|
|
|
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) |
|
|
{ |
|
|
double |
|
|
alpha[16], |
|
|
gamma, |
|
|
pixels[16]; |
|
|
|
|
|
MagickBooleanType |
|
|
status; |
|
|
|
|
|
PixelInterpolateMethod |
|
|
interpolate; |
|
|
|
|
|
PixelTrait |
|
|
traits; |
|
|
|
|
|
register const Quantum |
|
|
*p; |
|
|
|
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
ssize_t |
|
|
x_offset, |
|
|
y_offset; |
|
|
|
|
|
assert(image != (Image *) NULL); |
|
|
assert(image->signature == MagickCoreSignature); |
|
|
assert(image_view != (CacheView *) NULL); |
|
|
status=MagickTrue; |
|
|
*pixel=0.0; |
|
|
traits=GetPixelChannelTraits(image,channel); |
|
|
x_offset=(ssize_t) floor(x); |
|
|
y_offset=(ssize_t) floor(y); |
|
|
interpolate=method; |
|
|
if (interpolate == UndefinedInterpolatePixel) |
|
|
interpolate=image->interpolate; |
|
|
switch (interpolate) |
|
|
{ |
|
|
case AverageInterpolatePixel: /* nearest 4 neighbours */ |
|
|
case Average9InterpolatePixel: /* nearest 9 neighbours */ |
|
|
case Average16InterpolatePixel: /* nearest 16 neighbours */ |
|
|
{ |
|
|
ssize_t |
|
|
count; |
|
|
|
|
|
count=2; /* size of the area to average - default nearest 4 */ |
|
|
if (interpolate == Average9InterpolatePixel) |
|
|
{ |
|
|
count=3; |
|
|
x_offset=(ssize_t) (floor(x+0.5)-1); |
|
|
y_offset=(ssize_t) (floor(y+0.5)-1); |
|
|
} |
|
|
else |
|
|
if (interpolate == Average16InterpolatePixel) |
|
|
{ |
|
|
count=4; |
|
|
x_offset--; |
|
|
y_offset--; |
|
|
} |
|
|
p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,(size_t) count, |
|
|
(size_t) count,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
{ |
|
|
status=MagickFalse; |
|
|
break; |
|
|
} |
|
|
count*=count; /* Number of pixels to average */ |
|
|
if ((traits & BlendPixelTrait) == 0) |
|
|
for (i=0; i < (ssize_t) count; i++) |
|
|
{ |
|
|
alpha[i]=1.0; |
|
|
pixels[i]=(double) p[i*GetPixelChannels(image)+channel]; |
|
|
} |
|
|
else |
|
|
for (i=0; i < (ssize_t) count; i++) |
|
|
{ |
|
|
alpha[i]=QuantumScale*GetPixelAlpha(image,p+i* |
|
|
GetPixelChannels(image)); |
|
|
pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel]; |
|
|
} |
|
|
for (i=0; i < (ssize_t) count; i++) |
|
|
{ |
|
|
gamma=PerceptibleReciprocal(alpha[i])/count; |
|
|
*pixel+=gamma*pixels[i]; |
|
|
} |
|
|
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; |
|
|
} |
|
|
if ((traits & BlendPixelTrait) == 0) |
|
|
for (i=0; i < 4; i++) |
|
|
{ |
|
|
alpha[i]=1.0; |
|
|
pixels[i]=(double) 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; |
|
|
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=PerceptibleReciprocal(gamma); |
|
|
*pixel=gamma*(epsilon.y*(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y* |
|
|
(epsilon.x*pixels[2]+delta.x*pixels[3])); |
|
|
break; |
|
|
} |
|
|
case BlendInterpolatePixel: |
|
|
{ |
|
|
p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
{ |
|
|
status=MagickFalse; |
|
|
break; |
|
|
} |
|
|
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]; |
|
|
} |
|
|
gamma=1.0; /* number of pixels blended together (its variable) */ |
|
|
for (i=0; i <= 1L; i++) { |
|
|
if ((y-y_offset) >= 0.75) |
|
|
{ |
|
|
alpha[i]=alpha[i+2]; /* take right pixels */ |
|
|
pixels[i]=pixels[i+2]; |
|
|
} |
|
|
else |
|
|
if ((y-y_offset) > 0.25) |
|
|
{ |
|
|
gamma=2.0; /* blend both pixels in row */ |
|
|
alpha[i]+=alpha[i+2]; /* add up alpha weights */ |
|
|
pixels[i]+=pixels[i+2]; |
|
|
} |
|
|
} |
|
|
if ((x-x_offset) >= 0.75) |
|
|
{ |
|
|
alpha[0]=alpha[1]; /* take bottom row blend */ |
|
|
pixels[0]=pixels[1]; |
|
|
} |
|
|
else |
|
|
if ((x-x_offset) > 0.25) |
|
|
{ |
|
|
gamma*=2.0; /* blend both rows */ |
|
|
alpha[0]+=alpha[1]; /* add up alpha weights */ |
|
|
pixels[0]+=pixels[1]; |
|
|
} |
|
|
if (channel != AlphaPixelChannel) |
|
|
gamma=PerceptibleReciprocal(alpha[0]); /* (color) 1/alpha_weights */ |
|
|
else |
|
|
gamma=PerceptibleReciprocal(gamma); /* (alpha) 1/number_of_pixels */ |
|
|
*pixel=gamma*pixels[0]; |
|
|
break; |
|
|
} |
|
|
case CatromInterpolatePixel: |
|
|
{ |
|
|
double |
|
|
cx[4], |
|
|
cy[4]; |
|
|
|
|
|
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]=(double) 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]; |
|
|
} |
|
|
CatromWeights((double) (x-x_offset),&cx); |
|
|
CatromWeights((double) (y-y_offset),&cy); |
|
|
gamma=(channel == AlphaPixelChannel ? (double) 1.0 : |
|
|
PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]* |
|
|
alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]* |
|
|
alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]* |
|
|
alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+ |
|
|
cx[2]*alpha[14]+cx[3]*alpha[15]))); |
|
|
*pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+ |
|
|
cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]* |
|
|
pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+ |
|
|
cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]* |
|
|
pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15])); |
|
|
break; |
|
|
} |
|
|
case IntegerInterpolatePixel: |
|
|
{ |
|
|
p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
{ |
|
|
status=MagickFalse; |
|
|
break; |
|
|
} |
|
|
*pixel=(double) GetPixelChannel(image,channel,p); |
|
|
break; |
|
|
} |
|
|
case NearestInterpolatePixel: |
|
|
{ |
|
|
x_offset=(ssize_t) floor(x+0.5); |
|
|
y_offset=(ssize_t) floor(y+0.5); |
|
|
p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
{ |
|
|
status=MagickFalse; |
|
|
break; |
|
|
} |
|
|
*pixel=(double) GetPixelChannel(image,channel,p); |
|
|
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; |
|
|
} |
|
|
if ((traits & BlendPixelTrait) == 0) |
|
|
for (i=0; i < 4; i++) |
|
|
{ |
|
|
alpha[i]=1.0; |
|
|
pixels[i]=(double) 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=GetPixelLuma(image,p)-(double) |
|
|
GetPixelLuma(image,p+3*GetPixelChannels(image)); |
|
|
luminance.y=GetPixelLuma(image,p+GetPixelChannels(image))-(double) |
|
|
GetPixelLuma(image,p+2*GetPixelChannels(image)); |
|
|
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=PerceptibleReciprocal(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=PerceptibleReciprocal(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=PerceptibleReciprocal(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=PerceptibleReciprocal(gamma); |
|
|
*pixel=gamma*MeshInterpolate(&delta,pixels[3],pixels[2], |
|
|
pixels[1]); |
|
|
} |
|
|
} |
|
|
break; |
|
|
} |
|
|
case SplineInterpolatePixel: |
|
|
{ |
|
|
double |
|
|
cx[4], |
|
|
cy[4]; |
|
|
|
|
|
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]=(double) 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]; |
|
|
} |
|
|
SplineWeights((double) (x-x_offset),&cx); |
|
|
SplineWeights((double) (y-y_offset),&cy); |
|
|
gamma=(channel == AlphaPixelChannel ? (double) 1.0 : |
|
|
PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]* |
|
|
alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]* |
|
|
alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]* |
|
|
alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+ |
|
|
cx[2]*alpha[14]+cx[3]*alpha[15]))); |
|
|
*pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+ |
|
|
cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]* |
|
|
pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+ |
|
|
cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]* |
|
|
pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15])); |
|
|
break; |
|
|
} |
|
|
} |
|
|
return(status); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
% 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. |
|
|
% |
|
|
% Interpolation is restricted to just the current channel setting of the |
|
|
% destination image into which the color is to be stored |
|
|
% |
|
|
% 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, for the interpolated color |
|
|
% |
|
|
% 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; |
|
|
|
|
|
double |
|
|
alpha[16], |
|
|
gamma, |
|
|
pixels[16]; |
|
|
|
|
|
register const Quantum |
|
|
*p; |
|
|
|
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
ssize_t |
|
|
x_offset, |
|
|
y_offset; |
|
|
|
|
|
PixelInterpolateMethod |
|
|
interpolate; |
|
|
|
|
|
assert(source != (Image *) NULL); |
|
|
assert(source->signature == MagickCoreSignature); |
|
|
assert(source_view != (CacheView *) NULL); |
|
|
status=MagickTrue; |
|
|
x_offset=(ssize_t) floor(x); |
|
|
y_offset=(ssize_t) floor(y); |
|
|
interpolate=method; |
|
|
if (interpolate == UndefinedInterpolatePixel) |
|
|
interpolate=source->interpolate; |
|
|
switch (interpolate) |
|
|
{ |
|
|
case AverageInterpolatePixel: /* nearest 4 neighbours */ |
|
|
case Average9InterpolatePixel: /* nearest 9 neighbours */ |
|
|
case Average16InterpolatePixel: /* nearest 16 neighbours */ |
|
|
{ |
|
|
ssize_t |
|
|
count; |
|
|
|
|
|
count=2; /* size of the area to average - default nearest 4 */ |
|
|
if (interpolate == Average9InterpolatePixel) |
|
|
{ |
|
|
count=3; |
|
|
x_offset=(ssize_t) (floor(x+0.5)-1); |
|
|
y_offset=(ssize_t) (floor(y+0.5)-1); |
|
|
} |
|
|
else |
|
|
if (interpolate == Average16InterpolatePixel) |
|
|
{ |
|
|
count=4; |
|
|
x_offset--; |
|
|
y_offset--; |
|
|
} |
|
|
p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,(size_t) count, |
|
|
(size_t) count,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
{ |
|
|
status=MagickFalse; |
|
|
break; |
|
|
} |
|
|
count*=count; /* Number of pixels to average */ |
|
|
for (i=0; i < (ssize_t) GetPixelChannels(source); i++) |
|
|
{ |
|
|
double |
|
|
sum; |
|
|
|
|
|
register ssize_t |
|
|
j; |
|
|
|
|
|
PixelChannel channel=GetPixelChannelChannel(source,i); |
|
|
PixelTrait traits=GetPixelChannelTraits(source,channel); |
|
|
PixelTrait destination_traits=GetPixelChannelTraits(destination, |
|
|
channel); |
|
|
if ((traits == UndefinedPixelTrait) || |
|
|
(destination_traits == UndefinedPixelTrait)) |
|
|
continue; |
|
|
for (j=0; j < (ssize_t) count; j++) |
|
|
pixels[j]=(double) p[j*GetPixelChannels(source)+i]; |
|
|
sum=0.0; |
|
|
if ((traits & BlendPixelTrait) == 0) |
|
|
{ |
|
|
for (j=0; j < (ssize_t) count; j++) |
|
|
sum+=pixels[j]; |
|
|
sum/=count; |
|
|
SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel); |
|
|
continue; |
|
|
} |
|
|
for (j=0; j < (ssize_t) count; j++) |
|
|
{ |
|
|
alpha[j]=QuantumScale*GetPixelAlpha(source,p+j* |
|
|
GetPixelChannels(source)); |
|
|
pixels[j]*=alpha[j]; |
|
|
gamma=PerceptibleReciprocal(alpha[j]); |
|
|
sum+=gamma*pixels[j]; |
|
|
} |
|
|
sum/=count; |
|
|
SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel); |
|
|
} |
|
|
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; |
|
|
|
|
|
PixelChannel channel=GetPixelChannelChannel(source,i); |
|
|
PixelTrait traits=GetPixelChannelTraits(source,channel); |
|
|
PixelTrait destination_traits=GetPixelChannelTraits(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]=(double) p[i]; |
|
|
pixels[1]=(double) p[GetPixelChannels(source)+i]; |
|
|
pixels[2]=(double) p[2*GetPixelChannels(source)+i]; |
|
|
pixels[3]=(double) p[3*GetPixelChannels(source)+i]; |
|
|
if ((traits & BlendPixelTrait) == 0) |
|
|
{ |
|
|
gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x))); |
|
|
gamma=PerceptibleReciprocal(gamma); |
|
|
SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y* |
|
|
(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x* |
|
|
pixels[2]+delta.x*pixels[3]))),pixel); |
|
|
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=PerceptibleReciprocal(gamma); |
|
|
SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y* |
|
|
(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*pixels[2]+ |
|
|
delta.x*pixels[3]))),pixel); |
|
|
} |
|
|
break; |
|
|
} |
|
|
case BlendInterpolatePixel: |
|
|
{ |
|
|
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++) |
|
|
{ |
|
|
register ssize_t |
|
|
j; |
|
|
|
|
|
PixelChannel channel=GetPixelChannelChannel(source,i); |
|
|
PixelTrait traits=GetPixelChannelTraits(source,channel); |
|
|
PixelTrait destination_traits=GetPixelChannelTraits(destination, |
|
|
channel); |
|
|
if ((traits == UndefinedPixelTrait) || |
|
|
(destination_traits == UndefinedPixelTrait)) |
|
|
continue; |
|
|
if (source->alpha_trait != BlendPixelTrait) |
|
|
for (j=0; j < 4; j++) |
|
|
{ |
|
|
alpha[j]=1.0; |
|
|
pixels[j]=(double) p[j*GetPixelChannels(source)+i]; |
|
|
} |
|
|
else |
|
|
for (j=0; j < 4; j++) |
|
|
{ |
|
|
alpha[j]=QuantumScale*GetPixelAlpha(source,p+j* |
|
|
GetPixelChannels(source)); |
|
|
pixels[j]=(double) p[j*GetPixelChannels(source)+i]; |
|
|
if (channel != AlphaPixelChannel) |
|
|
pixels[j]*=alpha[j]; |
|
|
} |
|
|
gamma=1.0; /* number of pixels blended together (its variable) */ |
|
|
for (j=0; j <= 1L; j++) |
|
|
{ |
|
|
if ((y-y_offset) >= 0.75) |
|
|
{ |
|
|
alpha[j]=alpha[j+2]; /* take right pixels */ |
|
|
pixels[j]=pixels[j+2]; |
|
|
} |
|
|
else |
|
|
if ((y-y_offset) > 0.25) |
|
|
{ |
|
|
gamma=2.0; /* blend both pixels in row */ |
|
|
alpha[j]+=alpha[j+2]; /* add up alpha weights */ |
|
|
pixels[j]+=pixels[j+2]; |
|
|
} |
|
|
} |
|
|
if ((x-x_offset) >= 0.75) |
|
|
{ |
|
|
alpha[0]=alpha[1]; /* take bottom row blend */ |
|
|
pixels[0]=pixels[1]; |
|
|
} |
|
|
else |
|
|
if ((x-x_offset) > 0.25) |
|
|
{ |
|
|
gamma*=2.0; /* blend both rows */ |
|
|
alpha[0]+=alpha[1]; /* add up alpha weights */ |
|
|
pixels[0]+=pixels[1]; |
|
|
} |
|
|
if (channel != AlphaPixelChannel) |
|
|
gamma=PerceptibleReciprocal(alpha[0]); /* (color) 1/alpha_weights */ |
|
|
else |
|
|
gamma=PerceptibleReciprocal(gamma); /* (alpha) 1/number_of_pixels */ |
|
|
SetPixelChannel(destination,channel,ClampToQuantum(gamma*pixels[0]), |
|
|
pixel); |
|
|
} |
|
|
break; |
|
|
} |
|
|
case CatromInterpolatePixel: |
|
|
{ |
|
|
double |
|
|
cx[4], |
|
|
cy[4]; |
|
|
|
|
|
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; |
|
|
|
|
|
PixelChannel channel=GetPixelChannelChannel(source,i); |
|
|
PixelTrait traits=GetPixelChannelTraits(source,channel); |
|
|
PixelTrait destination_traits=GetPixelChannelTraits(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]=(double) 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]; |
|
|
} |
|
|
CatromWeights((double) (x-x_offset),&cx); |
|
|
CatromWeights((double) (y-y_offset),&cy); |
|
|
gamma=((traits & BlendPixelTrait) ? (double) (1.0) : |
|
|
PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]* |
|
|
alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]* |
|
|
alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]* |
|
|
alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+ |
|
|
cx[2]*alpha[14]+cx[3]*alpha[15]))); |
|
|
SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]* |
|
|
pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]* |
|
|
(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+ |
|
|
cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]* |
|
|
pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]* |
|
|
pixels[14]+cx[3]*pixels[15]))),pixel); |
|
|
} |
|
|
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++) |
|
|
{ |
|
|
PixelChannel channel=GetPixelChannelChannel(source,i); |
|
|
PixelTrait traits=GetPixelChannelTraits(source,channel); |
|
|
PixelTrait destination_traits=GetPixelChannelTraits(destination, |
|
|
channel); |
|
|
if ((traits == UndefinedPixelTrait) || |
|
|
(destination_traits == UndefinedPixelTrait)) |
|
|
continue; |
|
|
SetPixelChannel(destination,channel,p[i],pixel); |
|
|
} |
|
|
break; |
|
|
} |
|
|
case NearestInterpolatePixel: |
|
|
{ |
|
|
x_offset=(ssize_t) floor(x+0.5); |
|
|
y_offset=(ssize_t) floor(y+0.5); |
|
|
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++) |
|
|
{ |
|
|
PixelChannel channel=GetPixelChannelChannel(source,i); |
|
|
PixelTrait traits=GetPixelChannelTraits(source,channel); |
|
|
PixelTrait destination_traits=GetPixelChannelTraits(destination, |
|
|
channel); |
|
|
if ((traits == UndefinedPixelTrait) || |
|
|
(destination_traits == UndefinedPixelTrait)) |
|
|
continue; |
|
|
SetPixelChannel(destination,channel,p[i],pixel); |
|
|
} |
|
|
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; |
|
|
|
|
|
PixelChannel channel=GetPixelChannelChannel(source,i); |
|
|
PixelTrait traits=GetPixelChannelTraits(source,channel); |
|
|
PixelTrait destination_traits=GetPixelChannelTraits(destination, |
|
|
channel); |
|
|
if ((traits == UndefinedPixelTrait) || |
|
|
(destination_traits == UndefinedPixelTrait)) |
|
|
continue; |
|
|
pixels[0]=(double) p[i]; |
|
|
pixels[1]=(double) p[GetPixelChannels(source)+i]; |
|
|
pixels[2]=(double) p[2*GetPixelChannels(source)+i]; |
|
|
pixels[3]=(double) 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=fabs((double) (GetPixelLuma(source,p)- |
|
|
GetPixelLuma(source,p+3*GetPixelChannels(source)))); |
|
|
luminance.y=fabs((double) (GetPixelLuma(source,p+ |
|
|
GetPixelChannels(source))-GetPixelLuma(source,p+2* |
|
|
GetPixelChannels(source)))); |
|
|
if (luminance.x < 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=PerceptibleReciprocal(gamma); |
|
|
SetPixelChannel(destination,channel,ClampToQuantum(gamma* |
|
|
MeshInterpolate(&delta,pixels[2],pixels[3],pixels[0])),pixel); |
|
|
} |
|
|
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=PerceptibleReciprocal(gamma); |
|
|
SetPixelChannel(destination,channel,ClampToQuantum(gamma* |
|
|
MeshInterpolate(&delta,pixels[1],pixels[0],pixels[3])),pixel); |
|
|
} |
|
|
} |
|
|
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=PerceptibleReciprocal(gamma); |
|
|
SetPixelChannel(destination,channel,ClampToQuantum(gamma* |
|
|
MeshInterpolate(&delta,pixels[0],pixels[1],pixels[2])),pixel); |
|
|
} |
|
|
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=PerceptibleReciprocal(gamma); |
|
|
SetPixelChannel(destination,channel,ClampToQuantum(gamma* |
|
|
MeshInterpolate(&delta,pixels[3],pixels[2],pixels[1])),pixel); |
|
|
} |
|
|
} |
|
|
} |
|
|
break; |
|
|
} |
|
|
case SplineInterpolatePixel: |
|
|
{ |
|
|
double |
|
|
cx[4], |
|
|
cy[4]; |
|
|
|
|
|
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; |
|
|
|
|
|
PixelChannel channel=GetPixelChannelChannel(source,i); |
|
|
PixelTrait traits=GetPixelChannelTraits(source,channel); |
|
|
PixelTrait destination_traits=GetPixelChannelTraits(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]=(double) 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]; |
|
|
} |
|
|
SplineWeights((double) (x-x_offset),&cx); |
|
|
SplineWeights((double) (y-y_offset),&cy); |
|
|
gamma=((traits & BlendPixelTrait) ? (double) (1.0) : |
|
|
PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]* |
|
|
alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]* |
|
|
alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]* |
|
|
alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+ |
|
|
cx[2]*alpha[14]+cx[3]*alpha[15]))); |
|
|
SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]* |
|
|
pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]* |
|
|
(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+ |
|
|
cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]* |
|
|
pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]* |
|
|
pixels[14]+cx[3]*pixels[15]))),pixel); |
|
|
} |
|
|
break; |
|
|
} |
|
|
} |
|
|
return(status); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
% 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. |
|
|
% |
|
|
% Interpolation is restricted to just RGBKA channels. |
|
|
% |
|
|
% 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,double *alpha) |
|
|
{ |
|
|
if (image->alpha_trait == UndefinedPixelTrait) |
|
|
{ |
|
|
*alpha=1.0; |
|
|
pixel_info->red=(double) GetPixelRed(image,pixel); |
|
|
pixel_info->green=(double) GetPixelGreen(image,pixel); |
|
|
pixel_info->blue=(double) GetPixelBlue(image,pixel); |
|
|
pixel_info->black=0.0; |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
pixel_info->black=(double) GetPixelBlack(image,pixel); |
|
|
pixel_info->alpha=(double) 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=(double) GetPixelAlpha(image,pixel); |
|
|
} |
|
|
|
|
|
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; |
|
|
|
|
|
double |
|
|
alpha[16], |
|
|
gamma; |
|
|
|
|
|
PixelInfo |
|
|
pixels[16]; |
|
|
|
|
|
register const Quantum |
|
|
*p; |
|
|
|
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
ssize_t |
|
|
x_offset, |
|
|
y_offset; |
|
|
|
|
|
PixelInterpolateMethod |
|
|
interpolate; |
|
|
|
|
|
assert(image != (Image *) NULL); |
|
|
assert(image->signature == MagickCoreSignature); |
|
|
assert(image_view != (CacheView *) NULL); |
|
|
status=MagickTrue; |
|
|
x_offset=(ssize_t) floor(x); |
|
|
y_offset=(ssize_t) floor(y); |
|
|
interpolate=method; |
|
|
if (interpolate == UndefinedInterpolatePixel) |
|
|
interpolate=image->interpolate; |
|
|
(void) ResetMagickMemory(&pixels,0,sizeof(pixels)); |
|
|
switch (interpolate) |
|
|
{ |
|
|
case AverageInterpolatePixel: /* nearest 4 neighbours */ |
|
|
case Average9InterpolatePixel: /* nearest 9 neighbours */ |
|
|
case Average16InterpolatePixel: /* nearest 16 neighbours */ |
|
|
{ |
|
|
ssize_t |
|
|
count; |
|
|
|
|
|
count=2; /* size of the area to average - default nearest 4 */ |
|
|
if (interpolate == Average9InterpolatePixel) |
|
|
{ |
|
|
count=3; |
|
|
x_offset=(ssize_t) (floor(x+0.5)-1); |
|
|
y_offset=(ssize_t) (floor(y+0.5)-1); |
|
|
} |
|
|
else if (interpolate == Average16InterpolatePixel) |
|
|
{ |
|
|
count=4; |
|
|
x_offset--; |
|
|
y_offset--; |
|
|
} |
|
|
p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,(size_t) count, |
|
|
(size_t) count,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
{ |
|
|
status=MagickFalse; |
|
|
break; |
|
|
} |
|
|
pixel->red=0.0; |
|
|
pixel->green=0.0; |
|
|
pixel->blue=0.0; |
|
|
pixel->black=0.0; |
|
|
pixel->alpha=0.0; |
|
|
count*=count; /* number of pixels - square of size */ |
|
|
for (i=0; i < (ssize_t) count; i++) |
|
|
{ |
|
|
AlphaBlendPixelInfo(image,p,pixels,alpha); |
|
|
gamma=PerceptibleReciprocal(alpha[0]); |
|
|
pixel->red+=gamma*pixels[0].red; |
|
|
pixel->green+=gamma*pixels[0].green; |
|
|
pixel->blue+=gamma*pixels[0].blue; |
|
|
pixel->black+=gamma*pixels[0].black; |
|
|
pixel->alpha+=pixels[0].alpha; |
|
|
p += GetPixelChannels(image); |
|
|
} |
|
|
gamma=1.0/count; /* average weighting of each pixel in area */ |
|
|
pixel->red*=gamma; |
|
|
pixel->green*=gamma; |
|
|
pixel->blue*=gamma; |
|
|
pixel->black*=gamma; |
|
|
pixel->alpha*=gamma; |
|
|
break; |
|
|
} |
|
|
case BackgroundInterpolatePixel: |
|
|
{ |
|
|
*pixel=image->background_color; /* Copy PixelInfo Structure */ |
|
|
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; |
|
|
} |
|
|
for (i=0; i < 4L; i++) |
|
|
AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i); |
|
|
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=PerceptibleReciprocal(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=PerceptibleReciprocal(gamma); |
|
|
pixel->alpha=gamma*(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 BlendInterpolatePixel: |
|
|
{ |
|
|
p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
{ |
|
|
status=MagickFalse; |
|
|
break; |
|
|
} |
|
|
for (i=0; i < 4L; i++) |
|
|
{ |
|
|
GetPixelInfoPixel(image,p+i*GetPixelChannels(image),pixels+i); |
|
|
AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i); |
|
|
} |
|
|
gamma=1.0; /* number of pixels blended together (its variable) */ |
|
|
for (i=0; i <= 1L; i++) |
|
|
{ |
|
|
if ((y-y_offset) >= 0.75) |
|
|
{ |
|
|
alpha[i]=alpha[i+2]; /* take right pixels */ |
|
|
pixels[i]=pixels[i+2]; |
|
|
} |
|
|
else |
|
|
if ((y-y_offset) > 0.25) |
|
|
{ |
|
|
gamma=2.0; /* blend both pixels in row */ |
|
|
alpha[i]+=alpha[i+2]; /* add up alpha weights */ |
|
|
pixels[i].red+=pixels[i+2].red; |
|
|
pixels[i].green+=pixels[i+2].green; |
|
|
pixels[i].blue+=pixels[i+2].blue; |
|
|
pixels[i].black+=pixels[i+2].black; |
|
|
pixels[i].alpha+=pixels[i+2].alpha; |
|
|
} |
|
|
} |
|
|
if ((x-x_offset) >= 0.75) |
|
|
{ |
|
|
alpha[0]=alpha[1]; |
|
|
pixels[0]=pixels[1]; |
|
|
} |
|
|
else |
|
|
if ((x-x_offset) > 0.25) |
|
|
{ |
|
|
gamma*=2.0; /* blend both rows */ |
|
|
alpha[0]+= alpha[1]; /* add up alpha weights */ |
|
|
pixels[0].red+=pixels[1].red; |
|
|
pixels[0].green+=pixels[1].green; |
|
|
pixels[0].blue+=pixels[1].blue; |
|
|
pixels[0].black+=pixels[1].black; |
|
|
pixels[0].alpha+=pixels[1].alpha; |
|
|
} |
|
|
gamma=1.0/gamma; |
|
|
alpha[0]=PerceptibleReciprocal(alpha[0]); |
|
|
pixel->red=alpha[0]*pixels[0].red; |
|
|
pixel->green=alpha[0]*pixels[0].green; /* divide by sum of alpha */ |
|
|
pixel->blue=alpha[0]*pixels[0].blue; |
|
|
pixel->black=alpha[0]*pixels[0].black; |
|
|
pixel->alpha=gamma*pixels[0].alpha; /* divide by number of pixels */ |
|
|
break; |
|
|
} |
|
|
case CatromInterpolatePixel: |
|
|
{ |
|
|
double |
|
|
cx[4], |
|
|
cy[4]; |
|
|
|
|
|
p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4, |
|
|
exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
{ |
|
|
status=MagickFalse; |
|
|
break; |
|
|
} |
|
|
for (i=0; i < 16L; i++) |
|
|
AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i); |
|
|
CatromWeights((double) (x-x_offset),&cx); |
|
|
CatromWeights((double) (y-y_offset),&cy); |
|
|
pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*pixels[1].red+cx[2]* |
|
|
pixels[2].red+cx[3]*pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]* |
|
|
pixels[5].red+cx[2]*pixels[6].red+cx[3]*pixels[7].red)+cy[2]*(cx[0]* |
|
|
pixels[8].red+cx[1]*pixels[9].red+cx[2]*pixels[10].red+cx[3]* |
|
|
pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*pixels[13].red+cx[2]* |
|
|
pixels[14].red+cx[3]*pixels[15].red)); |
|
|
pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*pixels[1].green+cx[2]* |
|
|
pixels[2].green+cx[3]*pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+ |
|
|
cx[1]*pixels[5].green+cx[2]*pixels[6].green+cx[3]*pixels[7].green)+ |
|
|
cy[2]*(cx[0]*pixels[8].green+cx[1]*pixels[9].green+cx[2]* |
|
|
pixels[10].green+cx[3]*pixels[11].green)+cy[3]*(cx[0]* |
|
|
pixels[12].green+cx[1]*pixels[13].green+cx[2]*pixels[14].green+cx[3]* |
|
|
pixels[15].green)); |
|
|
pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*pixels[1].blue+cx[2]* |
|
|
pixels[2].blue+cx[3]*pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]* |
|
|
pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*pixels[7].blue)+cy[2]*(cx[0]* |
|
|
pixels[8].blue+cx[1]*pixels[9].blue+cx[2]*pixels[10].blue+cx[3]* |
|
|
pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*pixels[13].blue+ |
|
|
cx[2]*pixels[14].blue+cx[3]*pixels[15].blue)); |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*pixels[1].black+cx[2]* |
|
|
pixels[2].black+cx[3]*pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+ |
|
|
cx[1]*pixels[5].black+cx[2]*pixels[6].black+cx[3]*pixels[7].black)+ |
|
|
cy[2]*(cx[0]*pixels[8].black+cx[1]*pixels[9].black+cx[2]* |
|
|
pixels[10].black+cx[3]*pixels[11].black)+cy[3]*(cx[0]* |
|
|
pixels[12].black+cx[1]*pixels[13].black+cx[2]*pixels[14].black+cx[3]* |
|
|
pixels[15].black)); |
|
|
pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*pixels[1].alpha+cx[2]* |
|
|
pixels[2].alpha+cx[3]*pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+ |
|
|
cx[1]*pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*pixels[7].alpha)+ |
|
|
cy[2]*(cx[0]*pixels[8].alpha+cx[1]*pixels[9].alpha+cx[2]* |
|
|
pixels[10].alpha+cx[3]*pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+ |
|
|
cx[1]*pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha)); |
|
|
break; |
|
|
} |
|
|
case IntegerInterpolatePixel: |
|
|
{ |
|
|
p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
{ |
|
|
status=MagickFalse; |
|
|
break; |
|
|
} |
|
|
GetPixelInfoPixel(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=GetPixelLuma(image,p)-(double) |
|
|
GetPixelLuma(image,p+3*GetPixelChannels(image)); |
|
|
luminance.y=GetPixelLuma(image,p+GetPixelChannels(image))-(double) |
|
|
GetPixelLuma(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]); |
|
|
gamma=PerceptibleReciprocal(gamma); |
|
|
pixel->red=gamma*MeshInterpolate(&delta,pixels[2].red, |
|
|
pixels[3].red,pixels[0].red); |
|
|
pixel->green=gamma*MeshInterpolate(&delta,pixels[2].green, |
|
|
pixels[3].green,pixels[0].green); |
|
|
pixel->blue=gamma*MeshInterpolate(&delta,pixels[2].blue, |
|
|
pixels[3].blue,pixels[0].blue); |
|
|
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). |
|
|
*/ |
|
|
delta.x=1.0-delta.x; |
|
|
gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]); |
|
|
gamma=PerceptibleReciprocal(gamma); |
|
|
pixel->red=gamma*MeshInterpolate(&delta,pixels[1].red, |
|
|
pixels[0].red,pixels[3].red); |
|
|
pixel->green=gamma*MeshInterpolate(&delta,pixels[1].green, |
|
|
pixels[0].green,pixels[3].green); |
|
|
pixel->blue=gamma*MeshInterpolate(&delta,pixels[1].blue, |
|
|
pixels[0].blue,pixels[3].blue); |
|
|
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); |
|
|
} |
|
|
} |
|
|
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=PerceptibleReciprocal(gamma); |
|
|
pixel->red=gamma*MeshInterpolate(&delta,pixels[0].red, |
|
|
pixels[1].red,pixels[2].red); |
|
|
pixel->green=gamma*MeshInterpolate(&delta,pixels[0].green, |
|
|
pixels[1].green,pixels[2].green); |
|
|
pixel->blue=gamma*MeshInterpolate(&delta,pixels[0].blue, |
|
|
pixels[1].blue,pixels[2].blue); |
|
|
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); |
|
|
} |
|
|
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=PerceptibleReciprocal(gamma); |
|
|
pixel->red=gamma*MeshInterpolate(&delta,pixels[3].red, |
|
|
pixels[2].red,pixels[1].red); |
|
|
pixel->green=gamma*MeshInterpolate(&delta,pixels[3].green, |
|
|
pixels[2].green,pixels[1].green); |
|
|
pixel->blue=gamma*MeshInterpolate(&delta,pixels[3].blue, |
|
|
pixels[2].blue,pixels[1].blue); |
|
|
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; |
|
|
} |
|
|
case NearestInterpolatePixel: |
|
|
{ |
|
|
x_offset=(ssize_t) floor(x+0.5); |
|
|
y_offset=(ssize_t) floor(y+0.5); |
|
|
p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
{ |
|
|
status=MagickFalse; |
|
|
break; |
|
|
} |
|
|
GetPixelInfoPixel(image,p,pixel); |
|
|
break; |
|
|
} |
|
|
case SplineInterpolatePixel: |
|
|
{ |
|
|
double |
|
|
cx[4], |
|
|
cy[4]; |
|
|
|
|
|
p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4, |
|
|
exception); |
|
|
if (p == (const Quantum *) NULL) |
|
|
{ |
|
|
status=MagickFalse; |
|
|
break; |
|
|
} |
|
|
for (i=0; i < 16L; i++) |
|
|
AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i); |
|
|
SplineWeights((double) (x-x_offset),&cx); |
|
|
SplineWeights((double) (y-y_offset),&cy); |
|
|
pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*pixels[1].red+cx[2]* |
|
|
pixels[2].red+cx[3]*pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]* |
|
|
pixels[5].red+cx[2]*pixels[6].red+cx[3]*pixels[7].red)+cy[2]*(cx[0]* |
|
|
pixels[8].red+cx[1]*pixels[9].red+cx[2]*pixels[10].red+cx[3]* |
|
|
pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*pixels[13].red+cx[2]* |
|
|
pixels[14].red+cx[3]*pixels[15].red)); |
|
|
pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*pixels[1].green+cx[2]* |
|
|
pixels[2].green+cx[3]*pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+ |
|
|
cx[1]*pixels[5].green+cx[2]*pixels[6].green+cx[3]*pixels[7].green)+ |
|
|
cy[2]*(cx[0]*pixels[8].green+cx[1]*pixels[9].green+cx[2]* |
|
|
pixels[10].green+cx[3]*pixels[11].green)+cy[3]*(cx[0]*pixels[12].green+ |
|
|
cx[1]*pixels[13].green+cx[2]*pixels[14].green+cx[3]*pixels[15].green)); |
|
|
pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*pixels[1].blue+cx[2]* |
|
|
pixels[2].blue+cx[3]*pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]* |
|
|
pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*pixels[7].blue)+cy[2]*(cx[0]* |
|
|
pixels[8].blue+cx[1]*pixels[9].blue+cx[2]*pixels[10].blue+cx[3]* |
|
|
pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*pixels[13].blue+ |
|
|
cx[2]*pixels[14].blue+cx[3]*pixels[15].blue)); |
|
|
if (image->colorspace == CMYKColorspace) |
|
|
pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*pixels[1].black+cx[2]* |
|
|
pixels[2].black+cx[3]*pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+ |
|
|
cx[1]*pixels[5].black+cx[2]*pixels[6].black+cx[3]*pixels[7].black)+ |
|
|
cy[2]*(cx[0]*pixels[8].black+cx[1]*pixels[9].black+cx[2]* |
|
|
pixels[10].black+cx[3]*pixels[11].black)+cy[3]*(cx[0]* |
|
|
pixels[12].black+cx[1]*pixels[13].black+cx[2]*pixels[14].black+cx[3]* |
|
|
pixels[15].black)); |
|
|
pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*pixels[1].alpha+cx[2]* |
|
|
pixels[2].alpha+cx[3]*pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+ |
|
|
cx[1]*pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*pixels[7].alpha)+ |
|
|
cy[2]*(cx[0]*pixels[8].alpha+cx[1]*pixels[9].alpha+cx[2]* |
|
|
pixels[10].alpha+cx[3]*pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+ |
|
|
cx[1]*pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha)); |
|
|
break; |
|
|
} |
|
|
} |
|
|
return(status); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
+ I s F u z z y E q u i v a l e n c e P i x e l % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% IsFuzzyEquivalencePixel() returns MagickTrue if the distance between two |
|
|
% pixels is less than the specified distance in a linear three (or four) |
|
|
% dimensional color space. |
|
|
% |
|
|
% The format of the IsFuzzyEquivalencePixel method is: |
|
|
% |
|
|
% void IsFuzzyEquivalencePixel(const Image *source,const Quantum *p, |
|
|
% const Image *destination,const Quantum *q) |
|
|
% |
|
|
% A description of each parameter follows: |
|
|
% |
|
|
% o source: the source image. |
|
|
% |
|
|
% o p: Pixel p. |
|
|
% |
|
|
% o destination: the destination image. |
|
|
% |
|
|
% o q: Pixel q. |
|
|
% |
|
|
*/ |
|
|
MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source, |
|
|
const Quantum *p,const Image *destination,const Quantum *q) |
|
|
{ |
|
|
double |
|
|
fuzz, |
|
|
pixel; |
|
|
|
|
|
register double |
|
|
distance, |
|
|
scale; |
|
|
|
|
|
fuzz=GetFuzzyColorDistance(source,destination); |
|
|
scale=1.0; |
|
|
distance=0.0; |
|
|
if (source->alpha_trait != UndefinedPixelTrait || |
|
|
destination->alpha_trait != UndefinedPixelTrait) |
|
|
{ |
|
|
/* |
|
|
Transparencies are involved - set alpha distance |
|
|
*/ |
|
|
pixel=GetPixelAlpha(source,p)-(double) GetPixelAlpha(destination,q); |
|
|
distance=pixel*pixel; |
|
|
if (distance > fuzz) |
|
|
return(MagickFalse); |
|
|
/* |
|
|
Generate a alpha scaling factor to generate a 4D cone on colorspace |
|
|
Note that if one color is transparent, distance has no color component. |
|
|
*/ |
|
|
if (source->alpha_trait != UndefinedPixelTrait) |
|
|
scale=QuantumScale*GetPixelAlpha(source,p); |
|
|
if (destination->alpha_trait != UndefinedPixelTrait) |
|
|
scale*=QuantumScale*GetPixelAlpha(destination,q); |
|
|
if (scale <= MagickEpsilon) |
|
|
return(MagickTrue); |
|
|
} |
|
|
/* |
|
|
RGB or CMY color cube |
|
|
*/ |
|
|
distance*=3.0; /* rescale appropriately */ |
|
|
fuzz*=3.0; |
|
|
pixel=GetPixelRed(source,p)-(double) GetPixelRed(destination,q); |
|
|
if ((source->colorspace == HSLColorspace) || |
|
|
(source->colorspace == HSBColorspace) || |
|
|
(source->colorspace == HWBColorspace)) |
|
|
{ |
|
|
/* |
|
|
Compute an arc distance for hue. It should be a vector angle of |
|
|
'S'/'W' length with 'L'/'B' forming appropriate cones. |
|
|
*/ |
|
|
if (fabs((double) pixel) > (QuantumRange/2)) |
|
|
pixel-=QuantumRange; |
|
|
pixel*=2; |
|
|
} |
|
|
distance+=scale*pixel*pixel; |
|
|
if (distance > fuzz) |
|
|
return(MagickFalse); |
|
|
pixel=GetPixelGreen(source,p)-(double) GetPixelGreen(destination,q); |
|
|
distance+=scale*pixel*pixel; |
|
|
if (distance > fuzz) |
|
|
return(MagickFalse); |
|
|
pixel=GetPixelBlue(source,p)-(double) GetPixelBlue(destination,q); |
|
|
distance+=scale*pixel*pixel; |
|
|
if (distance > fuzz) |
|
|
return(MagickFalse); |
|
|
return(MagickTrue); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
+ I s F u z z y E q u i v a l e n c e P i x e l I n f o % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% IsFuzzyEquivalencePixelInfo() returns true if the distance between two |
|
|
% colors is less than the specified distance in a linear three (or four) |
|
|
% dimensional color space. |
|
|
% |
|
|
% This implements the equivalent of: |
|
|
% fuzz < sqrt(color_distance^2 * u.a*v.a + alpha_distance^2) |
|
|
% |
|
|
% Which produces a multi-dimensional cone for that colorspace along the |
|
|
% transparency vector. |
|
|
% |
|
|
% For example for an RGB: |
|
|
% color_distance^2 = ( (u.r-v.r)^2 + (u.g-v.g)^2 + (u.b-v.b)^2 ) / 3 |
|
|
% |
|
|
% See http://www.imagemagick.org/Usage/bugs/fuzz_distance/ |
|
|
% |
|
|
% Hue colorspace distances need more work. Hue is not a distance, it is an |
|
|
% angle! |
|
|
% |
|
|
% A check that q is in the same color space as p should be made and the |
|
|
% appropriate mapping made. -- Anthony Thyssen 8 December 2010 |
|
|
% |
|
|
% The format of the IsFuzzyEquivalencePixelInfo method is: |
|
|
% |
|
|
% MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p, |
|
|
% const PixelInfo *q) |
|
|
% |
|
|
% A description of each parameter follows: |
|
|
% |
|
|
% o p: Pixel p. |
|
|
% |
|
|
% o q: Pixel q. |
|
|
% |
|
|
*/ |
|
|
MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p, |
|
|
const PixelInfo *q) |
|
|
{ |
|
|
double |
|
|
fuzz, |
|
|
pixel; |
|
|
|
|
|
register double |
|
|
scale, |
|
|
distance; |
|
|
|
|
|
fuzz=(double) MagickMax(MagickMax(p->fuzz,q->fuzz),(MagickRealType) |
|
|
MagickSQ1_2); |
|
|
fuzz*=fuzz; |
|
|
scale=1.0; |
|
|
distance=0.0; |
|
|
if ((p->alpha_trait != UndefinedPixelTrait) || |
|
|
(q->alpha_trait != UndefinedPixelTrait)) |
|
|
{ |
|
|
/* |
|
|
Transparencies are involved - set alpha distance. |
|
|
*/ |
|
|
pixel=(p->alpha_trait != UndefinedPixelTrait ? p->alpha : OpaqueAlpha)- |
|
|
(q->alpha_trait != UndefinedPixelTrait ? q->alpha : OpaqueAlpha); |
|
|
distance=pixel*pixel; |
|
|
if (distance > fuzz) |
|
|
return(MagickFalse); |
|
|
/* |
|
|
Generate a alpha scaling factor to generate a 4D cone on colorspace. |
|
|
If one color is transparent, distance has no color component. |
|
|
*/ |
|
|
if (p->alpha_trait != UndefinedPixelTrait) |
|
|
scale=(QuantumScale*p->alpha); |
|
|
if (q->alpha_trait != UndefinedPixelTrait) |
|
|
scale*=(QuantumScale*q->alpha); |
|
|
if (scale <= MagickEpsilon ) |
|
|
return(MagickTrue); |
|
|
} |
|
|
/* |
|
|
CMYK create a CMY cube with a multi-dimensional cone toward black. |
|
|
*/ |
|
|
if (p->colorspace == CMYKColorspace) |
|
|
{ |
|
|
pixel=p->black-q->black; |
|
|
distance+=pixel*pixel*scale; |
|
|
if (distance > fuzz) |
|
|
return(MagickFalse); |
|
|
scale*=(double) (QuantumScale*(QuantumRange-p->black)); |
|
|
scale*=(double) (QuantumScale*(QuantumRange-q->black)); |
|
|
} |
|
|
/* |
|
|
RGB or CMY color cube. |
|
|
*/ |
|
|
distance*=3.0; /* rescale appropriately */ |
|
|
fuzz*=3.0; |
|
|
pixel=p->red-q->red; |
|
|
if ((p->colorspace == HSLColorspace) || (p->colorspace == HSBColorspace) || |
|
|
(p->colorspace == HWBColorspace)) |
|
|
{ |
|
|
/* |
|
|
This calculates a arc distance for hue-- it should be a vector |
|
|
angle of 'S'/'W' length with 'L'/'B' forming appropriate cones. |
|
|
In other words this is a hack - Anthony. |
|
|
*/ |
|
|
if (fabs((double) pixel) > (QuantumRange/2)) |
|
|
pixel-=QuantumRange; |
|
|
pixel*=2; |
|
|
} |
|
|
distance+=pixel*pixel*scale; |
|
|
if (distance > fuzz) |
|
|
return(MagickFalse); |
|
|
pixel=p->green-q->green; |
|
|
distance+=pixel*pixel*scale; |
|
|
if (distance > fuzz) |
|
|
return(MagickFalse); |
|
|
pixel=p->blue-q->blue; |
|
|
distance+=pixel*pixel*scale; |
|
|
if (distance > fuzz) |
|
|
return(MagickFalse); |
|
|
return(MagickTrue); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
% S e t P i x e l C h a n n e l M a s k % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% SetPixelChannelMask() sets the pixel channel map from the specified channel |
|
|
% mask. |
|
|
% |
|
|
% The format of the SetPixelChannelMask method is: |
|
|
% |
|
|
% 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 ChannelType SetPixelChannelMask(Image *image, |
|
|
const ChannelType channel_mask) |
|
|
{ |
|
|
#define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01) |
|
|
|
|
|
ChannelType |
|
|
mask; |
|
|
|
|
|
register ssize_t |
|
|
i; |
|
|
|
|
|
assert(image != (Image *) NULL); |
|
|
assert(image->signature == MagickCoreSignature); |
|
|
if (image->debug != MagickFalse) |
|
|
(void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%08x]", |
|
|
image->filename,channel_mask); |
|
|
mask=image->channel_mask; |
|
|
image->channel_mask=channel_mask; |
|
|
for (i=0; i < (ssize_t) GetPixelChannels(image); i++) |
|
|
{ |
|
|
PixelChannel channel=GetPixelChannelChannel(image,i); |
|
|
if (GetChannelBit(channel_mask,channel) == 0) |
|
|
{ |
|
|
SetPixelChannelTraits(image,channel,CopyPixelTrait); |
|
|
continue; |
|
|
} |
|
|
if (channel == AlphaPixelChannel) |
|
|
{ |
|
|
if ((image->alpha_trait & CopyPixelTrait) != 0) |
|
|
{ |
|
|
SetPixelChannelTraits(image,channel,CopyPixelTrait); |
|
|
continue; |
|
|
} |
|
|
SetPixelChannelTraits(image,channel,UpdatePixelTrait); |
|
|
continue; |
|
|
} |
|
|
if (image->alpha_trait != UndefinedPixelTrait) |
|
|
{ |
|
|
SetPixelChannelTraits(image,channel,(const PixelTrait) |
|
|
(UpdatePixelTrait | BlendPixelTrait)); |
|
|
continue; |
|
|
} |
|
|
SetPixelChannelTraits(image,channel,UpdatePixelTrait); |
|
|
} |
|
|
if (image->storage_class == PseudoClass) |
|
|
SetPixelChannelTraits(image,IndexPixelChannel,CopyPixelTrait); |
|
|
if (image->read_mask != MagickFalse) |
|
|
SetPixelChannelTraits(image,ReadMaskPixelChannel,CopyPixelTrait); |
|
|
if (image->write_mask != MagickFalse) |
|
|
SetPixelChannelTraits(image,WriteMaskPixelChannel,CopyPixelTrait); |
|
|
if (image->debug != MagickFalse) |
|
|
LogPixelChannels(image); |
|
|
return(mask); |
|
|
} |
|
|
|
|
|
/* |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
% S e t P i x e l M e t a C h a n n e l s % |
|
|
% % |
|
|
% % |
|
|
% % |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
% |
|
|
% SetPixelMetaChannels() sets the image meta channels. |
|
|
% |
|
|
% The format of the SetPixelMetaChannels method is: |
|
|
% |
|
|
% MagickBooleanType SetPixelMetaChannels(Image *image, |
|
|
% const size_t number_meta_channels,ExceptionInfo *exception) |
|
|
% |
|
|
% A description of each parameter follows: |
|
|
% |
|
|
% o image: the image. |
|
|
% |
|
|
% o number_meta_channels: the number of meta channels. |
|
|
% |
|
|
% o exception: return any errors or warnings in this structure. |
|
|
% |
|
|
*/ |
|
|
MagickExport MagickBooleanType SetPixelMetaChannels(Image *image, |
|
|
const size_t number_meta_channels,ExceptionInfo *exception) |
|
|
{ |
|
|
image->number_meta_channels=number_meta_channels; |
|
|
return(SyncImagePixelCache(image,exception)); |
|
|
}
|
|
|
|