blob: 21d69a1424aaf5b201adaee8e5659547b5531c4c [file] [log] [blame]
cristy4c08aed2011-07-01 19:47:50 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% PPPP IIIII X X EEEEE L %
7% P P I X X E L %
8% PPPP I X EEE L %
9% P I X X E L %
10% P IIIII X X EEEEE LLLLL %
11% %
12% MagickCore Methods to Import/Export Pixels %
13% %
14% Software Design %
15% John Cristy %
16% October 1998 %
17% %
18% %
cristy45ef08f2012-12-07 13:13:34 +000019% Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization %
cristy4c08aed2011-07-01 19:47:50 +000020% dedicated to making software imaging solutions freely available. %
21% %
22% You may not use this file except in compliance with the License. You may %
23% obtain a copy of the License at %
24% %
25% http://www.imagemagick.org/script/license.php %
26% %
27% Unless required by applicable law or agreed to in writing, software %
28% distributed under the License is distributed on an "AS IS" BASIS, %
29% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30% See the License for the specific language governing permissions and %
31% limitations under the License. %
32% %
33%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34%
35%
36*/
37
38/*
39 Include declarations.
40*/
41#include "MagickCore/studio.h"
42#include "MagickCore/property.h"
43#include "MagickCore/blob.h"
44#include "MagickCore/blob-private.h"
cristy322d07d2012-03-18 21:17:23 +000045#include "MagickCore/cache-private.h"
cristy4c08aed2011-07-01 19:47:50 +000046#include "MagickCore/color-private.h"
47#include "MagickCore/draw.h"
48#include "MagickCore/exception.h"
49#include "MagickCore/exception-private.h"
50#include "MagickCore/cache.h"
51#include "MagickCore/constitute.h"
52#include "MagickCore/delegate.h"
53#include "MagickCore/geometry.h"
54#include "MagickCore/image-private.h"
55#include "MagickCore/list.h"
56#include "MagickCore/magick.h"
57#include "MagickCore/memory_.h"
58#include "MagickCore/monitor.h"
59#include "MagickCore/option.h"
60#include "MagickCore/pixel.h"
61#include "MagickCore/pixel-accessor.h"
cristy380a11c2012-06-02 15:15:22 +000062#include "MagickCore/pixel-private.h"
cristy4c08aed2011-07-01 19:47:50 +000063#include "MagickCore/quantum.h"
64#include "MagickCore/quantum-private.h"
65#include "MagickCore/resource_.h"
66#include "MagickCore/semaphore.h"
67#include "MagickCore/statistic.h"
68#include "MagickCore/stream.h"
69#include "MagickCore/string_.h"
70#include "MagickCore/transform.h"
71#include "MagickCore/utility.h"
72
cristy146a62b2011-10-23 23:40:46 +000073#define LogPixelChannels(image) \
74{ \
75 register ssize_t \
76 i; \
77 \
78 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%.20g]", \
79 image->filename,(double) image->number_channels); \
80 for (i=0; i < (ssize_t) image->number_channels; i++) \
81 { \
82 char \
83 traits[MaxTextExtent]; \
84 \
85 const char \
cristy46795722011-12-10 23:56:57 +000086 *name; \
87 \
88 PixelChannel \
89 channel; \
cristy146a62b2011-10-23 23:40:46 +000090 \
cristycf1296e2012-08-26 23:40:49 +000091 switch (GetPixelChannelChannel(image,i)) \
cristy146a62b2011-10-23 23:40:46 +000092 { \
93 case RedPixelChannel: \
94 { \
cristy46795722011-12-10 23:56:57 +000095 name="red"; \
cristy146a62b2011-10-23 23:40:46 +000096 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +000097 name="cyan"; \
cristy146a62b2011-10-23 23:40:46 +000098 if (image->colorspace == GRAYColorspace) \
cristy46795722011-12-10 23:56:57 +000099 name="gray"; \
cristy146a62b2011-10-23 23:40:46 +0000100 break; \
101 } \
102 case GreenPixelChannel: \
103 { \
cristy46795722011-12-10 23:56:57 +0000104 name="green"; \
cristy146a62b2011-10-23 23:40:46 +0000105 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +0000106 name="magenta"; \
cristy146a62b2011-10-23 23:40:46 +0000107 break; \
108 } \
109 case BluePixelChannel: \
110 { \
cristy46795722011-12-10 23:56:57 +0000111 name="blue"; \
cristy146a62b2011-10-23 23:40:46 +0000112 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +0000113 name="yellow"; \
cristy146a62b2011-10-23 23:40:46 +0000114 break; \
115 } \
116 case BlackPixelChannel: \
117 { \
cristy46795722011-12-10 23:56:57 +0000118 name="black"; \
cristy146a62b2011-10-23 23:40:46 +0000119 if (image->storage_class == PseudoClass) \
cristy46795722011-12-10 23:56:57 +0000120 name="index"; \
cristy146a62b2011-10-23 23:40:46 +0000121 break; \
122 } \
cristye2a912b2011-12-05 20:02:07 +0000123 case IndexPixelChannel: \
124 { \
cristy46795722011-12-10 23:56:57 +0000125 name="index"; \
cristye2a912b2011-12-05 20:02:07 +0000126 break; \
127 } \
cristy146a62b2011-10-23 23:40:46 +0000128 case AlphaPixelChannel: \
129 { \
cristy46795722011-12-10 23:56:57 +0000130 name="alpha"; \
cristy146a62b2011-10-23 23:40:46 +0000131 break; \
132 } \
133 case MaskPixelChannel: \
134 { \
cristy46795722011-12-10 23:56:57 +0000135 name="mask"; \
cristy146a62b2011-10-23 23:40:46 +0000136 break; \
137 } \
cristye2a912b2011-12-05 20:02:07 +0000138 case MetaPixelChannel: \
cristy146a62b2011-10-23 23:40:46 +0000139 { \
cristy46795722011-12-10 23:56:57 +0000140 name="meta"; \
cristye2a912b2011-12-05 20:02:07 +0000141 break; \
cristy146a62b2011-10-23 23:40:46 +0000142 } \
cristye2a912b2011-12-05 20:02:07 +0000143 default: \
cristy46795722011-12-10 23:56:57 +0000144 name="undefined"; \
cristy146a62b2011-10-23 23:40:46 +0000145 } \
cristycf1296e2012-08-26 23:40:49 +0000146 channel=GetPixelChannelChannel(image,i); \
cristy146a62b2011-10-23 23:40:46 +0000147 *traits='\0'; \
cristycf1296e2012-08-26 23:40:49 +0000148 if ((GetPixelChannelTraits(image,channel) & UpdatePixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000149 (void) ConcatenateMagickString(traits,"update,",MaxTextExtent); \
cristycf1296e2012-08-26 23:40:49 +0000150 if ((GetPixelChannelTraits(image,channel) & BlendPixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000151 (void) ConcatenateMagickString(traits,"blend,",MaxTextExtent); \
cristycf1296e2012-08-26 23:40:49 +0000152 if ((GetPixelChannelTraits(image,channel) & CopyPixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000153 (void) ConcatenateMagickString(traits,"copy,",MaxTextExtent); \
154 if (*traits == '\0') \
155 (void) ConcatenateMagickString(traits,"undefined,",MaxTextExtent); \
156 traits[strlen(traits)-1]='\0'; \
157 (void) LogMagickEvent(PixelEvent,GetMagickModule()," %.20g: %s (%s)", \
cristy46795722011-12-10 23:56:57 +0000158 (double) i,name,traits); \
cristy146a62b2011-10-23 23:40:46 +0000159 } \
160}
161
162/*
cristy4c08aed2011-07-01 19:47:50 +0000163%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164% %
165% %
166% %
cristyed231572011-07-14 02:18:59 +0000167+ A c q u i r e P i x e l C h a n n e l M a p %
cristy4c08aed2011-07-01 19:47:50 +0000168% %
169% %
170% %
171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172%
cristyed231572011-07-14 02:18:59 +0000173% AcquirePixelChannelMap() acquires a pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000174%
cristyed231572011-07-14 02:18:59 +0000175% The format of the AcquirePixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000176%
cristybd5a96c2011-08-21 00:04:26 +0000177% PixelChannelMap *AcquirePixelChannelMap(void)
cristy4c08aed2011-07-01 19:47:50 +0000178%
179*/
cristybd5a96c2011-08-21 00:04:26 +0000180MagickExport PixelChannelMap *AcquirePixelChannelMap(void)
cristy4c08aed2011-07-01 19:47:50 +0000181{
cristyed231572011-07-14 02:18:59 +0000182 PixelChannelMap
cristybd5a96c2011-08-21 00:04:26 +0000183 *channel_map;
cristy4c08aed2011-07-01 19:47:50 +0000184
185 register ssize_t
186 i;
187
cristybd5a96c2011-08-21 00:04:26 +0000188 channel_map=(PixelChannelMap *) AcquireQuantumMemory(MaxPixelChannels,
189 sizeof(*channel_map));
190 if (channel_map == (PixelChannelMap *) NULL)
cristy4c08aed2011-07-01 19:47:50 +0000191 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristybd5a96c2011-08-21 00:04:26 +0000192 (void) ResetMagickMemory(channel_map,0,MaxPixelChannels*sizeof(*channel_map));
193 for (i=0; i < MaxPixelChannels; i++)
194 channel_map[i].channel=(PixelChannel) i;
cristyed231572011-07-14 02:18:59 +0000195 return(channel_map);
cristy4c08aed2011-07-01 19:47:50 +0000196}
197
198/*
199%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
200% %
201% %
202% %
cristyed231572011-07-14 02:18:59 +0000203+ C l o n e P i x e l C h a n n e l M a p %
cristy4c08aed2011-07-01 19:47:50 +0000204% %
205% %
206% %
207%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
208%
cristyed231572011-07-14 02:18:59 +0000209% ClonePixelChannelMap() clones a pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000210%
cristyed231572011-07-14 02:18:59 +0000211% The format of the ClonePixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000212%
cristybd5a96c2011-08-21 00:04:26 +0000213% PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000214%
215% A description of each parameter follows:
216%
cristyed231572011-07-14 02:18:59 +0000217% o channel_map: the pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000218%
219*/
cristybd5a96c2011-08-21 00:04:26 +0000220MagickExport PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000221{
cristyed231572011-07-14 02:18:59 +0000222 PixelChannelMap
cristybd5a96c2011-08-21 00:04:26 +0000223 *clone_map;
cristy4c08aed2011-07-01 19:47:50 +0000224
cristybd5a96c2011-08-21 00:04:26 +0000225 assert(channel_map != (PixelChannelMap *) NULL);
cristyed231572011-07-14 02:18:59 +0000226 clone_map=AcquirePixelChannelMap();
cristybd5a96c2011-08-21 00:04:26 +0000227 if (clone_map == (PixelChannelMap *) NULL)
228 return((PixelChannelMap *) NULL);
229 (void) CopyMagickMemory(clone_map,channel_map,MaxPixelChannels*
230 sizeof(*channel_map));
cristy4c08aed2011-07-01 19:47:50 +0000231 return(clone_map);
232}
233
234/*
235%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
236% %
237% %
238% %
239+ C l o n e P i x e l I n f o %
240% %
241% %
242% %
243%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244%
245% ClonePixelInfo() makes a duplicate of the given pixel info structure, or if
246% pixel info is NULL, a new one.
247%
248% The format of the ClonePixelInfo method is:
249%
250% PixelInfo *ClonePixelInfo(const PixelInfo *pixel_info)
251%
252% A description of each parameter follows:
253%
254% o pixel_info: the pixel info.
255%
256*/
257MagickExport PixelInfo *ClonePixelInfo(const PixelInfo *pixel)
258{
259 PixelInfo
260 *pixel_info;
261
cristya64b85d2011-09-14 01:02:31 +0000262 pixel_info=(PixelInfo *) AcquireQuantumMemory(1,sizeof(*pixel_info));
cristy4c08aed2011-07-01 19:47:50 +0000263 if (pixel_info == (PixelInfo *) NULL)
264 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
265 *pixel_info=(*pixel);
266 return(pixel_info);
267}
268
269/*
270%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271% %
272% %
273% %
cristyc8aff842012-12-24 16:59:46 +0000274% D e c o d e P i x e l G a m m a %
275% %
276% %
277% %
278%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279%
280% DecodePixelGamma() applies the expansive power-law nonlinearity to the pixel.
281%
282% The format of the DecodePixelGammaImage method is:
283%
284% double DecodePixelGamma(const MagickRealType pixel)
285%
286% A description of each parameter follows:
287%
288% o pixel: the pixel.
289%
290*/
291MagickExport MagickRealType DecodePixelGamma(const MagickRealType pixel)
292{
293 if (pixel <= (0.0404482362771076*QuantumRange))
294 return(pixel/12.92f);
295 return((MagickRealType) (QuantumRange*pow((double) (QuantumScale*pixel+
296 0.055)/1.055,2.4)));
297}
298
299/*
300%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
301% %
302% %
303% %
cristyed231572011-07-14 02:18:59 +0000304+ D e s t r o y P i x e l C h a n n e l M a p %
cristy4c08aed2011-07-01 19:47:50 +0000305% %
306% %
307% %
308%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
309%
cristyed231572011-07-14 02:18:59 +0000310% DestroyPixelChannelMap() deallocates memory associated with the pixel
311% channel map.
cristy4c08aed2011-07-01 19:47:50 +0000312%
cristyed231572011-07-14 02:18:59 +0000313% The format of the DestroyPixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000314%
cristybd5a96c2011-08-21 00:04:26 +0000315% PixelChannelMap *DestroyPixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000316%
317% A description of each parameter follows:
318%
cristyed231572011-07-14 02:18:59 +0000319% o channel_map: the pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000320%
321*/
cristybd5a96c2011-08-21 00:04:26 +0000322MagickExport PixelChannelMap *DestroyPixelChannelMap(
323 PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000324{
cristybd5a96c2011-08-21 00:04:26 +0000325 assert(channel_map != (PixelChannelMap *) NULL);
326 channel_map=(PixelChannelMap *) RelinquishMagickMemory(channel_map);
327 return((PixelChannelMap *) RelinquishMagickMemory(channel_map));
cristy4c08aed2011-07-01 19:47:50 +0000328}
329
330/*
331%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
332% %
333% %
334% %
cristyc8aff842012-12-24 16:59:46 +0000335+ E n c o d e P i x e l G a m m a %
336% %
337% %
338% %
339%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
340%
341% EncodePixelGamma() cancels any nonlinearity in the pixel.
342%
343% The format of the EncodePixelGammaImage method is:
344%
345% MagickRealType EncodePixelGamma(const double MagickRealType)
346%
347% A description of each parameter follows:
348%
349% o pixel: the pixel.
350%
351*/
352MagickExport MagickRealType EncodePixelGamma(const MagickRealType pixel)
353{
354 if (pixel <= (0.0031306684425005883*QuantumRange))
355 return(12.92f*pixel);
356 return((MagickRealType) QuantumRange*(1.055*pow((double) QuantumScale*pixel,
357 1.0/2.4)-0.055));
358}
359
360/*
361%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
362% %
363% %
364% %
cristy4c08aed2011-07-01 19:47:50 +0000365% E x p o r t I m a g e P i x e l s %
366% %
367% %
368% %
369%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
370%
371% ExportImagePixels() extracts pixel data from an image and returns it to you.
372% The method returns MagickTrue on success otherwise MagickFalse if an error is
cristyb5a45a32012-01-10 13:31:13 +0000373% encountered. The data is returned as char, short int, Quantum, unsigned int,
cristycafe0412012-01-10 13:29:58 +0000374% unsigned long long, float, or double in the order specified by map.
cristy4c08aed2011-07-01 19:47:50 +0000375%
376% Suppose you want to extract the first scanline of a 640x480 image as
377% character data in red-green-blue order:
378%
379% ExportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels,exception);
380%
381% The format of the ExportImagePixels method is:
382%
cristycafe0412012-01-10 13:29:58 +0000383% MagickBooleanType ExportImagePixels(const Image *image,const ssize_t x,
384% const ssize_t y,const size_t width,const size_t height,
385% const char *map,const StorageType type,void *pixels,
cristy46f4be22012-01-07 00:26:39 +0000386% ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +0000387%
388% A description of each parameter follows:
389%
390% o image: the image.
391%
cristycafe0412012-01-10 13:29:58 +0000392% o x,y,width,height: These values define the perimeter
cristy4c08aed2011-07-01 19:47:50 +0000393% of a region of pixels you want to extract.
394%
395% o map: This string reflects the expected ordering of the pixel array.
396% It can be any combination or order of R = red, G = green, B = blue,
397% A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
398% Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
399% P = pad.
400%
401% o type: Define the data type of the pixels. Float and double types are
402% normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
cristy6c9e1682012-01-07 21:37:44 +0000403% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
cristyff6834e2012-01-10 03:00:25 +0000404% LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
cristy6c9e1682012-01-07 21:37:44 +0000405% QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
cristy4c08aed2011-07-01 19:47:50 +0000406%
407% o pixels: This array of values contain the pixel components as defined by
408% map and type. You must preallocate this array where the expected
409% length varies depending on the values of width, height, map, and type.
410%
411% o exception: return any errors or warnings in this structure.
412%
413*/
cristye5370942012-01-06 03:49:31 +0000414
cristy2dc655d2012-07-05 13:16:28 +0000415static void ExportCharPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000416 const char *restrict map,const QuantumType *quantum_map,void *pixels,
417 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000418{
419 register const Quantum
420 *restrict p;
421
422 register ssize_t
423 x;
424
425 register unsigned char
cristy3fe11452012-01-09 01:27:42 +0000426 *restrict q;
cristye5370942012-01-06 03:49:31 +0000427
cristy14d71292012-05-20 16:48:13 +0000428 size_t
429 length;
430
cristye5370942012-01-06 03:49:31 +0000431 ssize_t
432 y;
433
cristy46f4be22012-01-07 00:26:39 +0000434 q=(unsigned char *) pixels;
cristye5370942012-01-06 03:49:31 +0000435 if (LocaleCompare(map,"BGR") == 0)
436 {
cristycafe0412012-01-10 13:29:58 +0000437 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000438 {
cristycafe0412012-01-10 13:29:58 +0000439 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000440 if (p == (const Quantum *) NULL)
441 break;
cristycafe0412012-01-10 13:29:58 +0000442 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000443 {
444 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
445 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
446 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
447 p+=GetPixelChannels(image);
448 }
449 }
450 return;
451 }
452 if (LocaleCompare(map,"BGRA") == 0)
453 {
cristycafe0412012-01-10 13:29:58 +0000454 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000455 {
cristycafe0412012-01-10 13:29:58 +0000456 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000457 if (p == (const Quantum *) NULL)
458 break;
cristycafe0412012-01-10 13:29:58 +0000459 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000460 {
461 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
462 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
463 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
464 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
465 p+=GetPixelChannels(image);
466 }
467 }
468 return;
469 }
470 if (LocaleCompare(map,"BGRP") == 0)
471 {
cristycafe0412012-01-10 13:29:58 +0000472 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000473 {
cristycafe0412012-01-10 13:29:58 +0000474 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000475 if (p == (const Quantum *) NULL)
476 break;
cristycafe0412012-01-10 13:29:58 +0000477 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000478 {
479 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
480 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
481 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
482 *q++=ScaleQuantumToChar((Quantum) 0);
483 p+=GetPixelChannels(image);
484 }
485 }
486 return;
487 }
488 if (LocaleCompare(map,"I") == 0)
489 {
cristycafe0412012-01-10 13:29:58 +0000490 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000491 {
cristycafe0412012-01-10 13:29:58 +0000492 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000493 if (p == (const Quantum *) NULL)
494 break;
cristycafe0412012-01-10 13:29:58 +0000495 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000496 {
497 *q++=ScaleQuantumToChar(GetPixelIntensity(image,p));
498 p+=GetPixelChannels(image);
499 }
500 }
501 return;
502 }
503 if (LocaleCompare(map,"RGB") == 0)
504 {
cristycafe0412012-01-10 13:29:58 +0000505 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000506 {
cristycafe0412012-01-10 13:29:58 +0000507 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000508 if (p == (const Quantum *) NULL)
509 break;
cristycafe0412012-01-10 13:29:58 +0000510 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000511 {
512 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
513 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
514 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
515 p+=GetPixelChannels(image);
516 }
517 }
518 return;
519 }
520 if (LocaleCompare(map,"RGBA") == 0)
521 {
cristycafe0412012-01-10 13:29:58 +0000522 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000523 {
cristycafe0412012-01-10 13:29:58 +0000524 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000525 if (p == (const Quantum *) NULL)
526 break;
cristycafe0412012-01-10 13:29:58 +0000527 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000528 {
529 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
530 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
531 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
532 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
533 p+=GetPixelChannels(image);
534 }
535 }
536 return;
537 }
538 if (LocaleCompare(map,"RGBP") == 0)
539 {
cristycafe0412012-01-10 13:29:58 +0000540 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000541 {
cristycafe0412012-01-10 13:29:58 +0000542 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000543 if (p == (const Quantum *) NULL)
544 break;
cristycafe0412012-01-10 13:29:58 +0000545 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000546 {
547 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
548 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
549 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
550 *q++=ScaleQuantumToChar((Quantum) 0);
551 p+=GetPixelChannels(image);
552 }
553 }
554 return;
555 }
cristy14d71292012-05-20 16:48:13 +0000556 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +0000557 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000558 {
cristycafe0412012-01-10 13:29:58 +0000559 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000560 if (p == (const Quantum *) NULL)
561 break;
cristycafe0412012-01-10 13:29:58 +0000562 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000563 {
564 register ssize_t
565 i;
566
cristy14d71292012-05-20 16:48:13 +0000567 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +0000568 {
569 *q=0;
570 switch (quantum_map[i])
571 {
572 case RedQuantum:
573 case CyanQuantum:
574 {
575 *q=ScaleQuantumToChar(GetPixelRed(image,p));
576 break;
577 }
578 case GreenQuantum:
579 case MagentaQuantum:
580 {
581 *q=ScaleQuantumToChar(GetPixelGreen(image,p));
582 break;
583 }
584 case BlueQuantum:
585 case YellowQuantum:
586 {
587 *q=ScaleQuantumToChar(GetPixelBlue(image,p));
588 break;
589 }
590 case AlphaQuantum:
591 {
592 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
593 break;
594 }
595 case OpacityQuantum:
596 {
597 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
598 break;
599 }
600 case BlackQuantum:
601 {
602 if (image->colorspace == CMYKColorspace)
603 *q=ScaleQuantumToChar(GetPixelBlack(image,p));
604 break;
605 }
606 case IndexQuantum:
607 {
608 *q=ScaleQuantumToChar(GetPixelIntensity(image,p));
609 break;
610 }
611 default:
612 break;
613 }
614 q++;
615 }
616 p+=GetPixelChannels(image);
617 }
618 }
619}
620
cristy2dc655d2012-07-05 13:16:28 +0000621static void ExportDoublePixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000622 const char *restrict map,const QuantumType *quantum_map,void *pixels,
623 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000624{
625 register const Quantum
626 *restrict p;
627
628 register double
cristy3fe11452012-01-09 01:27:42 +0000629 *restrict q;
cristye5370942012-01-06 03:49:31 +0000630
631 register ssize_t
632 x;
633
cristy14d71292012-05-20 16:48:13 +0000634 size_t
635 length;
636
cristye5370942012-01-06 03:49:31 +0000637 ssize_t
638 y;
639
640 q=(double *) pixels;
641 if (LocaleCompare(map,"BGR") == 0)
642 {
cristycafe0412012-01-10 13:29:58 +0000643 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000644 {
cristycafe0412012-01-10 13:29:58 +0000645 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000646 if (p == (const Quantum *) NULL)
647 break;
cristycafe0412012-01-10 13:29:58 +0000648 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000649 {
650 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
651 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
652 *q++=(double) (QuantumScale*GetPixelRed(image,p));
653 p+=GetPixelChannels(image);
654 }
655 }
656 return;
657 }
658 if (LocaleCompare(map,"BGRA") == 0)
659 {
cristycafe0412012-01-10 13:29:58 +0000660 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000661 {
cristycafe0412012-01-10 13:29:58 +0000662 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000663 if (p == (const Quantum *) NULL)
664 break;
cristycafe0412012-01-10 13:29:58 +0000665 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000666 {
667 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
668 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
669 *q++=(double) (QuantumScale*GetPixelRed(image,p));
670 *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
671 p+=GetPixelChannels(image);
672 }
673 }
674 return;
675 }
676 if (LocaleCompare(map,"BGRP") == 0)
677 {
cristycafe0412012-01-10 13:29:58 +0000678 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000679 {
cristycafe0412012-01-10 13:29:58 +0000680 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000681 if (p == (const Quantum *) NULL)
682 break;
cristycafe0412012-01-10 13:29:58 +0000683 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000684 {
685 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
686 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
687 *q++=(double) (QuantumScale*GetPixelRed(image,p));
688 *q++=0.0;
689 p+=GetPixelChannels(image);
690 }
691 }
692 return;
693 }
694 if (LocaleCompare(map,"I") == 0)
695 {
cristycafe0412012-01-10 13:29:58 +0000696 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000697 {
cristycafe0412012-01-10 13:29:58 +0000698 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000699 if (p == (const Quantum *) NULL)
700 break;
cristycafe0412012-01-10 13:29:58 +0000701 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000702 {
703 *q++=(double) (QuantumScale*GetPixelIntensity(image,p));
704 p+=GetPixelChannels(image);
705 }
706 }
707 return;
708 }
709 if (LocaleCompare(map,"RGB") == 0)
710 {
cristycafe0412012-01-10 13:29:58 +0000711 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000712 {
cristycafe0412012-01-10 13:29:58 +0000713 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000714 if (p == (const Quantum *) NULL)
715 break;
cristycafe0412012-01-10 13:29:58 +0000716 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000717 {
718 *q++=(double) (QuantumScale*GetPixelRed(image,p));
719 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
720 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
721 p+=GetPixelChannels(image);
722 }
723 }
724 return;
725 }
726 if (LocaleCompare(map,"RGBA") == 0)
727 {
cristycafe0412012-01-10 13:29:58 +0000728 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000729 {
cristycafe0412012-01-10 13:29:58 +0000730 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000731 if (p == (const Quantum *) NULL)
732 break;
cristycafe0412012-01-10 13:29:58 +0000733 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000734 {
735 *q++=(double) (QuantumScale*GetPixelRed(image,p));
736 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
737 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
738 *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
739 p+=GetPixelChannels(image);
740 }
741 }
742 return;
743 }
744 if (LocaleCompare(map,"RGBP") == 0)
745 {
cristycafe0412012-01-10 13:29:58 +0000746 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000747 {
cristycafe0412012-01-10 13:29:58 +0000748 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000749 if (p == (const Quantum *) NULL)
750 break;
cristycafe0412012-01-10 13:29:58 +0000751 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000752 {
753 *q++=(double) (QuantumScale*GetPixelRed(image,p));
754 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
755 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
756 *q++=0.0;
757 p+=GetPixelChannels(image);
758 }
759 }
760 return;
761 }
cristy14d71292012-05-20 16:48:13 +0000762 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +0000763 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000764 {
cristycafe0412012-01-10 13:29:58 +0000765 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000766 if (p == (const Quantum *) NULL)
767 break;
cristycafe0412012-01-10 13:29:58 +0000768 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000769 {
770 register ssize_t
771 i;
772
cristy14d71292012-05-20 16:48:13 +0000773 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +0000774 {
775 *q=0;
776 switch (quantum_map[i])
777 {
778 case RedQuantum:
779 case CyanQuantum:
780 {
781 *q=(double) (QuantumScale*GetPixelRed(image,p));
782 break;
783 }
784 case GreenQuantum:
785 case MagentaQuantum:
786 {
787 *q=(double) (QuantumScale*GetPixelGreen(image,p));
788 break;
789 }
790 case BlueQuantum:
791 case YellowQuantum:
792 {
793 *q=(double) (QuantumScale*GetPixelBlue(image,p));
794 break;
795 }
796 case AlphaQuantum:
797 {
798 *q=(double) (QuantumScale*GetPixelAlpha(image,p));
799 break;
800 }
801 case OpacityQuantum:
802 {
803 *q=(double) (QuantumScale*GetPixelAlpha(image,p));
804 break;
805 }
806 case BlackQuantum:
807 {
808 if (image->colorspace == CMYKColorspace)
809 *q=(double) (QuantumScale*
810 GetPixelBlack(image,p));
811 break;
812 }
813 case IndexQuantum:
814 {
815 *q=(double) (QuantumScale*GetPixelIntensity(image,p));
816 break;
817 }
818 default:
819 *q=0;
820 }
821 q++;
822 }
823 p+=GetPixelChannels(image);
824 }
825 }
826}
827
cristy2dc655d2012-07-05 13:16:28 +0000828static void ExportFloatPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000829 const char *restrict map,const QuantumType *quantum_map,void *pixels,
830 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000831{
832 register const Quantum
833 *restrict p;
834
835 register float
cristy3fe11452012-01-09 01:27:42 +0000836 *restrict q;
cristye5370942012-01-06 03:49:31 +0000837
838 register ssize_t
839 x;
840
cristy14d71292012-05-20 16:48:13 +0000841 size_t
842 length;
843
cristye5370942012-01-06 03:49:31 +0000844 ssize_t
845 y;
846
847 q=(float *) pixels;
848 if (LocaleCompare(map,"BGR") == 0)
849 {
cristycafe0412012-01-10 13:29:58 +0000850 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000851 {
cristycafe0412012-01-10 13:29:58 +0000852 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000853 if (p == (const Quantum *) NULL)
854 break;
cristycafe0412012-01-10 13:29:58 +0000855 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000856 {
857 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
858 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
859 *q++=(float) (QuantumScale*GetPixelRed(image,p));
860 p+=GetPixelChannels(image);
861 }
862 }
863 return;
864 }
865 if (LocaleCompare(map,"BGRA") == 0)
866 {
cristycafe0412012-01-10 13:29:58 +0000867 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000868 {
cristycafe0412012-01-10 13:29:58 +0000869 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000870 if (p == (const Quantum *) NULL)
871 break;
cristycafe0412012-01-10 13:29:58 +0000872 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000873 {
874 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
875 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
876 *q++=(float) (QuantumScale*GetPixelRed(image,p));
877 *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
878 p+=GetPixelChannels(image);
879 }
880 }
881 return;
882 }
883 if (LocaleCompare(map,"BGRP") == 0)
884 {
cristycafe0412012-01-10 13:29:58 +0000885 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000886 {
cristycafe0412012-01-10 13:29:58 +0000887 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000888 if (p == (const Quantum *) NULL)
889 break;
cristycafe0412012-01-10 13:29:58 +0000890 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000891 {
892 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
893 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
894 *q++=(float) (QuantumScale*GetPixelRed(image,p));
895 *q++=0.0;
896 p+=GetPixelChannels(image);
897 }
898 }
899 return;
900 }
901 if (LocaleCompare(map,"I") == 0)
902 {
cristycafe0412012-01-10 13:29:58 +0000903 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000904 {
cristycafe0412012-01-10 13:29:58 +0000905 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000906 if (p == (const Quantum *) NULL)
907 break;
cristycafe0412012-01-10 13:29:58 +0000908 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000909 {
910 *q++=(float) (QuantumScale*GetPixelIntensity(image,p));
911 p+=GetPixelChannels(image);
912 }
913 }
914 return;
915 }
916 if (LocaleCompare(map,"RGB") == 0)
917 {
cristycafe0412012-01-10 13:29:58 +0000918 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000919 {
cristycafe0412012-01-10 13:29:58 +0000920 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000921 if (p == (const Quantum *) NULL)
922 break;
cristycafe0412012-01-10 13:29:58 +0000923 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000924 {
925 *q++=(float) (QuantumScale*GetPixelRed(image,p));
926 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
927 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
928 p+=GetPixelChannels(image);
929 }
930 }
931 return;
932 }
933 if (LocaleCompare(map,"RGBA") == 0)
934 {
cristycafe0412012-01-10 13:29:58 +0000935 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000936 {
cristycafe0412012-01-10 13:29:58 +0000937 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000938 if (p == (const Quantum *) NULL)
939 break;
cristycafe0412012-01-10 13:29:58 +0000940 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000941 {
942 *q++=(float) (QuantumScale*GetPixelRed(image,p));
943 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
944 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
945 *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
946 p+=GetPixelChannels(image);
947 }
948 }
949 return;
950 }
951 if (LocaleCompare(map,"RGBP") == 0)
952 {
cristycafe0412012-01-10 13:29:58 +0000953 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000954 {
cristycafe0412012-01-10 13:29:58 +0000955 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000956 if (p == (const Quantum *) NULL)
957 break;
cristycafe0412012-01-10 13:29:58 +0000958 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000959 {
960 *q++=(float) (QuantumScale*GetPixelRed(image,p));
961 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
962 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
963 *q++=0.0;
964 p+=GetPixelChannels(image);
965 }
966 }
967 return;
968 }
cristy14d71292012-05-20 16:48:13 +0000969 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +0000970 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000971 {
cristycafe0412012-01-10 13:29:58 +0000972 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000973 if (p == (const Quantum *) NULL)
974 break;
cristycafe0412012-01-10 13:29:58 +0000975 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000976 {
977 register ssize_t
978 i;
979
cristy14d71292012-05-20 16:48:13 +0000980 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +0000981 {
982 *q=0;
983 switch (quantum_map[i])
984 {
985 case RedQuantum:
986 case CyanQuantum:
987 {
988 *q=(float) (QuantumScale*GetPixelRed(image,p));
989 break;
990 }
991 case GreenQuantum:
992 case MagentaQuantum:
993 {
994 *q=(float) (QuantumScale*GetPixelGreen(image,p));
995 break;
996 }
997 case BlueQuantum:
998 case YellowQuantum:
999 {
1000 *q=(float) (QuantumScale*GetPixelBlue(image,p));
1001 break;
1002 }
1003 case AlphaQuantum:
1004 {
1005 *q=(float) (QuantumScale*((Quantum) (GetPixelAlpha(image,p))));
1006 break;
1007 }
1008 case OpacityQuantum:
1009 {
1010 *q=(float) (QuantumScale*GetPixelAlpha(image,p));
1011 break;
1012 }
1013 case BlackQuantum:
1014 {
1015 if (image->colorspace == CMYKColorspace)
1016 *q=(float) (QuantumScale* GetPixelBlack(image,p));
1017 break;
1018 }
1019 case IndexQuantum:
1020 {
1021 *q=(float) (QuantumScale*GetPixelIntensity(image,p));
1022 break;
1023 }
1024 default:
1025 *q=0;
1026 }
1027 q++;
1028 }
1029 p+=GetPixelChannels(image);
1030 }
1031 }
1032}
1033
cristy2dc655d2012-07-05 13:16:28 +00001034static void ExportLongPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00001035 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1036 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001037{
1038 register const Quantum
1039 *restrict p;
1040
1041 register ssize_t
1042 x;
1043
1044 register unsigned int
cristy3fe11452012-01-09 01:27:42 +00001045 *restrict q;
cristye5370942012-01-06 03:49:31 +00001046
cristy14d71292012-05-20 16:48:13 +00001047 size_t
1048 length;
1049
cristye5370942012-01-06 03:49:31 +00001050 ssize_t
1051 y;
1052
1053 q=(unsigned int *) pixels;
1054 if (LocaleCompare(map,"BGR") == 0)
1055 {
cristycafe0412012-01-10 13:29:58 +00001056 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001057 {
cristycafe0412012-01-10 13:29:58 +00001058 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001059 if (p == (const Quantum *) NULL)
1060 break;
cristycafe0412012-01-10 13:29:58 +00001061 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001062 {
cristy6c9e1682012-01-07 21:37:44 +00001063 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1064 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1065 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001066 p+=GetPixelChannels(image);
1067 }
1068 }
1069 return;
1070 }
1071 if (LocaleCompare(map,"BGRA") == 0)
1072 {
cristycafe0412012-01-10 13:29:58 +00001073 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001074 {
cristycafe0412012-01-10 13:29:58 +00001075 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001076 if (p == (const Quantum *) NULL)
1077 break;
cristycafe0412012-01-10 13:29:58 +00001078 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001079 {
cristy6c9e1682012-01-07 21:37:44 +00001080 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1081 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1082 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1083 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001084 p+=GetPixelChannels(image);
1085 }
1086 }
1087 return;
1088 }
1089 if (LocaleCompare(map,"BGRP") == 0)
1090 {
cristycafe0412012-01-10 13:29:58 +00001091 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001092 {
cristycafe0412012-01-10 13:29:58 +00001093 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001094 if (p == (const Quantum *) NULL)
1095 break;
cristycafe0412012-01-10 13:29:58 +00001096 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001097 {
cristy6c9e1682012-01-07 21:37:44 +00001098 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1099 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1100 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1101 *q++=0;
cristye5370942012-01-06 03:49:31 +00001102 p+=GetPixelChannels(image);
1103 }
1104 }
1105 return;
1106 }
1107 if (LocaleCompare(map,"I") == 0)
1108 {
cristycafe0412012-01-10 13:29:58 +00001109 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001110 {
cristycafe0412012-01-10 13:29:58 +00001111 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001112 if (p == (const Quantum *) NULL)
1113 break;
cristycafe0412012-01-10 13:29:58 +00001114 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001115 {
cristy6c9e1682012-01-07 21:37:44 +00001116 *q++=ScaleQuantumToLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001117 p+=GetPixelChannels(image);
1118 }
1119 }
1120 return;
1121 }
1122 if (LocaleCompare(map,"RGB") == 0)
1123 {
cristycafe0412012-01-10 13:29:58 +00001124 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001125 {
cristycafe0412012-01-10 13:29:58 +00001126 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001127 if (p == (const Quantum *) NULL)
1128 break;
cristycafe0412012-01-10 13:29:58 +00001129 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001130 {
cristy6c9e1682012-01-07 21:37:44 +00001131 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1132 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1133 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001134 p+=GetPixelChannels(image);
1135 }
1136 }
1137 return;
1138 }
1139 if (LocaleCompare(map,"RGBA") == 0)
1140 {
cristycafe0412012-01-10 13:29:58 +00001141 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001142 {
cristycafe0412012-01-10 13:29:58 +00001143 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001144 if (p == (const Quantum *) NULL)
1145 break;
cristycafe0412012-01-10 13:29:58 +00001146 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001147 {
cristy6c9e1682012-01-07 21:37:44 +00001148 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1149 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1150 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1151 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001152 p+=GetPixelChannels(image);
1153 }
1154 }
1155 return;
1156 }
1157 if (LocaleCompare(map,"RGBP") == 0)
1158 {
cristycafe0412012-01-10 13:29:58 +00001159 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001160 {
cristycafe0412012-01-10 13:29:58 +00001161 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001162 if (p == (const Quantum *) NULL)
1163 break;
cristycafe0412012-01-10 13:29:58 +00001164 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001165 {
cristy6c9e1682012-01-07 21:37:44 +00001166 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1167 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1168 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1169 *q++=0;
cristye5370942012-01-06 03:49:31 +00001170 p+=GetPixelChannels(image);
1171 }
1172 }
1173 return;
1174 }
cristy14d71292012-05-20 16:48:13 +00001175 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00001176 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001177 {
cristycafe0412012-01-10 13:29:58 +00001178 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001179 if (p == (const Quantum *) NULL)
1180 break;
cristycafe0412012-01-10 13:29:58 +00001181 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001182 {
1183 register ssize_t
1184 i;
1185
cristy14d71292012-05-20 16:48:13 +00001186 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00001187 {
1188 *q=0;
1189 switch (quantum_map[i])
1190 {
1191 case RedQuantum:
1192 case CyanQuantum:
1193 {
cristy6c9e1682012-01-07 21:37:44 +00001194 *q=ScaleQuantumToLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001195 break;
1196 }
1197 case GreenQuantum:
1198 case MagentaQuantum:
1199 {
cristy6c9e1682012-01-07 21:37:44 +00001200 *q=ScaleQuantumToLong(GetPixelGreen(image,p));
cristye5370942012-01-06 03:49:31 +00001201 break;
1202 }
1203 case BlueQuantum:
1204 case YellowQuantum:
1205 {
cristy6c9e1682012-01-07 21:37:44 +00001206 *q=ScaleQuantumToLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001207 break;
1208 }
1209 case AlphaQuantum:
1210 {
cristy6c9e1682012-01-07 21:37:44 +00001211 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001212 break;
1213 }
1214 case OpacityQuantum:
1215 {
cristy6c9e1682012-01-07 21:37:44 +00001216 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001217 break;
1218 }
1219 case BlackQuantum:
1220 {
1221 if (image->colorspace == CMYKColorspace)
cristy6c9e1682012-01-07 21:37:44 +00001222 *q=ScaleQuantumToLong(GetPixelBlack(image,p));
cristye5370942012-01-06 03:49:31 +00001223 break;
1224 }
1225 case IndexQuantum:
1226 {
cristy6c9e1682012-01-07 21:37:44 +00001227 *q=ScaleQuantumToLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001228 break;
1229 }
1230 default:
cristy6c9e1682012-01-07 21:37:44 +00001231 break;
cristye5370942012-01-06 03:49:31 +00001232 }
1233 q++;
1234 }
1235 p+=GetPixelChannels(image);
1236 }
1237 }
1238}
1239
cristy2dc655d2012-07-05 13:16:28 +00001240static void ExportLongLongPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00001241 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1242 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001243{
1244 register const Quantum
1245 *restrict p;
1246
1247 register ssize_t
1248 x;
1249
cristyb13e12a2012-01-06 21:48:27 +00001250 register MagickSizeType
cristy3fe11452012-01-09 01:27:42 +00001251 *restrict q;
cristye5370942012-01-06 03:49:31 +00001252
cristy14d71292012-05-20 16:48:13 +00001253 size_t
1254 length;
1255
cristye5370942012-01-06 03:49:31 +00001256 ssize_t
1257 y;
1258
cristyb13e12a2012-01-06 21:48:27 +00001259 q=(MagickSizeType *) pixels;
cristye5370942012-01-06 03:49:31 +00001260 if (LocaleCompare(map,"BGR") == 0)
1261 {
cristycafe0412012-01-10 13:29:58 +00001262 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001263 {
cristycafe0412012-01-10 13:29:58 +00001264 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001265 if (p == (const Quantum *) NULL)
1266 break;
cristycafe0412012-01-10 13:29:58 +00001267 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001268 {
cristyb13e12a2012-01-06 21:48:27 +00001269 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1270 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1271 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001272 p+=GetPixelChannels(image);
1273 }
1274 }
1275 return;
1276 }
1277 if (LocaleCompare(map,"BGRA") == 0)
1278 {
cristycafe0412012-01-10 13:29:58 +00001279 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001280 {
cristycafe0412012-01-10 13:29:58 +00001281 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001282 if (p == (const Quantum *) NULL)
1283 break;
cristycafe0412012-01-10 13:29:58 +00001284 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001285 {
cristyb13e12a2012-01-06 21:48:27 +00001286 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1287 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1288 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1289 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001290 p+=GetPixelChannels(image);
1291 }
1292 }
1293 return;
1294 }
1295 if (LocaleCompare(map,"BGRP") == 0)
1296 {
cristycafe0412012-01-10 13:29:58 +00001297 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001298 {
cristycafe0412012-01-10 13:29:58 +00001299 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001300 if (p == (const Quantum *) NULL)
1301 break;
cristycafe0412012-01-10 13:29:58 +00001302 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001303 {
cristyb13e12a2012-01-06 21:48:27 +00001304 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1305 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1306 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001307 *q++=0;
1308 p+=GetPixelChannels(image);
1309 }
1310 }
1311 return;
1312 }
1313 if (LocaleCompare(map,"I") == 0)
1314 {
cristycafe0412012-01-10 13:29:58 +00001315 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001316 {
cristycafe0412012-01-10 13:29:58 +00001317 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001318 if (p == (const Quantum *) NULL)
1319 break;
cristycafe0412012-01-10 13:29:58 +00001320 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001321 {
cristyb13e12a2012-01-06 21:48:27 +00001322 *q++=ScaleQuantumToLongLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001323 p+=GetPixelChannels(image);
1324 }
1325 }
1326 return;
1327 }
1328 if (LocaleCompare(map,"RGB") == 0)
1329 {
cristycafe0412012-01-10 13:29:58 +00001330 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001331 {
cristycafe0412012-01-10 13:29:58 +00001332 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001333 if (p == (const Quantum *) NULL)
1334 break;
cristycafe0412012-01-10 13:29:58 +00001335 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001336 {
cristyb13e12a2012-01-06 21:48:27 +00001337 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1338 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1339 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001340 p+=GetPixelChannels(image);
1341 }
1342 }
1343 return;
1344 }
1345 if (LocaleCompare(map,"RGBA") == 0)
1346 {
cristycafe0412012-01-10 13:29:58 +00001347 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001348 {
cristycafe0412012-01-10 13:29:58 +00001349 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001350 if (p == (const Quantum *) NULL)
1351 break;
cristycafe0412012-01-10 13:29:58 +00001352 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001353 {
cristyb13e12a2012-01-06 21:48:27 +00001354 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1355 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1356 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1357 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001358 p+=GetPixelChannels(image);
1359 }
1360 }
1361 return;
1362 }
1363 if (LocaleCompare(map,"RGBP") == 0)
1364 {
cristycafe0412012-01-10 13:29:58 +00001365 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001366 {
cristycafe0412012-01-10 13:29:58 +00001367 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001368 if (p == (const Quantum *) NULL)
1369 break;
cristycafe0412012-01-10 13:29:58 +00001370 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001371 {
cristyb13e12a2012-01-06 21:48:27 +00001372 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1373 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1374 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001375 *q++=0;
1376 p+=GetPixelChannels(image);
1377 }
1378 }
1379 return;
1380 }
cristy14d71292012-05-20 16:48:13 +00001381 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00001382 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001383 {
cristycafe0412012-01-10 13:29:58 +00001384 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001385 if (p == (const Quantum *) NULL)
1386 break;
cristycafe0412012-01-10 13:29:58 +00001387 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001388 {
1389 register ssize_t
1390 i;
1391
cristy14d71292012-05-20 16:48:13 +00001392 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00001393 {
1394 *q=0;
1395 switch (quantum_map[i])
1396 {
1397 case RedQuantum:
1398 case CyanQuantum:
1399 {
cristyb13e12a2012-01-06 21:48:27 +00001400 *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001401 break;
1402 }
1403 case GreenQuantum:
1404 case MagentaQuantum:
1405 {
cristyb13e12a2012-01-06 21:48:27 +00001406 *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
cristye5370942012-01-06 03:49:31 +00001407 break;
1408 }
1409 case BlueQuantum:
1410 case YellowQuantum:
1411 {
cristyb13e12a2012-01-06 21:48:27 +00001412 *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001413 break;
1414 }
1415 case AlphaQuantum:
1416 {
cristyb13e12a2012-01-06 21:48:27 +00001417 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001418 break;
1419 }
1420 case OpacityQuantum:
1421 {
cristyb13e12a2012-01-06 21:48:27 +00001422 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001423 break;
1424 }
1425 case BlackQuantum:
1426 {
1427 if (image->colorspace == CMYKColorspace)
cristyb13e12a2012-01-06 21:48:27 +00001428 *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
cristye5370942012-01-06 03:49:31 +00001429 break;
1430 }
1431 case IndexQuantum:
1432 {
cristyb13e12a2012-01-06 21:48:27 +00001433 *q=ScaleQuantumToLongLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001434 break;
1435 }
1436 default:
1437 break;
1438 }
1439 q++;
1440 }
1441 p+=GetPixelChannels(image);
1442 }
1443 }
1444}
1445
cristy2dc655d2012-07-05 13:16:28 +00001446static void ExportQuantumPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00001447 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1448 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001449{
1450 register const Quantum
1451 *restrict p;
1452
1453 register Quantum
cristy3fe11452012-01-09 01:27:42 +00001454 *restrict q;
cristye5370942012-01-06 03:49:31 +00001455
1456 register ssize_t
1457 x;
1458
cristy14d71292012-05-20 16:48:13 +00001459 size_t
1460 length;
1461
cristye5370942012-01-06 03:49:31 +00001462 ssize_t
1463 y;
1464
1465 q=(Quantum *) pixels;
1466 if (LocaleCompare(map,"BGR") == 0)
1467 {
cristycafe0412012-01-10 13:29:58 +00001468 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001469 {
cristycafe0412012-01-10 13:29:58 +00001470 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001471 if (p == (const Quantum *) NULL)
1472 break;
cristycafe0412012-01-10 13:29:58 +00001473 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001474 {
1475 *q++=GetPixelBlue(image,p);
1476 *q++=GetPixelGreen(image,p);
1477 *q++=GetPixelRed(image,p);
1478 p+=GetPixelChannels(image);
1479 }
1480 }
1481 return;
1482 }
1483 if (LocaleCompare(map,"BGRA") == 0)
1484 {
cristycafe0412012-01-10 13:29:58 +00001485 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001486 {
cristycafe0412012-01-10 13:29:58 +00001487 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001488 if (p == (const Quantum *) NULL)
1489 break;
cristycafe0412012-01-10 13:29:58 +00001490 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001491 {
1492 *q++=GetPixelBlue(image,p);
1493 *q++=GetPixelGreen(image,p);
1494 *q++=GetPixelRed(image,p);
1495 *q++=(Quantum) (GetPixelAlpha(image,p));
1496 p+=GetPixelChannels(image);
1497 }
1498 }
1499 return;
1500 }
1501 if (LocaleCompare(map,"BGRP") == 0)
1502 {
cristycafe0412012-01-10 13:29:58 +00001503 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001504 {
cristycafe0412012-01-10 13:29:58 +00001505 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001506 if (p == (const Quantum *) NULL)
1507 break;
cristycafe0412012-01-10 13:29:58 +00001508 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001509 {
1510 *q++=GetPixelBlue(image,p);
1511 *q++=GetPixelGreen(image,p);
1512 *q++=GetPixelRed(image,p);
1513 *q++=(Quantum) 0;
1514 p+=GetPixelChannels(image);
1515 }
1516 }
1517 return;
1518 }
1519 if (LocaleCompare(map,"I") == 0)
1520 {
cristycafe0412012-01-10 13:29:58 +00001521 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001522 {
cristycafe0412012-01-10 13:29:58 +00001523 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001524 if (p == (const Quantum *) NULL)
1525 break;
cristycafe0412012-01-10 13:29:58 +00001526 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001527 {
1528 *q++=GetPixelIntensity(image,p);
1529 p+=GetPixelChannels(image);
1530 }
1531 }
1532 return;
1533 }
1534 if (LocaleCompare(map,"RGB") == 0)
1535 {
cristycafe0412012-01-10 13:29:58 +00001536 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001537 {
cristycafe0412012-01-10 13:29:58 +00001538 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001539 if (p == (const Quantum *) NULL)
1540 break;
cristycafe0412012-01-10 13:29:58 +00001541 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001542 {
1543 *q++=GetPixelRed(image,p);
1544 *q++=GetPixelGreen(image,p);
1545 *q++=GetPixelBlue(image,p);
1546 p+=GetPixelChannels(image);
1547 }
1548 }
1549 return;
1550 }
1551 if (LocaleCompare(map,"RGBA") == 0)
1552 {
cristycafe0412012-01-10 13:29:58 +00001553 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001554 {
cristycafe0412012-01-10 13:29:58 +00001555 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001556 if (p == (const Quantum *) NULL)
1557 break;
cristycafe0412012-01-10 13:29:58 +00001558 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001559 {
1560 *q++=GetPixelRed(image,p);
1561 *q++=GetPixelGreen(image,p);
1562 *q++=GetPixelBlue(image,p);
1563 *q++=(Quantum) (GetPixelAlpha(image,p));
1564 p+=GetPixelChannels(image);
1565 }
1566 }
1567 return;
1568 }
1569 if (LocaleCompare(map,"RGBP") == 0)
1570 {
cristycafe0412012-01-10 13:29:58 +00001571 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001572 {
cristycafe0412012-01-10 13:29:58 +00001573 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001574 if (p == (const Quantum *) NULL)
1575 break;
cristycafe0412012-01-10 13:29:58 +00001576 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001577 {
1578 *q++=GetPixelRed(image,p);
1579 *q++=GetPixelGreen(image,p);
1580 *q++=GetPixelBlue(image,p);
1581 *q++=(Quantum) 0;
1582 p+=GetPixelChannels(image);
1583 }
1584 }
1585 return;
1586 }
cristy14d71292012-05-20 16:48:13 +00001587 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00001588 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001589 {
cristycafe0412012-01-10 13:29:58 +00001590 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001591 if (p == (const Quantum *) NULL)
1592 break;
cristycafe0412012-01-10 13:29:58 +00001593 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001594 {
1595 register ssize_t
1596 i;
1597
cristy14d71292012-05-20 16:48:13 +00001598 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00001599 {
1600 *q=(Quantum) 0;
1601 switch (quantum_map[i])
1602 {
1603 case RedQuantum:
1604 case CyanQuantum:
1605 {
1606 *q=GetPixelRed(image,p);
1607 break;
1608 }
1609 case GreenQuantum:
1610 case MagentaQuantum:
1611 {
1612 *q=GetPixelGreen(image,p);
1613 break;
1614 }
1615 case BlueQuantum:
1616 case YellowQuantum:
1617 {
1618 *q=GetPixelBlue(image,p);
1619 break;
1620 }
1621 case AlphaQuantum:
1622 {
1623 *q=GetPixelAlpha(image,p);
1624 break;
1625 }
1626 case OpacityQuantum:
1627 {
1628 *q=GetPixelAlpha(image,p);
1629 break;
1630 }
1631 case BlackQuantum:
1632 {
1633 if (image->colorspace == CMYKColorspace)
1634 *q=GetPixelBlack(image,p);
1635 break;
1636 }
1637 case IndexQuantum:
1638 {
1639 *q=(GetPixelIntensity(image,p));
1640 break;
1641 }
1642 default:
1643 {
1644 *q=(Quantum) 0;
1645 break;
1646 }
1647 }
1648 q++;
1649 }
1650 p+=GetPixelChannels(image);
1651 }
1652 }
1653}
1654
cristy2dc655d2012-07-05 13:16:28 +00001655static void ExportShortPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00001656 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1657 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001658{
1659 register const Quantum
1660 *restrict p;
1661
1662 register ssize_t
1663 x;
1664
cristye5370942012-01-06 03:49:31 +00001665 register unsigned short
cristy3fe11452012-01-09 01:27:42 +00001666 *restrict q;
cristye5370942012-01-06 03:49:31 +00001667
cristy14d71292012-05-20 16:48:13 +00001668 size_t
1669 length;
1670
1671 ssize_t
1672 y;
1673
cristye5370942012-01-06 03:49:31 +00001674 q=(unsigned short *) pixels;
1675 if (LocaleCompare(map,"BGR") == 0)
1676 {
cristycafe0412012-01-10 13:29:58 +00001677 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001678 {
cristycafe0412012-01-10 13:29:58 +00001679 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001680 if (p == (const Quantum *) NULL)
1681 break;
cristycafe0412012-01-10 13:29:58 +00001682 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001683 {
1684 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1685 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1686 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1687 p+=GetPixelChannels(image);
1688 }
1689 }
1690 return;
1691 }
1692 if (LocaleCompare(map,"BGRA") == 0)
1693 {
cristycafe0412012-01-10 13:29:58 +00001694 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001695 {
cristycafe0412012-01-10 13:29:58 +00001696 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001697 if (p == (const Quantum *) NULL)
1698 break;
cristycafe0412012-01-10 13:29:58 +00001699 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001700 {
1701 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1702 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1703 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1704 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1705 p+=GetPixelChannels(image);
1706 }
1707 }
1708 return;
1709 }
1710 if (LocaleCompare(map,"BGRP") == 0)
1711 {
cristycafe0412012-01-10 13:29:58 +00001712 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001713 {
cristycafe0412012-01-10 13:29:58 +00001714 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001715 if (p == (const Quantum *) NULL)
1716 break;
cristycafe0412012-01-10 13:29:58 +00001717 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001718 {
1719 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1720 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1721 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1722 *q++=0;
1723 p+=GetPixelChannels(image);
1724 }
1725 }
1726 return;
1727 }
1728 if (LocaleCompare(map,"I") == 0)
1729 {
cristycafe0412012-01-10 13:29:58 +00001730 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001731 {
cristycafe0412012-01-10 13:29:58 +00001732 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001733 if (p == (const Quantum *) NULL)
1734 break;
cristycafe0412012-01-10 13:29:58 +00001735 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001736 {
1737 *q++=ScaleQuantumToShort(GetPixelIntensity(image,p));
1738 p+=GetPixelChannels(image);
1739 }
1740 }
1741 return;
1742 }
1743 if (LocaleCompare(map,"RGB") == 0)
1744 {
cristycafe0412012-01-10 13:29:58 +00001745 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001746 {
cristycafe0412012-01-10 13:29:58 +00001747 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001748 if (p == (const Quantum *) NULL)
1749 break;
cristycafe0412012-01-10 13:29:58 +00001750 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001751 {
1752 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1753 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1754 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1755 p+=GetPixelChannels(image);
1756 }
1757 }
1758 return;
1759 }
1760 if (LocaleCompare(map,"RGBA") == 0)
1761 {
cristycafe0412012-01-10 13:29:58 +00001762 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001763 {
cristycafe0412012-01-10 13:29:58 +00001764 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001765 if (p == (const Quantum *) NULL)
1766 break;
cristycafe0412012-01-10 13:29:58 +00001767 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001768 {
1769 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1770 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1771 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1772 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1773 p+=GetPixelChannels(image);
1774 }
1775 }
1776 return;
1777 }
1778 if (LocaleCompare(map,"RGBP") == 0)
1779 {
cristycafe0412012-01-10 13:29:58 +00001780 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001781 {
cristycafe0412012-01-10 13:29:58 +00001782 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001783 if (p == (const Quantum *) NULL)
1784 break;
cristycafe0412012-01-10 13:29:58 +00001785 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001786 {
1787 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1788 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1789 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1790 *q++=0;
1791 p+=GetPixelChannels(image);
1792 }
1793 }
1794 return;
1795 }
cristy14d71292012-05-20 16:48:13 +00001796 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00001797 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001798 {
cristycafe0412012-01-10 13:29:58 +00001799 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001800 if (p == (const Quantum *) NULL)
1801 break;
cristycafe0412012-01-10 13:29:58 +00001802 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001803 {
1804 register ssize_t
1805 i;
1806
cristy14d71292012-05-20 16:48:13 +00001807 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00001808 {
1809 *q=0;
1810 switch (quantum_map[i])
1811 {
1812 case RedQuantum:
1813 case CyanQuantum:
1814 {
1815 *q=ScaleQuantumToShort(GetPixelRed(image,p));
1816 break;
1817 }
1818 case GreenQuantum:
1819 case MagentaQuantum:
1820 {
1821 *q=ScaleQuantumToShort(GetPixelGreen(image,p));
1822 break;
1823 }
1824 case BlueQuantum:
1825 case YellowQuantum:
1826 {
1827 *q=ScaleQuantumToShort(GetPixelBlue(image,p));
1828 break;
1829 }
1830 case AlphaQuantum:
1831 {
1832 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1833 break;
1834 }
1835 case OpacityQuantum:
1836 {
1837 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1838 break;
1839 }
1840 case BlackQuantum:
1841 {
1842 if (image->colorspace == CMYKColorspace)
1843 *q=ScaleQuantumToShort(GetPixelBlack(image,p));
1844 break;
1845 }
1846 case IndexQuantum:
1847 {
1848 *q=ScaleQuantumToShort(GetPixelIntensity(image,p));
1849 break;
1850 }
1851 default:
1852 break;
1853 }
1854 q++;
1855 }
1856 p+=GetPixelChannels(image);
1857 }
1858 }
1859}
1860
cristy2dc655d2012-07-05 13:16:28 +00001861MagickExport MagickBooleanType ExportImagePixels(Image *image,
cristycafe0412012-01-10 13:29:58 +00001862 const ssize_t x,const ssize_t y,const size_t width,const size_t height,
1863 const char *map,const StorageType type,void *pixels,ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00001864{
1865 QuantumType
1866 *quantum_map;
1867
cristycafe0412012-01-10 13:29:58 +00001868 RectangleInfo
1869 roi;
1870
cristy4c08aed2011-07-01 19:47:50 +00001871 register ssize_t
cristye5370942012-01-06 03:49:31 +00001872 i;
cristy4c08aed2011-07-01 19:47:50 +00001873
cristy14d71292012-05-20 16:48:13 +00001874 size_t
1875 length;
1876
cristy4c08aed2011-07-01 19:47:50 +00001877 assert(image != (Image *) NULL);
1878 assert(image->signature == MagickSignature);
1879 if (image->debug != MagickFalse)
1880 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristy14d71292012-05-20 16:48:13 +00001881 length=strlen(map);
1882 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
cristy4c08aed2011-07-01 19:47:50 +00001883 if (quantum_map == (QuantumType *) NULL)
1884 {
1885 (void) ThrowMagickException(exception,GetMagickModule(),
cristyefe601c2013-01-05 17:51:12 +00001886 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
cristy4c08aed2011-07-01 19:47:50 +00001887 return(MagickFalse);
1888 }
cristy14d71292012-05-20 16:48:13 +00001889 for (i=0; i < (ssize_t) length; i++)
cristy4c08aed2011-07-01 19:47:50 +00001890 {
1891 switch (map[i])
1892 {
1893 case 'A':
1894 case 'a':
1895 {
1896 quantum_map[i]=AlphaQuantum;
1897 break;
1898 }
1899 case 'B':
1900 case 'b':
1901 {
1902 quantum_map[i]=BlueQuantum;
1903 break;
1904 }
1905 case 'C':
1906 case 'c':
1907 {
1908 quantum_map[i]=CyanQuantum;
1909 if (image->colorspace == CMYKColorspace)
1910 break;
1911 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1912 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristyefe601c2013-01-05 17:51:12 +00001913 "ColorSeparatedImageRequired","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001914 return(MagickFalse);
1915 }
1916 case 'g':
1917 case 'G':
1918 {
1919 quantum_map[i]=GreenQuantum;
1920 break;
1921 }
1922 case 'I':
1923 case 'i':
1924 {
1925 quantum_map[i]=IndexQuantum;
1926 break;
1927 }
1928 case 'K':
1929 case 'k':
1930 {
1931 quantum_map[i]=BlackQuantum;
1932 if (image->colorspace == CMYKColorspace)
1933 break;
1934 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1935 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristyefe601c2013-01-05 17:51:12 +00001936 "ColorSeparatedImageRequired","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001937 return(MagickFalse);
1938 }
1939 case 'M':
1940 case 'm':
1941 {
1942 quantum_map[i]=MagentaQuantum;
1943 if (image->colorspace == CMYKColorspace)
1944 break;
1945 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1946 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristyefe601c2013-01-05 17:51:12 +00001947 "ColorSeparatedImageRequired","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001948 return(MagickFalse);
1949 }
1950 case 'o':
1951 case 'O':
1952 {
1953 quantum_map[i]=OpacityQuantum;
1954 break;
1955 }
1956 case 'P':
1957 case 'p':
1958 {
1959 quantum_map[i]=UndefinedQuantum;
1960 break;
1961 }
1962 case 'R':
1963 case 'r':
1964 {
1965 quantum_map[i]=RedQuantum;
1966 break;
1967 }
1968 case 'Y':
1969 case 'y':
1970 {
1971 quantum_map[i]=YellowQuantum;
1972 if (image->colorspace == CMYKColorspace)
1973 break;
1974 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1975 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
cristyefe601c2013-01-05 17:51:12 +00001976 "ColorSeparatedImageRequired","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001977 return(MagickFalse);
1978 }
1979 default:
1980 {
1981 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1982 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
cristyefe601c2013-01-05 17:51:12 +00001983 "UnrecognizedPixelMap","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001984 return(MagickFalse);
1985 }
1986 }
1987 }
cristycafe0412012-01-10 13:29:58 +00001988 roi.width=width;
1989 roi.height=height;
1990 roi.x=x;
1991 roi.y=y;
cristy4c08aed2011-07-01 19:47:50 +00001992 switch (type)
1993 {
1994 case CharPixel:
1995 {
cristycafe0412012-01-10 13:29:58 +00001996 ExportCharPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001997 break;
1998 }
1999 case DoublePixel:
2000 {
cristycafe0412012-01-10 13:29:58 +00002001 ExportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00002002 break;
2003 }
2004 case FloatPixel:
2005 {
cristycafe0412012-01-10 13:29:58 +00002006 ExportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00002007 break;
2008 }
cristy4c08aed2011-07-01 19:47:50 +00002009 case LongPixel:
2010 {
cristycafe0412012-01-10 13:29:58 +00002011 ExportLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00002012 break;
2013 }
cristy6c9e1682012-01-07 21:37:44 +00002014 case LongLongPixel:
2015 {
cristycafe0412012-01-10 13:29:58 +00002016 ExportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy6c9e1682012-01-07 21:37:44 +00002017 break;
2018 }
cristy4c08aed2011-07-01 19:47:50 +00002019 case QuantumPixel:
2020 {
cristycafe0412012-01-10 13:29:58 +00002021 ExportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00002022 break;
2023 }
2024 case ShortPixel:
2025 {
cristycafe0412012-01-10 13:29:58 +00002026 ExportShortPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00002027 break;
2028 }
2029 default:
2030 {
2031 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2032 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
cristyefe601c2013-01-05 17:51:12 +00002033 "UnrecognizedPixelMap","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00002034 break;
2035 }
2036 }
2037 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2038 return(MagickTrue);
2039}
2040
2041/*
2042%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2043% %
2044% %
2045% %
cristyaa8634f2011-10-01 13:25:12 +00002046% G e t P i x e l I n f o %
cristy4c08aed2011-07-01 19:47:50 +00002047% %
2048% %
2049% %
2050%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2051%
2052% GetPixelInfo() initializes the PixelInfo structure.
2053%
2054% The format of the GetPixelInfo method is:
2055%
2056% GetPixelInfo(const Image *image,PixelInfo *pixel)
2057%
2058% A description of each parameter follows:
2059%
2060% o image: the image.
2061%
cristy101ab702011-10-13 13:06:32 +00002062% o pixel: Specifies a pointer to a PixelInfo structure.
cristy4c08aed2011-07-01 19:47:50 +00002063%
2064*/
cristyaa8634f2011-10-01 13:25:12 +00002065MagickExport void GetPixelInfo(const Image *image,PixelInfo *pixel)
cristy4c08aed2011-07-01 19:47:50 +00002066{
2067 pixel->storage_class=DirectClass;
cristy7020ae62012-04-18 12:58:34 +00002068 pixel->colorspace=sRGBColorspace;
cristy8a46d822012-08-28 23:32:39 +00002069 pixel->alpha_trait=UndefinedPixelTrait;
cristy4c08aed2011-07-01 19:47:50 +00002070 pixel->fuzz=0.0;
2071 pixel->depth=MAGICKCORE_QUANTUM_DEPTH;
2072 pixel->red=0.0;
2073 pixel->green=0.0;
2074 pixel->blue=0.0;
2075 pixel->black=0.0;
cristya19f1d72012-08-07 18:24:38 +00002076 pixel->alpha=(double) OpaqueAlpha;
cristy4c08aed2011-07-01 19:47:50 +00002077 pixel->index=0.0;
2078 if (image == (const Image *) NULL)
2079 return;
2080 pixel->storage_class=image->storage_class;
2081 pixel->colorspace=image->colorspace;
cristy8a46d822012-08-28 23:32:39 +00002082 pixel->alpha_trait=image->alpha_trait;
cristy4c08aed2011-07-01 19:47:50 +00002083 pixel->depth=image->depth;
2084 pixel->fuzz=image->fuzz;
2085}
2086
2087/*
2088%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2089% %
2090% %
2091% %
2092% I m p o r t I m a g e P i x e l s %
2093% %
2094% %
2095% %
2096%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2097%
2098% ImportImagePixels() accepts pixel data and stores in the image at the
2099% location you specify. The method returns MagickTrue on success otherwise
2100% MagickFalse if an error is encountered. The pixel data can be either char,
cristyb5a45a32012-01-10 13:31:13 +00002101% Quantum, short int, unsigned int, unsigned long long, float, or double in
2102% the order specified by map.
cristy4c08aed2011-07-01 19:47:50 +00002103%
2104% Suppose your want to upload the first scanline of a 640x480 image from
2105% character data in red-green-blue order:
2106%
2107% ImportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels);
2108%
2109% The format of the ImportImagePixels method is:
2110%
cristycafe0412012-01-10 13:29:58 +00002111% MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
2112% const ssize_t y,const size_t width,const size_t height,
2113% const char *map,const StorageType type,const void *pixels,
2114% ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00002115%
2116% A description of each parameter follows:
2117%
2118% o image: the image.
2119%
cristycafe0412012-01-10 13:29:58 +00002120% o x,y,width,height: These values define the perimeter
cristy4c08aed2011-07-01 19:47:50 +00002121% of a region of pixels you want to define.
2122%
2123% o map: This string reflects the expected ordering of the pixel array.
2124% It can be any combination or order of R = red, G = green, B = blue,
2125% A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
2126% Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
2127% P = pad.
2128%
2129% o type: Define the data type of the pixels. Float and double types are
2130% normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
cristy6c9e1682012-01-07 21:37:44 +00002131% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
cristyff6834e2012-01-10 03:00:25 +00002132% LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
cristy6c9e1682012-01-07 21:37:44 +00002133% QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
cristy4c08aed2011-07-01 19:47:50 +00002134%
2135% o pixels: This array of values contain the pixel components as defined by
2136% map and type. You must preallocate this array where the expected
2137% length varies depending on the values of width, height, map, and type.
2138%
cristy018f07f2011-09-04 21:15:19 +00002139% o exception: return any errors or warnings in this structure.
2140%
cristy4c08aed2011-07-01 19:47:50 +00002141*/
cristye5370942012-01-06 03:49:31 +00002142
cristycafe0412012-01-10 13:29:58 +00002143static void ImportCharPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002144 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2145 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002146{
2147 register const unsigned char
2148 *restrict p;
2149
2150 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002151 *restrict q;
cristye5370942012-01-06 03:49:31 +00002152
2153 register ssize_t
2154 x;
2155
cristy14d71292012-05-20 16:48:13 +00002156 size_t
2157 length;
2158
cristye5370942012-01-06 03:49:31 +00002159 ssize_t
2160 y;
2161
2162 p=(const unsigned char *) pixels;
2163 if (LocaleCompare(map,"BGR") == 0)
2164 {
cristycafe0412012-01-10 13:29:58 +00002165 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002166 {
cristycafe0412012-01-10 13:29:58 +00002167 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002168 if (q == (Quantum *) NULL)
2169 break;
cristycafe0412012-01-10 13:29:58 +00002170 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002171 {
2172 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2173 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2174 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2175 q+=GetPixelChannels(image);
2176 }
2177 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2178 break;
2179 }
2180 return;
2181 }
2182 if (LocaleCompare(map,"BGRA") == 0)
2183 {
cristycafe0412012-01-10 13:29:58 +00002184 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002185 {
cristycafe0412012-01-10 13:29:58 +00002186 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002187 if (q == (Quantum *) NULL)
2188 break;
cristycafe0412012-01-10 13:29:58 +00002189 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002190 {
2191 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2192 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2193 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2194 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2195 q+=GetPixelChannels(image);
2196 }
2197 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2198 break;
2199 }
2200 return;
2201 }
2202 if (LocaleCompare(map,"BGRO") == 0)
2203 {
cristycafe0412012-01-10 13:29:58 +00002204 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002205 {
cristycafe0412012-01-10 13:29:58 +00002206 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002207 if (q == (Quantum *) NULL)
2208 break;
cristycafe0412012-01-10 13:29:58 +00002209 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002210 {
2211 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2212 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2213 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2214 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2215 q+=GetPixelChannels(image);
2216 }
2217 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2218 break;
2219 }
2220 return;
2221 }
2222 if (LocaleCompare(map,"BGRP") == 0)
2223 {
cristycafe0412012-01-10 13:29:58 +00002224 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002225 {
cristycafe0412012-01-10 13:29:58 +00002226 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002227 if (q == (Quantum *) NULL)
2228 break;
cristycafe0412012-01-10 13:29:58 +00002229 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002230 {
2231 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2232 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2233 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2234 p++;
2235 q+=GetPixelChannels(image);
2236 }
2237 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2238 break;
2239 }
2240 return;
2241 }
2242 if (LocaleCompare(map,"I") == 0)
2243 {
cristycafe0412012-01-10 13:29:58 +00002244 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002245 {
cristycafe0412012-01-10 13:29:58 +00002246 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002247 if (q == (Quantum *) NULL)
2248 break;
cristycafe0412012-01-10 13:29:58 +00002249 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002250 {
2251 SetPixelGray(image,ScaleCharToQuantum(*p++),q);
2252 q+=GetPixelChannels(image);
2253 }
2254 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2255 break;
2256 }
2257 return;
2258 }
2259 if (LocaleCompare(map,"RGB") == 0)
2260 {
cristycafe0412012-01-10 13:29:58 +00002261 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002262 {
cristycafe0412012-01-10 13:29:58 +00002263 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002264 if (q == (Quantum *) NULL)
2265 break;
cristycafe0412012-01-10 13:29:58 +00002266 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002267 {
2268 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2269 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2270 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2271 q+=GetPixelChannels(image);
2272 }
2273 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2274 break;
2275 }
2276 return;
2277 }
2278 if (LocaleCompare(map,"RGBA") == 0)
2279 {
cristycafe0412012-01-10 13:29:58 +00002280 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002281 {
cristycafe0412012-01-10 13:29:58 +00002282 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002283 if (q == (Quantum *) NULL)
2284 break;
cristycafe0412012-01-10 13:29:58 +00002285 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002286 {
2287 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2288 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2289 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2290 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2291 q+=GetPixelChannels(image);
2292 }
2293 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2294 break;
2295 }
2296 return;
2297 }
2298 if (LocaleCompare(map,"RGBO") == 0)
2299 {
cristycafe0412012-01-10 13:29:58 +00002300 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002301 {
cristycafe0412012-01-10 13:29:58 +00002302 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002303 if (q == (Quantum *) NULL)
2304 break;
cristycafe0412012-01-10 13:29:58 +00002305 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002306 {
2307 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2308 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2309 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2310 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2311 q+=GetPixelChannels(image);
2312 }
2313 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2314 break;
2315 }
2316 return;
2317 }
2318 if (LocaleCompare(map,"RGBP") == 0)
2319 {
cristycafe0412012-01-10 13:29:58 +00002320 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002321 {
cristycafe0412012-01-10 13:29:58 +00002322 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002323 if (q == (Quantum *) NULL)
2324 break;
cristycafe0412012-01-10 13:29:58 +00002325 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002326 {
2327 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2328 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2329 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2330 p++;
2331 q+=GetPixelChannels(image);
2332 }
2333 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2334 break;
2335 }
2336 return;
2337 }
cristy14d71292012-05-20 16:48:13 +00002338 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00002339 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002340 {
cristycafe0412012-01-10 13:29:58 +00002341 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002342 if (q == (Quantum *) NULL)
2343 break;
cristycafe0412012-01-10 13:29:58 +00002344 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002345 {
2346 register ssize_t
2347 i;
2348
cristy14d71292012-05-20 16:48:13 +00002349 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00002350 {
2351 switch (quantum_map[i])
2352 {
2353 case RedQuantum:
2354 case CyanQuantum:
2355 {
2356 SetPixelRed(image,ScaleCharToQuantum(*p),q);
2357 break;
2358 }
2359 case GreenQuantum:
2360 case MagentaQuantum:
2361 {
2362 SetPixelGreen(image,ScaleCharToQuantum(*p),q);
2363 break;
2364 }
2365 case BlueQuantum:
2366 case YellowQuantum:
2367 {
2368 SetPixelBlue(image,ScaleCharToQuantum(*p),q);
2369 break;
2370 }
2371 case AlphaQuantum:
2372 {
2373 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2374 break;
2375 }
2376 case OpacityQuantum:
2377 {
2378 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2379 break;
2380 }
2381 case BlackQuantum:
2382 {
2383 SetPixelBlack(image,ScaleCharToQuantum(*p),q);
2384 break;
2385 }
2386 case IndexQuantum:
2387 {
2388 SetPixelGray(image,ScaleCharToQuantum(*p),q);
2389 break;
2390 }
2391 default:
2392 break;
2393 }
2394 p++;
2395 }
2396 q+=GetPixelChannels(image);
2397 }
2398 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2399 break;
2400 }
2401}
2402
cristycafe0412012-01-10 13:29:58 +00002403static void ImportDoublePixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002404 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2405 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002406{
2407 register const double
2408 *restrict p;
2409
2410 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002411 *restrict q;
cristye5370942012-01-06 03:49:31 +00002412
2413 register ssize_t
2414 x;
2415
cristy14d71292012-05-20 16:48:13 +00002416 size_t
2417 length;
2418
cristye5370942012-01-06 03:49:31 +00002419 ssize_t
2420 y;
2421
2422 p=(const double *) pixels;
2423 if (LocaleCompare(map,"BGR") == 0)
2424 {
cristycafe0412012-01-10 13:29:58 +00002425 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002426 {
cristycafe0412012-01-10 13:29:58 +00002427 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002428 if (q == (Quantum *) NULL)
2429 break;
cristycafe0412012-01-10 13:29:58 +00002430 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002431 {
cristy8cd03c32012-07-07 18:57:59 +00002432 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002433 p++;
cristy8cd03c32012-07-07 18:57:59 +00002434 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002435 p++;
cristy8cd03c32012-07-07 18:57:59 +00002436 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002437 p++;
2438 q+=GetPixelChannels(image);
2439 }
2440 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2441 break;
2442 }
2443 return;
2444 }
2445 if (LocaleCompare(map,"BGRA") == 0)
2446 {
cristycafe0412012-01-10 13:29:58 +00002447 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002448 {
cristycafe0412012-01-10 13:29:58 +00002449 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002450 if (q == (Quantum *) NULL)
2451 break;
cristycafe0412012-01-10 13:29:58 +00002452 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002453 {
cristy8cd03c32012-07-07 18:57:59 +00002454 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002455 p++;
cristy8cd03c32012-07-07 18:57:59 +00002456 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002457 p++;
cristy8cd03c32012-07-07 18:57:59 +00002458 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002459 p++;
cristy8cd03c32012-07-07 18:57:59 +00002460 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002461 p++;
2462 q+=GetPixelChannels(image);
2463 }
2464 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2465 break;
2466 }
2467 return;
2468 }
2469 if (LocaleCompare(map,"BGRP") == 0)
2470 {
cristycafe0412012-01-10 13:29:58 +00002471 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002472 {
cristycafe0412012-01-10 13:29:58 +00002473 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002474 if (q == (Quantum *) NULL)
2475 break;
cristycafe0412012-01-10 13:29:58 +00002476 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002477 {
cristy8cd03c32012-07-07 18:57:59 +00002478 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002479 p++;
cristy8cd03c32012-07-07 18:57:59 +00002480 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002481 p++;
cristy8cd03c32012-07-07 18:57:59 +00002482 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002483 p++;
2484 p++;
2485 q+=GetPixelChannels(image);
2486 }
2487 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2488 break;
2489 }
2490 return;
2491 }
2492 if (LocaleCompare(map,"I") == 0)
2493 {
cristycafe0412012-01-10 13:29:58 +00002494 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002495 {
cristycafe0412012-01-10 13:29:58 +00002496 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002497 if (q == (Quantum *) NULL)
2498 break;
cristycafe0412012-01-10 13:29:58 +00002499 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002500 {
cristy8cd03c32012-07-07 18:57:59 +00002501 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002502 p++;
2503 q+=GetPixelChannels(image);
2504 }
2505 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2506 break;
2507 }
2508 return;
2509 }
2510 if (LocaleCompare(map,"RGB") == 0)
2511 {
cristycafe0412012-01-10 13:29:58 +00002512 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002513 {
cristycafe0412012-01-10 13:29:58 +00002514 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002515 if (q == (Quantum *) NULL)
2516 break;
cristycafe0412012-01-10 13:29:58 +00002517 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002518 {
cristy8cd03c32012-07-07 18:57:59 +00002519 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002520 p++;
cristy8cd03c32012-07-07 18:57:59 +00002521 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002522 p++;
cristy8cd03c32012-07-07 18:57:59 +00002523 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002524 p++;
2525 q+=GetPixelChannels(image);
2526 }
2527 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2528 break;
2529 }
2530 return;
2531 }
2532 if (LocaleCompare(map,"RGBA") == 0)
2533 {
cristycafe0412012-01-10 13:29:58 +00002534 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002535 {
cristycafe0412012-01-10 13:29:58 +00002536 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002537 if (q == (Quantum *) NULL)
2538 break;
cristycafe0412012-01-10 13:29:58 +00002539 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002540 {
cristy8cd03c32012-07-07 18:57:59 +00002541 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002542 p++;
cristy8cd03c32012-07-07 18:57:59 +00002543 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002544 p++;
cristy8cd03c32012-07-07 18:57:59 +00002545 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002546 p++;
cristy8cd03c32012-07-07 18:57:59 +00002547 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002548 p++;
2549 q+=GetPixelChannels(image);
2550 }
2551 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2552 break;
2553 }
2554 return;
2555 }
2556 if (LocaleCompare(map,"RGBP") == 0)
2557 {
cristycafe0412012-01-10 13:29:58 +00002558 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002559 {
cristycafe0412012-01-10 13:29:58 +00002560 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002561 if (q == (Quantum *) NULL)
2562 break;
cristycafe0412012-01-10 13:29:58 +00002563 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002564 {
cristy8cd03c32012-07-07 18:57:59 +00002565 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002566 p++;
cristy8cd03c32012-07-07 18:57:59 +00002567 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002568 p++;
cristy8cd03c32012-07-07 18:57:59 +00002569 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002570 p++;
2571 q+=GetPixelChannels(image);
2572 }
2573 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2574 break;
2575 }
2576 return;
2577 }
cristy14d71292012-05-20 16:48:13 +00002578 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00002579 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002580 {
cristycafe0412012-01-10 13:29:58 +00002581 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002582 if (q == (Quantum *) NULL)
2583 break;
cristycafe0412012-01-10 13:29:58 +00002584 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002585 {
2586 register ssize_t
2587 i;
2588
cristy14d71292012-05-20 16:48:13 +00002589 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00002590 {
2591 switch (quantum_map[i])
2592 {
2593 case RedQuantum:
2594 case CyanQuantum:
2595 {
cristy8cd03c32012-07-07 18:57:59 +00002596 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002597 break;
2598 }
2599 case GreenQuantum:
2600 case MagentaQuantum:
2601 {
cristy8cd03c32012-07-07 18:57:59 +00002602 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002603 break;
2604 }
2605 case BlueQuantum:
2606 case YellowQuantum:
2607 {
cristy8cd03c32012-07-07 18:57:59 +00002608 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002609 break;
2610 }
2611 case AlphaQuantum:
2612 {
cristy8cd03c32012-07-07 18:57:59 +00002613 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002614 break;
2615 }
2616 case OpacityQuantum:
2617 {
cristy8cd03c32012-07-07 18:57:59 +00002618 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002619 break;
2620 }
2621 case BlackQuantum:
2622 {
cristy8cd03c32012-07-07 18:57:59 +00002623 SetPixelBlack(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002624 break;
2625 }
2626 case IndexQuantum:
2627 {
cristy8cd03c32012-07-07 18:57:59 +00002628 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002629 break;
2630 }
2631 default:
2632 break;
2633 }
2634 p++;
2635 }
2636 q+=GetPixelChannels(image);
2637 }
2638 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2639 break;
2640 }
2641}
2642
cristycafe0412012-01-10 13:29:58 +00002643static void ImportFloatPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002644 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2645 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002646{
2647 register const float
2648 *restrict p;
2649
2650 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002651 *restrict q;
cristye5370942012-01-06 03:49:31 +00002652
2653 register ssize_t
2654 x;
2655
cristy14d71292012-05-20 16:48:13 +00002656 size_t
2657 length;
2658
cristye5370942012-01-06 03:49:31 +00002659 ssize_t
2660 y;
2661
2662 p=(const float *) pixels;
2663 if (LocaleCompare(map,"BGR") == 0)
2664 {
cristycafe0412012-01-10 13:29:58 +00002665 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002666 {
cristycafe0412012-01-10 13:29:58 +00002667 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002668 if (q == (Quantum *) NULL)
2669 break;
cristycafe0412012-01-10 13:29:58 +00002670 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002671 {
cristy8cd03c32012-07-07 18:57:59 +00002672 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002673 p++;
cristy8cd03c32012-07-07 18:57:59 +00002674 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002675 p++;
cristy8cd03c32012-07-07 18:57:59 +00002676 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002677 p++;
2678 q+=GetPixelChannels(image);
2679 }
2680 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2681 break;
2682 }
2683 return;
2684 }
2685 if (LocaleCompare(map,"BGRA") == 0)
2686 {
cristycafe0412012-01-10 13:29:58 +00002687 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002688 {
cristycafe0412012-01-10 13:29:58 +00002689 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002690 if (q == (Quantum *) NULL)
2691 break;
cristycafe0412012-01-10 13:29:58 +00002692 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002693 {
cristy8cd03c32012-07-07 18:57:59 +00002694 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002695 p++;
cristy8cd03c32012-07-07 18:57:59 +00002696 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002697 p++;
cristy8cd03c32012-07-07 18:57:59 +00002698 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002699 p++;
cristy8cd03c32012-07-07 18:57:59 +00002700 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002701 p++;
2702 q+=GetPixelChannels(image);
2703 }
2704 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2705 break;
2706 }
2707 return;
2708 }
2709 if (LocaleCompare(map,"BGRP") == 0)
2710 {
cristycafe0412012-01-10 13:29:58 +00002711 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002712 {
cristycafe0412012-01-10 13:29:58 +00002713 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002714 if (q == (Quantum *) NULL)
2715 break;
cristycafe0412012-01-10 13:29:58 +00002716 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002717 {
cristy8cd03c32012-07-07 18:57:59 +00002718 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002719 p++;
cristy8cd03c32012-07-07 18:57:59 +00002720 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002721 p++;
cristy8cd03c32012-07-07 18:57:59 +00002722 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002723 p++;
2724 p++;
2725 q+=GetPixelChannels(image);
2726 }
2727 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2728 break;
2729 }
2730 return;
2731 }
2732 if (LocaleCompare(map,"I") == 0)
2733 {
cristycafe0412012-01-10 13:29:58 +00002734 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002735 {
cristycafe0412012-01-10 13:29:58 +00002736 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002737 if (q == (Quantum *) NULL)
2738 break;
cristycafe0412012-01-10 13:29:58 +00002739 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002740 {
cristy8cd03c32012-07-07 18:57:59 +00002741 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002742 p++;
2743 q+=GetPixelChannels(image);
2744 }
2745 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2746 break;
2747 }
2748 return;
2749 }
2750 if (LocaleCompare(map,"RGB") == 0)
2751 {
cristycafe0412012-01-10 13:29:58 +00002752 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002753 {
cristycafe0412012-01-10 13:29:58 +00002754 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002755 if (q == (Quantum *) NULL)
2756 break;
cristycafe0412012-01-10 13:29:58 +00002757 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002758 {
cristy8cd03c32012-07-07 18:57:59 +00002759 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002760 p++;
cristy8cd03c32012-07-07 18:57:59 +00002761 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002762 p++;
cristy8cd03c32012-07-07 18:57:59 +00002763 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002764 p++;
2765 q+=GetPixelChannels(image);
2766 }
2767 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2768 break;
2769 }
2770 return;
2771 }
2772 if (LocaleCompare(map,"RGBA") == 0)
2773 {
cristycafe0412012-01-10 13:29:58 +00002774 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002775 {
cristycafe0412012-01-10 13:29:58 +00002776 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002777 if (q == (Quantum *) NULL)
2778 break;
cristycafe0412012-01-10 13:29:58 +00002779 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002780 {
cristy8cd03c32012-07-07 18:57:59 +00002781 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002782 p++;
cristy8cd03c32012-07-07 18:57:59 +00002783 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002784 p++;
cristy8cd03c32012-07-07 18:57:59 +00002785 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002786 p++;
cristy8cd03c32012-07-07 18:57:59 +00002787 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002788 p++;
2789 q+=GetPixelChannels(image);
2790 }
2791 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2792 break;
2793 }
2794 return;
2795 }
2796 if (LocaleCompare(map,"RGBP") == 0)
2797 {
cristycafe0412012-01-10 13:29:58 +00002798 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002799 {
cristycafe0412012-01-10 13:29:58 +00002800 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002801 if (q == (Quantum *) NULL)
2802 break;
cristycafe0412012-01-10 13:29:58 +00002803 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002804 {
cristy8cd03c32012-07-07 18:57:59 +00002805 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002806 p++;
cristy8cd03c32012-07-07 18:57:59 +00002807 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002808 p++;
cristy8cd03c32012-07-07 18:57:59 +00002809 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002810 p++;
2811 q+=GetPixelChannels(image);
2812 }
2813 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2814 break;
2815 }
2816 return;
2817 }
cristy14d71292012-05-20 16:48:13 +00002818 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00002819 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002820 {
cristycafe0412012-01-10 13:29:58 +00002821 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002822 if (q == (Quantum *) NULL)
2823 break;
cristycafe0412012-01-10 13:29:58 +00002824 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002825 {
2826 register ssize_t
2827 i;
2828
cristy14d71292012-05-20 16:48:13 +00002829 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00002830 {
2831 switch (quantum_map[i])
2832 {
2833 case RedQuantum:
2834 case CyanQuantum:
2835 {
cristy8cd03c32012-07-07 18:57:59 +00002836 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002837 break;
2838 }
2839 case GreenQuantum:
2840 case MagentaQuantum:
2841 {
cristy8cd03c32012-07-07 18:57:59 +00002842 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002843 break;
2844 }
2845 case BlueQuantum:
2846 case YellowQuantum:
2847 {
cristy8cd03c32012-07-07 18:57:59 +00002848 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002849 break;
2850 }
2851 case AlphaQuantum:
2852 {
cristy8cd03c32012-07-07 18:57:59 +00002853 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002854 break;
2855 }
2856 case OpacityQuantum:
2857 {
cristy8cd03c32012-07-07 18:57:59 +00002858 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002859 break;
2860 }
2861 case BlackQuantum:
2862 {
cristy8cd03c32012-07-07 18:57:59 +00002863 SetPixelBlack(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002864 break;
2865 }
2866 case IndexQuantum:
2867 {
cristy8cd03c32012-07-07 18:57:59 +00002868 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002869 break;
2870 }
2871 default:
2872 break;
2873 }
2874 p++;
2875 }
2876 q+=GetPixelChannels(image);
2877 }
2878 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2879 break;
2880 }
2881}
2882
cristycafe0412012-01-10 13:29:58 +00002883static void ImportLongPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002884 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2885 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002886{
2887 register const unsigned int
2888 *restrict p;
2889
2890 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002891 *restrict q;
cristye5370942012-01-06 03:49:31 +00002892
2893 register ssize_t
2894 x;
2895
cristy14d71292012-05-20 16:48:13 +00002896 size_t
2897 length;
2898
cristye5370942012-01-06 03:49:31 +00002899 ssize_t
2900 y;
2901
2902 p=(const unsigned int *) pixels;
2903 if (LocaleCompare(map,"BGR") == 0)
2904 {
cristycafe0412012-01-10 13:29:58 +00002905 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002906 {
cristycafe0412012-01-10 13:29:58 +00002907 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002908 if (q == (Quantum *) NULL)
2909 break;
cristycafe0412012-01-10 13:29:58 +00002910 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002911 {
2912 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2913 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2914 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2915 q+=GetPixelChannels(image);
2916 }
2917 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2918 break;
2919 }
2920 return;
2921 }
2922 if (LocaleCompare(map,"BGRA") == 0)
2923 {
cristycafe0412012-01-10 13:29:58 +00002924 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002925 {
cristycafe0412012-01-10 13:29:58 +00002926 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002927 if (q == (Quantum *) NULL)
2928 break;
cristycafe0412012-01-10 13:29:58 +00002929 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002930 {
2931 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2932 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2933 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2934 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
2935 q+=GetPixelChannels(image);
2936 }
2937 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2938 break;
2939 }
2940 return;
2941 }
2942 if (LocaleCompare(map,"BGRP") == 0)
2943 {
cristycafe0412012-01-10 13:29:58 +00002944 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002945 {
cristycafe0412012-01-10 13:29:58 +00002946 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002947 if (q == (Quantum *) NULL)
2948 break;
cristycafe0412012-01-10 13:29:58 +00002949 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002950 {
2951 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2952 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2953 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2954 p++;
2955 q+=GetPixelChannels(image);
2956 }
2957 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2958 break;
2959 }
2960 return;
2961 }
2962 if (LocaleCompare(map,"I") == 0)
2963 {
cristycafe0412012-01-10 13:29:58 +00002964 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002965 {
cristycafe0412012-01-10 13:29:58 +00002966 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002967 if (q == (Quantum *) NULL)
2968 break;
cristycafe0412012-01-10 13:29:58 +00002969 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002970 {
2971 SetPixelGray(image,ScaleLongToQuantum(*p++),q);
2972 q+=GetPixelChannels(image);
2973 }
2974 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2975 break;
2976 }
2977 return;
2978 }
2979 if (LocaleCompare(map,"RGB") == 0)
2980 {
cristycafe0412012-01-10 13:29:58 +00002981 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002982 {
cristycafe0412012-01-10 13:29:58 +00002983 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002984 if (q == (Quantum *) NULL)
2985 break;
cristycafe0412012-01-10 13:29:58 +00002986 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002987 {
2988 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2989 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2990 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2991 q+=GetPixelChannels(image);
2992 }
2993 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2994 break;
2995 }
2996 return;
2997 }
2998 if (LocaleCompare(map,"RGBA") == 0)
2999 {
cristycafe0412012-01-10 13:29:58 +00003000 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003001 {
cristycafe0412012-01-10 13:29:58 +00003002 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003003 if (q == (Quantum *) NULL)
3004 break;
cristycafe0412012-01-10 13:29:58 +00003005 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003006 {
3007 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3008 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3009 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3010 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
3011 q+=GetPixelChannels(image);
3012 }
3013 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3014 break;
3015 }
3016 return;
3017 }
3018 if (LocaleCompare(map,"RGBP") == 0)
3019 {
cristycafe0412012-01-10 13:29:58 +00003020 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003021 {
cristycafe0412012-01-10 13:29:58 +00003022 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003023 if (q == (Quantum *) NULL)
3024 break;
cristycafe0412012-01-10 13:29:58 +00003025 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003026 {
3027 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3028 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3029 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3030 p++;
3031 q+=GetPixelChannels(image);
3032 }
3033 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3034 break;
3035 }
3036 return;
3037 }
cristy14d71292012-05-20 16:48:13 +00003038 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003039 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003040 {
cristycafe0412012-01-10 13:29:58 +00003041 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003042 if (q == (Quantum *) NULL)
3043 break;
cristycafe0412012-01-10 13:29:58 +00003044 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003045 {
3046 register ssize_t
3047 i;
3048
cristy14d71292012-05-20 16:48:13 +00003049 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003050 {
3051 switch (quantum_map[i])
3052 {
3053 case RedQuantum:
3054 case CyanQuantum:
3055 {
3056 SetPixelRed(image,ScaleLongToQuantum(*p),q);
3057 break;
3058 }
3059 case GreenQuantum:
3060 case MagentaQuantum:
3061 {
3062 SetPixelGreen(image,ScaleLongToQuantum(*p),q);
3063 break;
3064 }
3065 case BlueQuantum:
3066 case YellowQuantum:
3067 {
3068 SetPixelBlue(image,ScaleLongToQuantum(*p),q);
3069 break;
3070 }
3071 case AlphaQuantum:
3072 {
3073 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3074 break;
3075 }
3076 case OpacityQuantum:
3077 {
3078 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3079 break;
3080 }
3081 case BlackQuantum:
3082 {
3083 SetPixelBlack(image,ScaleLongToQuantum(*p),q);
3084 break;
3085 }
3086 case IndexQuantum:
3087 {
3088 SetPixelGray(image,ScaleLongToQuantum(*p),q);
3089 break;
3090 }
3091 default:
3092 break;
3093 }
3094 p++;
3095 }
3096 q+=GetPixelChannels(image);
3097 }
3098 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3099 break;
3100 }
3101}
3102
cristycafe0412012-01-10 13:29:58 +00003103static void ImportLongLongPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003104 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3105 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003106{
cristyb13e12a2012-01-06 21:48:27 +00003107 register const MagickSizeType
cristye5370942012-01-06 03:49:31 +00003108 *restrict p;
3109
3110 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003111 *restrict q;
cristye5370942012-01-06 03:49:31 +00003112
3113 register ssize_t
3114 x;
3115
cristy14d71292012-05-20 16:48:13 +00003116 size_t
3117 length;
3118
cristye5370942012-01-06 03:49:31 +00003119 ssize_t
3120 y;
3121
cristyb13e12a2012-01-06 21:48:27 +00003122 p=(const MagickSizeType *) pixels;
cristye5370942012-01-06 03:49:31 +00003123 if (LocaleCompare(map,"BGR") == 0)
3124 {
cristycafe0412012-01-10 13:29:58 +00003125 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003126 {
cristycafe0412012-01-10 13:29:58 +00003127 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003128 if (q == (Quantum *) NULL)
3129 break;
cristycafe0412012-01-10 13:29:58 +00003130 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003131 {
cristyb13e12a2012-01-06 21:48:27 +00003132 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3133 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3134 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003135 q+=GetPixelChannels(image);
3136 }
3137 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3138 break;
3139 }
3140 return;
3141 }
3142 if (LocaleCompare(map,"BGRA") == 0)
3143 {
cristycafe0412012-01-10 13:29:58 +00003144 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003145 {
cristycafe0412012-01-10 13:29:58 +00003146 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003147 if (q == (Quantum *) NULL)
3148 break;
cristycafe0412012-01-10 13:29:58 +00003149 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003150 {
cristyb13e12a2012-01-06 21:48:27 +00003151 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3152 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3153 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3154 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003155 q+=GetPixelChannels(image);
3156 }
3157 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3158 break;
3159 }
3160 return;
3161 }
3162 if (LocaleCompare(map,"BGRP") == 0)
3163 {
cristycafe0412012-01-10 13:29:58 +00003164 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003165 {
cristycafe0412012-01-10 13:29:58 +00003166 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003167 if (q == (Quantum *) NULL)
3168 break;
cristycafe0412012-01-10 13:29:58 +00003169 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003170 {
cristyb13e12a2012-01-06 21:48:27 +00003171 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3172 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3173 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003174 p++;
3175 q+=GetPixelChannels(image);
3176 }
3177 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3178 break;
3179 }
3180 return;
3181 }
3182 if (LocaleCompare(map,"I") == 0)
3183 {
cristycafe0412012-01-10 13:29:58 +00003184 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003185 {
cristycafe0412012-01-10 13:29:58 +00003186 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003187 if (q == (Quantum *) NULL)
3188 break;
cristycafe0412012-01-10 13:29:58 +00003189 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003190 {
cristyb13e12a2012-01-06 21:48:27 +00003191 SetPixelGray(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003192 q+=GetPixelChannels(image);
3193 }
3194 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3195 break;
3196 }
3197 return;
3198 }
3199 if (LocaleCompare(map,"RGB") == 0)
3200 {
cristycafe0412012-01-10 13:29:58 +00003201 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003202 {
cristycafe0412012-01-10 13:29:58 +00003203 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003204 if (q == (Quantum *) NULL)
3205 break;
cristycafe0412012-01-10 13:29:58 +00003206 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003207 {
cristyb13e12a2012-01-06 21:48:27 +00003208 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3209 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3210 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003211 q+=GetPixelChannels(image);
3212 }
3213 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3214 break;
3215 }
3216 return;
3217 }
3218 if (LocaleCompare(map,"RGBA") == 0)
3219 {
cristycafe0412012-01-10 13:29:58 +00003220 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003221 {
cristycafe0412012-01-10 13:29:58 +00003222 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003223 if (q == (Quantum *) NULL)
3224 break;
cristycafe0412012-01-10 13:29:58 +00003225 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003226 {
cristyb13e12a2012-01-06 21:48:27 +00003227 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3228 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3229 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3230 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003231 q+=GetPixelChannels(image);
3232 }
3233 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3234 break;
3235 }
3236 return;
3237 }
3238 if (LocaleCompare(map,"RGBP") == 0)
3239 {
cristycafe0412012-01-10 13:29:58 +00003240 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003241 {
cristycafe0412012-01-10 13:29:58 +00003242 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003243 if (q == (Quantum *) NULL)
3244 break;
cristycafe0412012-01-10 13:29:58 +00003245 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003246 {
cristyb13e12a2012-01-06 21:48:27 +00003247 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3248 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3249 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003250 p++;
3251 q+=GetPixelChannels(image);
3252 }
3253 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3254 break;
3255 }
3256 return;
3257 }
cristy14d71292012-05-20 16:48:13 +00003258 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003259 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003260 {
cristycafe0412012-01-10 13:29:58 +00003261 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003262 if (q == (Quantum *) NULL)
3263 break;
cristycafe0412012-01-10 13:29:58 +00003264 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003265 {
3266 register ssize_t
3267 i;
3268
cristy14d71292012-05-20 16:48:13 +00003269 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003270 {
3271 switch (quantum_map[i])
3272 {
3273 case RedQuantum:
3274 case CyanQuantum:
3275 {
cristyb13e12a2012-01-06 21:48:27 +00003276 SetPixelRed(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003277 break;
3278 }
3279 case GreenQuantum:
3280 case MagentaQuantum:
3281 {
cristyb13e12a2012-01-06 21:48:27 +00003282 SetPixelGreen(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003283 break;
3284 }
3285 case BlueQuantum:
3286 case YellowQuantum:
3287 {
cristyb13e12a2012-01-06 21:48:27 +00003288 SetPixelBlue(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003289 break;
3290 }
3291 case AlphaQuantum:
3292 {
cristyb13e12a2012-01-06 21:48:27 +00003293 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003294 break;
3295 }
3296 case OpacityQuantum:
3297 {
cristyb13e12a2012-01-06 21:48:27 +00003298 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003299 break;
3300 }
3301 case BlackQuantum:
3302 {
cristyb13e12a2012-01-06 21:48:27 +00003303 SetPixelBlack(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003304 break;
3305 }
3306 case IndexQuantum:
3307 {
cristyb13e12a2012-01-06 21:48:27 +00003308 SetPixelGray(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003309 break;
3310 }
3311 default:
3312 break;
3313 }
3314 p++;
3315 }
3316 q+=GetPixelChannels(image);
3317 }
3318 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3319 break;
3320 }
3321}
3322
cristycafe0412012-01-10 13:29:58 +00003323static void ImportQuantumPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003324 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3325 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003326{
3327 register const Quantum
3328 *restrict p;
3329
3330 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003331 *restrict q;
cristye5370942012-01-06 03:49:31 +00003332
3333 register ssize_t
3334 x;
3335
cristy14d71292012-05-20 16:48:13 +00003336 size_t
3337 length;
3338
cristye5370942012-01-06 03:49:31 +00003339 ssize_t
3340 y;
3341
3342 p=(const Quantum *) pixels;
3343 if (LocaleCompare(map,"BGR") == 0)
3344 {
cristycafe0412012-01-10 13:29:58 +00003345 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003346 {
cristycafe0412012-01-10 13:29:58 +00003347 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003348 if (q == (Quantum *) NULL)
3349 break;
cristycafe0412012-01-10 13:29:58 +00003350 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003351 {
3352 SetPixelBlue(image,*p++,q);
3353 SetPixelGreen(image,*p++,q);
3354 SetPixelRed(image,*p++,q);
3355 q+=GetPixelChannels(image);
3356 }
3357 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3358 break;
3359 }
3360 return;
3361 }
3362 if (LocaleCompare(map,"BGRA") == 0)
3363 {
cristycafe0412012-01-10 13:29:58 +00003364 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003365 {
cristycafe0412012-01-10 13:29:58 +00003366 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003367 if (q == (Quantum *) NULL)
3368 break;
cristycafe0412012-01-10 13:29:58 +00003369 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003370 {
3371 SetPixelBlue(image,*p++,q);
3372 SetPixelGreen(image,*p++,q);
3373 SetPixelRed(image,*p++,q);
3374 SetPixelAlpha(image,*p++,q);
3375 q+=GetPixelChannels(image);
3376 }
3377 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3378 break;
3379 }
3380 return;
3381 }
3382 if (LocaleCompare(map,"BGRP") == 0)
3383 {
cristycafe0412012-01-10 13:29:58 +00003384 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003385 {
cristycafe0412012-01-10 13:29:58 +00003386 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003387 if (q == (Quantum *) NULL)
3388 break;
cristycafe0412012-01-10 13:29:58 +00003389 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003390 {
3391 SetPixelBlue(image,*p++,q);
3392 SetPixelGreen(image,*p++,q);
3393 SetPixelRed(image,*p++,q);
3394 p++;
3395 q+=GetPixelChannels(image);
3396 }
3397 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3398 break;
3399 }
3400 return;
3401 }
3402 if (LocaleCompare(map,"I") == 0)
3403 {
cristycafe0412012-01-10 13:29:58 +00003404 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003405 {
cristycafe0412012-01-10 13:29:58 +00003406 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003407 if (q == (Quantum *) NULL)
3408 break;
cristycafe0412012-01-10 13:29:58 +00003409 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003410 {
3411 SetPixelGray(image,*p++,q);
3412 q+=GetPixelChannels(image);
3413 }
3414 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3415 break;
3416 }
3417 return;
3418 }
3419 if (LocaleCompare(map,"RGB") == 0)
3420 {
cristycafe0412012-01-10 13:29:58 +00003421 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003422 {
cristycafe0412012-01-10 13:29:58 +00003423 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003424 if (q == (Quantum *) NULL)
3425 break;
cristycafe0412012-01-10 13:29:58 +00003426 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003427 {
3428 SetPixelRed(image,*p++,q);
3429 SetPixelGreen(image,*p++,q);
3430 SetPixelBlue(image,*p++,q);
3431 q+=GetPixelChannels(image);
3432 }
3433 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3434 break;
3435 }
3436 return;
3437 }
3438 if (LocaleCompare(map,"RGBA") == 0)
3439 {
cristycafe0412012-01-10 13:29:58 +00003440 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003441 {
cristycafe0412012-01-10 13:29:58 +00003442 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003443 if (q == (Quantum *) NULL)
3444 break;
cristycafe0412012-01-10 13:29:58 +00003445 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003446 {
3447 SetPixelRed(image,*p++,q);
3448 SetPixelGreen(image,*p++,q);
3449 SetPixelBlue(image,*p++,q);
3450 SetPixelAlpha(image,*p++,q);
3451 q+=GetPixelChannels(image);
3452 }
3453 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3454 break;
3455 }
3456 return;
3457 }
3458 if (LocaleCompare(map,"RGBP") == 0)
3459 {
cristycafe0412012-01-10 13:29:58 +00003460 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003461 {
cristycafe0412012-01-10 13:29:58 +00003462 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003463 if (q == (Quantum *) NULL)
3464 break;
cristycafe0412012-01-10 13:29:58 +00003465 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003466 {
3467 SetPixelRed(image,*p++,q);
3468 SetPixelGreen(image,*p++,q);
3469 SetPixelBlue(image,*p++,q);
3470 p++;
3471 q+=GetPixelChannels(image);
3472 }
3473 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3474 break;
3475 }
3476 return;
3477 }
cristy14d71292012-05-20 16:48:13 +00003478 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003479 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003480 {
cristycafe0412012-01-10 13:29:58 +00003481 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003482 if (q == (Quantum *) NULL)
3483 break;
cristycafe0412012-01-10 13:29:58 +00003484 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003485 {
3486 register ssize_t
3487 i;
3488
cristy14d71292012-05-20 16:48:13 +00003489 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003490 {
3491 switch (quantum_map[i])
3492 {
3493 case RedQuantum:
3494 case CyanQuantum:
3495 {
3496 SetPixelRed(image,*p,q);
3497 break;
3498 }
3499 case GreenQuantum:
3500 case MagentaQuantum:
3501 {
3502 SetPixelGreen(image,*p,q);
3503 break;
3504 }
3505 case BlueQuantum:
3506 case YellowQuantum:
3507 {
3508 SetPixelBlue(image,*p,q);
3509 break;
3510 }
3511 case AlphaQuantum:
3512 {
3513 SetPixelAlpha(image,*p,q);
3514 break;
3515 }
3516 case OpacityQuantum:
3517 {
3518 SetPixelAlpha(image,*p,q);
3519 break;
3520 }
3521 case BlackQuantum:
3522 {
3523 SetPixelBlack(image,*p,q);
3524 break;
3525 }
3526 case IndexQuantum:
3527 {
3528 SetPixelGray(image,*p,q);
3529 break;
3530 }
3531 default:
3532 break;
3533 }
3534 p++;
3535 }
3536 q+=GetPixelChannels(image);
3537 }
3538 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3539 break;
3540 }
3541}
3542
cristycafe0412012-01-10 13:29:58 +00003543static void ImportShortPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003544 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3545 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003546{
3547 register const unsigned short
3548 *restrict p;
3549
3550 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003551 *restrict q;
cristye5370942012-01-06 03:49:31 +00003552
3553 register ssize_t
3554 x;
3555
cristy14d71292012-05-20 16:48:13 +00003556 size_t
3557 length;
3558
cristye5370942012-01-06 03:49:31 +00003559 ssize_t
3560 y;
3561
3562 p=(const unsigned short *) pixels;
3563 if (LocaleCompare(map,"BGR") == 0)
3564 {
cristycafe0412012-01-10 13:29:58 +00003565 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003566 {
cristycafe0412012-01-10 13:29:58 +00003567 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003568 if (q == (Quantum *) NULL)
3569 break;
cristycafe0412012-01-10 13:29:58 +00003570 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003571 {
3572 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3573 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3574 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3575 q+=GetPixelChannels(image);
3576 }
3577 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3578 break;
3579 }
3580 return;
3581 }
3582 if (LocaleCompare(map,"BGRA") == 0)
3583 {
cristycafe0412012-01-10 13:29:58 +00003584 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003585 {
cristycafe0412012-01-10 13:29:58 +00003586 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003587 if (q == (Quantum *) NULL)
3588 break;
cristycafe0412012-01-10 13:29:58 +00003589 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003590 {
3591 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3592 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3593 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3594 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3595 q+=GetPixelChannels(image);
3596 }
3597 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3598 break;
3599 }
3600 return;
3601 }
3602 if (LocaleCompare(map,"BGRP") == 0)
3603 {
cristycafe0412012-01-10 13:29:58 +00003604 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003605 {
cristycafe0412012-01-10 13:29:58 +00003606 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003607 if (q == (Quantum *) NULL)
3608 break;
cristycafe0412012-01-10 13:29:58 +00003609 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003610 {
3611 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3612 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3613 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3614 p++;
3615 q+=GetPixelChannels(image);
3616 }
3617 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3618 break;
3619 }
3620 return;
3621 }
3622 if (LocaleCompare(map,"I") == 0)
3623 {
cristycafe0412012-01-10 13:29:58 +00003624 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003625 {
cristycafe0412012-01-10 13:29:58 +00003626 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003627 if (q == (Quantum *) NULL)
3628 break;
cristycafe0412012-01-10 13:29:58 +00003629 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003630 {
3631 SetPixelGray(image,ScaleShortToQuantum(*p++),q);
3632 q+=GetPixelChannels(image);
3633 }
3634 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3635 break;
3636 }
3637 return;
3638 }
3639 if (LocaleCompare(map,"RGB") == 0)
3640 {
cristycafe0412012-01-10 13:29:58 +00003641 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003642 {
cristycafe0412012-01-10 13:29:58 +00003643 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003644 if (q == (Quantum *) NULL)
3645 break;
cristycafe0412012-01-10 13:29:58 +00003646 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003647 {
3648 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3649 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3650 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3651 q+=GetPixelChannels(image);
3652 }
3653 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3654 break;
3655 }
3656 return;
3657 }
3658 if (LocaleCompare(map,"RGBA") == 0)
3659 {
cristycafe0412012-01-10 13:29:58 +00003660 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003661 {
cristycafe0412012-01-10 13:29:58 +00003662 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003663 if (q == (Quantum *) NULL)
3664 break;
cristycafe0412012-01-10 13:29:58 +00003665 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003666 {
3667 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3668 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3669 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3670 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3671 q+=GetPixelChannels(image);
3672 }
3673 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3674 break;
3675 }
3676 return;
3677 }
3678 if (LocaleCompare(map,"RGBP") == 0)
3679 {
cristycafe0412012-01-10 13:29:58 +00003680 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003681 {
cristycafe0412012-01-10 13:29:58 +00003682 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003683 if (q == (Quantum *) NULL)
3684 break;
cristycafe0412012-01-10 13:29:58 +00003685 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003686 {
3687 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3688 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3689 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3690 p++;
3691 q+=GetPixelChannels(image);
3692 }
3693 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3694 break;
3695 }
3696 return;
3697 }
cristy14d71292012-05-20 16:48:13 +00003698 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003699 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003700 {
cristycafe0412012-01-10 13:29:58 +00003701 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003702 if (q == (Quantum *) NULL)
3703 break;
cristycafe0412012-01-10 13:29:58 +00003704 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003705 {
3706 register ssize_t
3707 i;
3708
cristy14d71292012-05-20 16:48:13 +00003709 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003710 {
3711 switch (quantum_map[i])
3712 {
3713 case RedQuantum:
3714 case CyanQuantum:
3715 {
3716 SetPixelRed(image,ScaleShortToQuantum(*p),q);
3717 break;
3718 }
3719 case GreenQuantum:
3720 case MagentaQuantum:
3721 {
3722 SetPixelGreen(image,ScaleShortToQuantum(*p),q);
3723 break;
3724 }
3725 case BlueQuantum:
3726 case YellowQuantum:
3727 {
3728 SetPixelBlue(image,ScaleShortToQuantum(*p),q);
3729 break;
3730 }
3731 case AlphaQuantum:
3732 {
3733 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
3734 break;
3735 }
3736 case OpacityQuantum:
3737 {
3738 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
3739 break;
3740 }
3741 case BlackQuantum:
3742 {
3743 SetPixelBlack(image,ScaleShortToQuantum(*p),q);
3744 break;
3745 }
3746 case IndexQuantum:
3747 {
3748 SetPixelGray(image,ScaleShortToQuantum(*p),q);
3749 break;
3750 }
3751 default:
3752 break;
3753 }
3754 p++;
3755 }
3756 q+=GetPixelChannels(image);
3757 }
3758 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3759 break;
3760 }
3761}
3762
cristycafe0412012-01-10 13:29:58 +00003763MagickExport MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
3764 const ssize_t y,const size_t width,const size_t height,const char *map,
3765 const StorageType type,const void *pixels,ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00003766{
cristy4c08aed2011-07-01 19:47:50 +00003767 QuantumType
3768 *quantum_map;
3769
cristycafe0412012-01-10 13:29:58 +00003770 RectangleInfo
3771 roi;
3772
cristy4c08aed2011-07-01 19:47:50 +00003773 register ssize_t
cristye5370942012-01-06 03:49:31 +00003774 i;
cristy4c08aed2011-07-01 19:47:50 +00003775
cristy14d71292012-05-20 16:48:13 +00003776 size_t
3777 length;
3778
cristy4c08aed2011-07-01 19:47:50 +00003779 /*
3780 Allocate image structure.
3781 */
3782 assert(image != (Image *) NULL);
3783 assert(image->signature == MagickSignature);
3784 if (image->debug != MagickFalse)
3785 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristy14d71292012-05-20 16:48:13 +00003786 length=strlen(map);
3787 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
cristy4c08aed2011-07-01 19:47:50 +00003788 if (quantum_map == (QuantumType *) NULL)
3789 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
3790 image->filename);
cristy14d71292012-05-20 16:48:13 +00003791 for (i=0; i < (ssize_t) length; i++)
cristy4c08aed2011-07-01 19:47:50 +00003792 {
3793 switch (map[i])
3794 {
3795 case 'a':
3796 case 'A':
3797 {
3798 quantum_map[i]=AlphaQuantum;
cristy8a46d822012-08-28 23:32:39 +00003799 image->alpha_trait=BlendPixelTrait;
cristy4c08aed2011-07-01 19:47:50 +00003800 break;
3801 }
3802 case 'B':
3803 case 'b':
3804 {
3805 quantum_map[i]=BlueQuantum;
3806 break;
3807 }
3808 case 'C':
3809 case 'c':
3810 {
3811 quantum_map[i]=CyanQuantum;
cristy63240882011-08-05 19:05:27 +00003812 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003813 break;
3814 }
3815 case 'g':
3816 case 'G':
3817 {
3818 quantum_map[i]=GreenQuantum;
3819 break;
3820 }
3821 case 'K':
3822 case 'k':
3823 {
3824 quantum_map[i]=BlackQuantum;
cristy63240882011-08-05 19:05:27 +00003825 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003826 break;
3827 }
3828 case 'I':
3829 case 'i':
3830 {
3831 quantum_map[i]=IndexQuantum;
cristyb7b3da62012-07-05 15:43:37 +00003832 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003833 break;
3834 }
3835 case 'm':
3836 case 'M':
3837 {
3838 quantum_map[i]=MagentaQuantum;
cristy63240882011-08-05 19:05:27 +00003839 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003840 break;
3841 }
3842 case 'O':
3843 case 'o':
3844 {
3845 quantum_map[i]=OpacityQuantum;
cristy8a46d822012-08-28 23:32:39 +00003846 image->alpha_trait=BlendPixelTrait;
cristy4c08aed2011-07-01 19:47:50 +00003847 break;
3848 }
3849 case 'P':
3850 case 'p':
3851 {
3852 quantum_map[i]=UndefinedQuantum;
3853 break;
3854 }
3855 case 'R':
3856 case 'r':
3857 {
3858 quantum_map[i]=RedQuantum;
3859 break;
3860 }
3861 case 'Y':
3862 case 'y':
3863 {
3864 quantum_map[i]=YellowQuantum;
cristy63240882011-08-05 19:05:27 +00003865 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003866 break;
3867 }
3868 default:
3869 {
3870 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
cristy63240882011-08-05 19:05:27 +00003871 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
cristyefe601c2013-01-05 17:51:12 +00003872 "UnrecognizedPixelMap","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00003873 return(MagickFalse);
3874 }
3875 }
3876 }
cristy63240882011-08-05 19:05:27 +00003877 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
cristy4c08aed2011-07-01 19:47:50 +00003878 return(MagickFalse);
3879 /*
cristye5370942012-01-06 03:49:31 +00003880 Transfer the pixels from the pixel data to the image.
cristy4c08aed2011-07-01 19:47:50 +00003881 */
cristycafe0412012-01-10 13:29:58 +00003882 roi.width=width;
3883 roi.height=height;
3884 roi.x=x;
3885 roi.y=y;
cristy4c08aed2011-07-01 19:47:50 +00003886 switch (type)
3887 {
3888 case CharPixel:
3889 {
cristycafe0412012-01-10 13:29:58 +00003890 ImportCharPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003891 break;
3892 }
3893 case DoublePixel:
3894 {
cristycafe0412012-01-10 13:29:58 +00003895 ImportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003896 break;
3897 }
3898 case FloatPixel:
3899 {
cristycafe0412012-01-10 13:29:58 +00003900 ImportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003901 break;
3902 }
cristy4c08aed2011-07-01 19:47:50 +00003903 case LongPixel:
3904 {
cristycafe0412012-01-10 13:29:58 +00003905 ImportLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003906 break;
3907 }
cristy6c9e1682012-01-07 21:37:44 +00003908 case LongLongPixel:
3909 {
cristycafe0412012-01-10 13:29:58 +00003910 ImportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy6c9e1682012-01-07 21:37:44 +00003911 break;
3912 }
cristy4c08aed2011-07-01 19:47:50 +00003913 case QuantumPixel:
3914 {
cristycafe0412012-01-10 13:29:58 +00003915 ImportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003916 break;
3917 }
3918 case ShortPixel:
3919 {
cristycafe0412012-01-10 13:29:58 +00003920 ImportShortPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003921 break;
3922 }
3923 default:
3924 {
3925 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
cristyc82a27b2011-10-21 01:07:16 +00003926 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
cristyefe601c2013-01-05 17:51:12 +00003927 "UnrecognizedPixelMap","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00003928 break;
3929 }
3930 }
3931 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
3932 return(MagickTrue);
3933}
3934
3935/*
3936%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3937% %
3938% %
3939% %
cristybd5a96c2011-08-21 00:04:26 +00003940+ 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 %
3941% %
3942% %
3943% %
3944%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3945%
3946% InitializePixelChannelMap() defines the standard pixel component map.
3947%
3948% The format of the InitializePixelChannelMap() method is:
3949%
3950% void InitializePixelChannelMap(Image *image)
3951%
3952% A description of each parameter follows:
3953%
3954% o image: the image.
3955%
3956*/
cristye2a912b2011-12-05 20:02:07 +00003957MagickExport void InitializePixelChannelMap(Image *image)
cristy77c30f52011-10-24 18:56:57 +00003958{
cristye2a912b2011-12-05 20:02:07 +00003959 PixelTrait
3960 trait;
3961
cristy77c30f52011-10-24 18:56:57 +00003962 register ssize_t
3963 i;
3964
cristyd26338f2011-12-14 02:39:30 +00003965 ssize_t
cristy77c30f52011-10-24 18:56:57 +00003966 n;
3967
3968 assert(image != (Image *) NULL);
3969 assert(image->signature == MagickSignature);
cristye2a912b2011-12-05 20:02:07 +00003970 (void) ResetMagickMemory(image->channel_map,0,MaxPixelChannels*
3971 sizeof(*image->channel_map));
3972 trait=UpdatePixelTrait;
cristy8a46d822012-08-28 23:32:39 +00003973 if (image->alpha_trait == BlendPixelTrait)
cristy61f18ad2011-12-08 21:12:37 +00003974 trait=(PixelTrait) (trait | BlendPixelTrait);
cristy77c30f52011-10-24 18:56:57 +00003975 n=0;
cristyc06c5802011-12-31 23:36:16 +00003976 if (image->colorspace == GRAYColorspace)
cristy77c30f52011-10-24 18:56:57 +00003977 {
cristycf1296e2012-08-26 23:40:49 +00003978 SetPixelChannelAttributes(image,BluePixelChannel,trait,n);
3979 SetPixelChannelAttributes(image,GreenPixelChannel,trait,n);
3980 SetPixelChannelAttributes(image,RedPixelChannel,trait,n++);
cristy3c316282011-12-15 15:43:24 +00003981 }
3982 else
3983 {
cristycf1296e2012-08-26 23:40:49 +00003984 SetPixelChannelAttributes(image,RedPixelChannel,trait,n++);
3985 SetPixelChannelAttributes(image,GreenPixelChannel,trait,n++);
3986 SetPixelChannelAttributes(image,BluePixelChannel,trait,n++);
cristy77c30f52011-10-24 18:56:57 +00003987 }
3988 if (image->colorspace == CMYKColorspace)
cristycf1296e2012-08-26 23:40:49 +00003989 SetPixelChannelAttributes(image,BlackPixelChannel,trait,n++);
cristy8a46d822012-08-28 23:32:39 +00003990 if (image->alpha_trait != UndefinedPixelTrait)
cristycf1296e2012-08-26 23:40:49 +00003991 SetPixelChannelAttributes(image,AlphaPixelChannel,CopyPixelTrait,n++);
cristye2a912b2011-12-05 20:02:07 +00003992 if (image->storage_class == PseudoClass)
cristycf1296e2012-08-26 23:40:49 +00003993 SetPixelChannelAttributes(image,IndexPixelChannel,CopyPixelTrait,n++);
cristy183a5c72012-01-30 01:40:35 +00003994 if (image->mask != MagickFalse)
cristycf1296e2012-08-26 23:40:49 +00003995 SetPixelChannelAttributes(image,MaskPixelChannel,CopyPixelTrait,n++);
cristye2a912b2011-12-05 20:02:07 +00003996 assert((n+image->number_meta_channels) < MaxPixelChannels);
3997 for (i=0; i < (ssize_t) image->number_meta_channels; i++)
cristycf1296e2012-08-26 23:40:49 +00003998 SetPixelChannelAttributes(image,(PixelChannel) (MetaPixelChannel+i),
3999 CopyPixelTrait,n++);
cristyd26338f2011-12-14 02:39:30 +00004000 image->number_channels=(size_t) n;
cristy77c30f52011-10-24 18:56:57 +00004001 if (image->debug != MagickFalse)
4002 LogPixelChannels(image);
cristycf1296e2012-08-26 23:40:49 +00004003 (void) SetImageChannelMask(image,image->channel_mask);
cristy77c30f52011-10-24 18:56:57 +00004004}
cristybd5a96c2011-08-21 00:04:26 +00004005
4006/*
4007%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4008% %
4009% %
4010% %
cristya085a432011-07-30 01:39:32 +00004011% I n t e r p o l a t e P i x e l C h a n n e l %
4012% %
4013% %
4014% %
4015%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4016%
cristy884f6002011-07-31 00:51:45 +00004017% InterpolatePixelChannel() applies a pixel interpolation method between a
4018% floating point coordinate and the pixels surrounding that coordinate. No
4019% pixel area resampling, or scaling of the result is performed.
cristya085a432011-07-30 01:39:32 +00004020%
anthonycf4e33d2012-06-08 07:33:23 +00004021% Interpolation is restricted to just the specified channel.
4022%
cristya085a432011-07-30 01:39:32 +00004023% The format of the InterpolatePixelChannel method is:
4024%
4025% MagickBooleanType InterpolatePixelChannel(const Image *image,
cristy444eda62011-08-10 02:07:46 +00004026% const CacheView *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00004027% const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00004028% double *pixel,ExceptionInfo *exception)
4029%
4030% A description of each parameter follows:
4031%
4032% o image: the image.
4033%
4034% o image_view: the image view.
4035%
4036% o channel: the pixel channel to interpolate.
4037%
4038% o method: the pixel color interpolation method.
4039%
4040% o x,y: A double representing the current (x,y) position of the pixel.
4041%
4042% o pixel: return the interpolated pixel here.
4043%
4044% o exception: return any errors or warnings in this structure.
4045%
4046*/
cristy94ea1632011-07-30 20:40:25 +00004047
cristya19f1d72012-08-07 18:24:38 +00004048static inline double MagickMax(const double x,const double y)
cristy884f6002011-07-31 00:51:45 +00004049{
4050 if (x > y)
4051 return(x);
4052 return(y);
4053}
4054
cristyb0a657e2012-08-29 00:45:37 +00004055static inline void CatromWeights(const double x,double (*weights)[4])
cristy884f6002011-07-31 00:51:45 +00004056{
cristya19f1d72012-08-07 18:24:38 +00004057 double
cristy884f6002011-07-31 00:51:45 +00004058 alpha,
nicolasd32d5e52012-06-12 15:34:10 +00004059 beta,
cristy884f6002011-07-31 00:51:45 +00004060 gamma;
4061
cristy5a5e4d92012-08-29 00:06:25 +00004062 /*
4063 Nicolas Robidoux' 10 flops (4* + 5- + 1+) refactoring of the computation
4064 of the standard four 1D Catmull-Rom weights. The sampling location is
4065 assumed between the second and third input pixel locations, and x is the
4066 position relative to the second input pixel location. Formulas originally
4067 derived for the VIPS (Virtual Image Processing System) library.
4068 */
cristya19f1d72012-08-07 18:24:38 +00004069 alpha=(double) 1.0-x;
4070 beta=(double) (-0.5)*x*alpha;
nicolasd32d5e52012-06-12 15:34:10 +00004071 (*weights)[0]=alpha*beta;
4072 (*weights)[3]=x*beta;
4073 /*
cristy5a5e4d92012-08-29 00:06:25 +00004074 The following computation of the inner weights from the outer ones work
4075 for all Keys cubics.
nicolasd32d5e52012-06-12 15:34:10 +00004076 */
4077 gamma=(*weights)[3]-(*weights)[0];
4078 (*weights)[1]=alpha-(*weights)[0]+gamma;
4079 (*weights)[2]=x-(*weights)[3]-gamma;
4080}
4081
cristyb0a657e2012-08-29 00:45:37 +00004082static inline void SplineWeights(const double x,double (*weights)[4])
nicolasd32d5e52012-06-12 15:34:10 +00004083{
cristy5a5e4d92012-08-29 00:06:25 +00004084 double
4085 alpha,
4086 beta;
4087
nicolasd32d5e52012-06-12 15:34:10 +00004088 /*
4089 Nicolas Robidoux' 12 flops (6* + 5- + 1+) refactoring of the
4090 computation of the standard four 1D cubic B-spline smoothing
4091 weights. The sampling location is assumed between the second and
4092 third input pixel locations, and x is the position relative to the
4093 second input pixel location.
4094 */
cristya19f1d72012-08-07 18:24:38 +00004095 alpha=(double) 1.0-x;
4096 (*weights)[3]=(double) (1.0/6.0)*x*x*x;
4097 (*weights)[0]=(double) (1.0/6.0)*alpha*alpha*alpha;
nicolasd32d5e52012-06-12 15:34:10 +00004098 beta=(*weights)[3]-(*weights)[0];
4099 (*weights)[1]=alpha-(*weights)[0]+beta;
4100 (*weights)[2]=x-(*weights)[3]-beta;
cristy884f6002011-07-31 00:51:45 +00004101}
4102
cristy94ea1632011-07-30 20:40:25 +00004103static inline double MeshInterpolate(const PointInfo *delta,const double p,
4104 const double x,const double y)
4105{
4106 return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p);
4107}
4108
anthonycf4e33d2012-06-08 07:33:23 +00004109/*
cristya19f1d72012-08-07 18:24:38 +00004110static inline ssize_t NearestNeighbor(const double x)
cristy884f6002011-07-31 00:51:45 +00004111{
4112 if (x >= 0.0)
4113 return((ssize_t) (x+0.5));
4114 return((ssize_t) (x-0.5));
4115}
anthonycf4e33d2012-06-08 07:33:23 +00004116*/
cristy884f6002011-07-31 00:51:45 +00004117
cristya085a432011-07-30 01:39:32 +00004118MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
4119 const CacheView *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00004120 const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00004121 double *pixel,ExceptionInfo *exception)
4122{
4123 MagickBooleanType
4124 status;
4125
cristya19f1d72012-08-07 18:24:38 +00004126 double
cristy94ea1632011-07-30 20:40:25 +00004127 alpha[16],
cristy884f6002011-07-31 00:51:45 +00004128 gamma,
4129 pixels[16];
cristy94ea1632011-07-30 20:40:25 +00004130
4131 PixelTrait
4132 traits;
4133
cristy94ea1632011-07-30 20:40:25 +00004134 register const Quantum
4135 *p;
4136
cristy50e64b82012-06-22 17:46:19 +00004137 register ssize_t
cristy94ea1632011-07-30 20:40:25 +00004138 i;
4139
cristya085a432011-07-30 01:39:32 +00004140 ssize_t
4141 x_offset,
4142 y_offset;
4143
anthonycf4e33d2012-06-08 07:33:23 +00004144 PixelInterpolateMethod
4145 interpolate;
4146
cristya085a432011-07-30 01:39:32 +00004147 assert(image != (Image *) NULL);
4148 assert(image != (Image *) NULL);
4149 assert(image->signature == MagickSignature);
4150 assert(image_view != (CacheView *) NULL);
4151 status=MagickTrue;
cristy884f6002011-07-31 00:51:45 +00004152 *pixel=0.0;
cristycf1296e2012-08-26 23:40:49 +00004153 traits=GetPixelChannelTraits(image,channel);
cristya085a432011-07-30 01:39:32 +00004154 x_offset=(ssize_t) floor(x);
4155 y_offset=(ssize_t) floor(y);
anthonycf4e33d2012-06-08 07:33:23 +00004156 interpolate = method;
4157 if ( interpolate == UndefinedInterpolatePixel )
4158 interpolate = image->interpolate;
4159 switch (interpolate)
cristya085a432011-07-30 01:39:32 +00004160 {
anthonycf4e33d2012-06-08 07:33:23 +00004161 case AverageInterpolatePixel: /* nearest 4 neighbours */
4162 case Average9InterpolatePixel: /* nearest 9 neighbours */
4163 case Average16InterpolatePixel: /* nearest 16 neighbours */
cristy884f6002011-07-31 00:51:45 +00004164 {
cristyfb122372012-10-17 23:31:21 +00004165 ssize_t
4166 count;
anthonycf4e33d2012-06-08 07:33:23 +00004167
cristyfb122372012-10-17 23:31:21 +00004168 count=2; /* size of the area to average - default nearest 4 */
anthonycf4e33d2012-06-08 07:33:23 +00004169 if (interpolate == Average9InterpolatePixel)
4170 {
4171 count=3;
4172 x_offset=(ssize_t) (floor(x+0.5)-1);
4173 y_offset=(ssize_t) (floor(y+0.5)-1);
4174 }
cristyfb122372012-10-17 23:31:21 +00004175 else
4176 if (interpolate == Average16InterpolatePixel)
4177 {
4178 count=4;
4179 x_offset--;
4180 y_offset--;
4181 }
anthonycf4e33d2012-06-08 07:33:23 +00004182 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,count,count,
cristy884f6002011-07-31 00:51:45 +00004183 exception);
4184 if (p == (const Quantum *) NULL)
4185 {
4186 status=MagickFalse;
4187 break;
4188 }
anthonycf4e33d2012-06-08 07:33:23 +00004189 count*=count; /* Number of pixels to Average */
cristy222b19c2011-08-04 01:35:11 +00004190 if ((traits & BlendPixelTrait) == 0)
cristy50e64b82012-06-22 17:46:19 +00004191 for (i=0; i < (ssize_t) count; i++)
cristy884f6002011-07-31 00:51:45 +00004192 {
4193 alpha[i]=1.0;
cristya19f1d72012-08-07 18:24:38 +00004194 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
cristy884f6002011-07-31 00:51:45 +00004195 }
4196 else
cristy50e64b82012-06-22 17:46:19 +00004197 for (i=0; i < (ssize_t) count; i++)
cristy884f6002011-07-31 00:51:45 +00004198 {
4199 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4200 GetPixelChannels(image));
4201 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4202 }
cristy50e64b82012-06-22 17:46:19 +00004203 for (i=0; i < (ssize_t) count; i++)
cristy884f6002011-07-31 00:51:45 +00004204 {
cristy3e3ec3a2012-11-03 23:11:06 +00004205 gamma=PerceptibleReciprocal(alpha[i])/count;
anthonycf4e33d2012-06-08 07:33:23 +00004206 *pixel+=gamma*pixels[i];
cristy884f6002011-07-31 00:51:45 +00004207 }
4208 break;
4209 }
anthonycf4e33d2012-06-08 07:33:23 +00004210 case BilinearInterpolatePixel:
4211 default:
4212 {
4213 PointInfo
4214 delta,
4215 epsilon;
4216
4217 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4218 if (p == (const Quantum *) NULL)
4219 {
4220 status=MagickFalse;
4221 break;
4222 }
4223 if ((traits & BlendPixelTrait) == 0)
4224 for (i=0; i < 4; i++)
4225 {
4226 alpha[i]=1.0;
cristya19f1d72012-08-07 18:24:38 +00004227 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
anthonycf4e33d2012-06-08 07:33:23 +00004228 }
4229 else
4230 for (i=0; i < 4; i++)
4231 {
4232 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4233 GetPixelChannels(image));
4234 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4235 }
4236 delta.x=x-x_offset;
4237 delta.y=y-y_offset;
4238 epsilon.x=1.0-delta.x;
4239 epsilon.y=1.0-delta.y;
4240 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4241 (epsilon.x*alpha[2]+delta.x*alpha[3])));
cristy3e3ec3a2012-11-03 23:11:06 +00004242 gamma=PerceptibleReciprocal(gamma);
anthonycf4e33d2012-06-08 07:33:23 +00004243 *pixel=gamma*(epsilon.y*(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*
4244 (epsilon.x*pixels[2]+delta.x*pixels[3]));
4245 break;
4246 }
anthony5f78bca2012-10-05 06:51:00 +00004247 case BlendInterpolatePixel:
4248 {
4249 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4250 if (p == (const Quantum *) NULL)
4251 {
4252 status=MagickFalse;
4253 break;
4254 }
4255 if ((traits & BlendPixelTrait) == 0)
4256 for (i=0; i < 4; i++)
4257 {
4258 alpha[i]=1.0;
4259 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4260 }
4261 else
4262 for (i=0; i < 4; i++)
4263 {
4264 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4265 GetPixelChannels(image));
4266 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4267 }
4268 gamma=1.0; /* number of pixels blended together (its variable) */
4269 for (i=0; i <= 1L; i++) {
cristyfb122372012-10-17 23:31:21 +00004270 if ((y-y_offset) >= 0.75)
4271 {
4272 alpha[i]=alpha[i+2]; /* take right pixels */
4273 pixels[i]=pixels[i+2];
4274 }
4275 else
4276 if ((y-y_offset) > 0.25)
4277 {
4278 gamma=2.0; /* blend both pixels in row */
4279 alpha[i]+=alpha[i+2]; /* add up alpha weights */
4280 pixels[i]+=pixels[i+2];
4281 }
4282 }
4283 if ((x-x_offset) >= 0.75)
4284 {
4285 alpha[0]=alpha[1]; /* take bottom row blend */
4286 pixels[0]=pixels[1];
anthony5f78bca2012-10-05 06:51:00 +00004287 }
cristyfb122372012-10-17 23:31:21 +00004288 else
4289 if ((x-x_offset) > 0.25)
4290 {
4291 gamma*=2.0; /* blend both rows */
4292 alpha[0]+=alpha[1]; /* add up alpha weights */
4293 pixels[0]+=pixels[1];
4294 }
anthony5f78bca2012-10-05 06:51:00 +00004295 if (channel != AlphaPixelChannel)
cristy3e3ec3a2012-11-03 23:11:06 +00004296 gamma=PerceptibleReciprocal(alpha[0]); /* (color) 1/alpha_weights */
anthony5f78bca2012-10-05 06:51:00 +00004297 else
cristy3e3ec3a2012-11-03 23:11:06 +00004298 gamma=PerceptibleReciprocal(gamma); /* (alpha) 1/number_of_pixels */
anthony5f78bca2012-10-05 06:51:00 +00004299 *pixel=gamma*pixels[0];
4300 break;
4301 }
anthonycf4e33d2012-06-08 07:33:23 +00004302 case CatromInterpolatePixel:
cristy884f6002011-07-31 00:51:45 +00004303 {
cristya19f1d72012-08-07 18:24:38 +00004304 double
cristy380a11c2012-06-02 15:15:22 +00004305 cx[4],
nicolas6676f5a2012-06-12 16:01:15 +00004306 cy[4];
cristy884f6002011-07-31 00:51:45 +00004307
cristy884f6002011-07-31 00:51:45 +00004308 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4309 exception);
4310 if (p == (const Quantum *) NULL)
4311 {
4312 status=MagickFalse;
4313 break;
4314 }
cristy222b19c2011-08-04 01:35:11 +00004315 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004316 for (i=0; i < 16; i++)
4317 {
4318 alpha[i]=1.0;
cristya19f1d72012-08-07 18:24:38 +00004319 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
cristy884f6002011-07-31 00:51:45 +00004320 }
4321 else
4322 for (i=0; i < 16; i++)
4323 {
4324 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4325 GetPixelChannels(image));
4326 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4327 }
cristya19f1d72012-08-07 18:24:38 +00004328 CatromWeights((double) (x-x_offset),&cx);
4329 CatromWeights((double) (y-y_offset),&cy);
4330 gamma=(channel == AlphaPixelChannel ? (double) 1.0 :
cristy3e3ec3a2012-11-03 23:11:06 +00004331 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
nicolasd32d5e52012-06-12 15:34:10 +00004332 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4333 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4334 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4335 cx[2]*alpha[14]+cx[3]*alpha[15])));
cristy380a11c2012-06-02 15:15:22 +00004336 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
nicolasd32d5e52012-06-12 15:34:10 +00004337 cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*
4338 pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+
4339 cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*
4340 pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15]));
cristy884f6002011-07-31 00:51:45 +00004341 break;
4342 }
anthonycf4e33d2012-06-08 07:33:23 +00004343#if 0
nicolas20075dc2012-06-12 20:47:38 +00004344 /* deprecated useless and very slow interpolator */
cristy884f6002011-07-31 00:51:45 +00004345 case FilterInterpolatePixel:
4346 {
4347 CacheView
4348 *filter_view;
4349
4350 Image
4351 *excerpt_image,
4352 *filter_image;
4353
4354 RectangleInfo
4355 geometry;
4356
4357 geometry.width=4L;
4358 geometry.height=4L;
4359 geometry.x=x_offset-1;
4360 geometry.y=y_offset-1;
4361 excerpt_image=ExcerptImage(image,&geometry,exception);
4362 if (excerpt_image == (Image *) NULL)
4363 {
4364 status=MagickFalse;
4365 break;
4366 }
cristyaa2c16c2012-03-25 22:21:35 +00004367 filter_image=ResizeImage(excerpt_image,1,1,image->filter,exception);
cristy884f6002011-07-31 00:51:45 +00004368 excerpt_image=DestroyImage(excerpt_image);
4369 if (filter_image == (Image *) NULL)
4370 break;
cristy46ff2672012-12-14 15:32:26 +00004371 filter_view=AcquireVirtualCacheView(filter_image,exception);
cristy884f6002011-07-31 00:51:45 +00004372 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4373 if (p == (const Quantum *) NULL)
4374 status=MagickFalse;
4375 else
cristy0beccfa2011-09-25 20:47:53 +00004376 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004377 filter_view=DestroyCacheView(filter_view);
4378 filter_image=DestroyImage(filter_image);
4379 break;
4380 }
anthonycf4e33d2012-06-08 07:33:23 +00004381#endif
cristy884f6002011-07-31 00:51:45 +00004382 case IntegerInterpolatePixel:
4383 {
4384 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
4385 if (p == (const Quantum *) NULL)
4386 {
4387 status=MagickFalse;
4388 break;
4389 }
cristy0beccfa2011-09-25 20:47:53 +00004390 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004391 break;
4392 }
anthonycf4e33d2012-06-08 07:33:23 +00004393 case NearestInterpolatePixel:
cristy884f6002011-07-31 00:51:45 +00004394 {
anthonycf4e33d2012-06-08 07:33:23 +00004395 x_offset=(ssize_t) floor(x+0.5);
4396 y_offset=(ssize_t) floor(y+0.5);
4397 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
cristy884f6002011-07-31 00:51:45 +00004398 if (p == (const Quantum *) NULL)
4399 {
4400 status=MagickFalse;
4401 break;
4402 }
cristy0beccfa2011-09-25 20:47:53 +00004403 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004404 break;
4405 }
4406 case MeshInterpolatePixel:
4407 {
4408 PointInfo
4409 delta,
cristy94ea1632011-07-30 20:40:25 +00004410 luminance;
4411
4412 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4413 if (p == (const Quantum *) NULL)
4414 {
4415 status=MagickFalse;
4416 break;
4417 }
cristy222b19c2011-08-04 01:35:11 +00004418 if ((traits & BlendPixelTrait) == 0)
cristy94ea1632011-07-30 20:40:25 +00004419 for (i=0; i < 4; i++)
4420 {
4421 alpha[i]=1.0;
cristya19f1d72012-08-07 18:24:38 +00004422 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
cristy94ea1632011-07-30 20:40:25 +00004423 }
4424 else
4425 for (i=0; i < 4; i++)
4426 {
4427 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4428 GetPixelChannels(image));
4429 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4430 }
cristy884f6002011-07-31 00:51:45 +00004431 delta.x=x-x_offset;
4432 delta.y=y-y_offset;
4433 luminance.x=GetPixelLuminance(image,p)-(double)
4434 GetPixelLuminance(image,p+3*GetPixelChannels(image));
cristy28474bf2011-09-11 23:32:52 +00004435 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
cristy884f6002011-07-31 00:51:45 +00004436 GetPixelLuminance(image,p+2*GetPixelChannels(image));
cristy94ea1632011-07-30 20:40:25 +00004437 if (fabs(luminance.x) < fabs(luminance.y))
4438 {
4439 /*
4440 Diagonal 0-3 NW-SE.
4441 */
4442 if (delta.x <= delta.y)
4443 {
4444 /*
4445 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4446 */
4447 delta.y=1.0-delta.y;
4448 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
cristy3e3ec3a2012-11-03 23:11:06 +00004449 gamma=PerceptibleReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004450 *pixel=gamma*MeshInterpolate(&delta,pixels[2],pixels[3],
4451 pixels[0]);
4452 }
4453 else
4454 {
4455 /*
4456 Top-right triangle (pixel: 1, diagonal: 0-3).
4457 */
4458 delta.x=1.0-delta.x;
4459 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
cristy3e3ec3a2012-11-03 23:11:06 +00004460 gamma=PerceptibleReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004461 *pixel=gamma*MeshInterpolate(&delta,pixels[1],pixels[0],
4462 pixels[3]);
4463 }
4464 }
4465 else
4466 {
4467 /*
4468 Diagonal 1-2 NE-SW.
4469 */
4470 if (delta.x <= (1.0-delta.y))
4471 {
4472 /*
4473 Top-left triangle (pixel: 0, diagonal: 1-2).
4474 */
4475 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
cristy3e3ec3a2012-11-03 23:11:06 +00004476 gamma=PerceptibleReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004477 *pixel=gamma*MeshInterpolate(&delta,pixels[0],pixels[1],
4478 pixels[2]);
4479 }
4480 else
4481 {
4482 /*
4483 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4484 */
4485 delta.x=1.0-delta.x;
4486 delta.y=1.0-delta.y;
4487 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
cristy3e3ec3a2012-11-03 23:11:06 +00004488 gamma=PerceptibleReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004489 *pixel=gamma*MeshInterpolate(&delta,pixels[3],pixels[2],
4490 pixels[1]);
4491 }
4492 }
cristya085a432011-07-30 01:39:32 +00004493 break;
4494 }
cristy884f6002011-07-31 00:51:45 +00004495 case SplineInterpolatePixel:
4496 {
cristya19f1d72012-08-07 18:24:38 +00004497 double
nicolasd32d5e52012-06-12 15:34:10 +00004498 cx[4],
nicolas6676f5a2012-06-12 16:01:15 +00004499 cy[4];
cristy884f6002011-07-31 00:51:45 +00004500
4501 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4502 exception);
4503 if (p == (const Quantum *) NULL)
4504 {
4505 status=MagickFalse;
4506 break;
4507 }
cristy222b19c2011-08-04 01:35:11 +00004508 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004509 for (i=0; i < 16; i++)
4510 {
4511 alpha[i]=1.0;
cristya19f1d72012-08-07 18:24:38 +00004512 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
cristy884f6002011-07-31 00:51:45 +00004513 }
4514 else
4515 for (i=0; i < 16; i++)
4516 {
4517 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4518 GetPixelChannels(image));
4519 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4520 }
cristya19f1d72012-08-07 18:24:38 +00004521 SplineWeights((double) (x-x_offset),&cx);
4522 SplineWeights((double) (y-y_offset),&cy);
4523 gamma=(channel == AlphaPixelChannel ? (double) 1.0 :
cristy3e3ec3a2012-11-03 23:11:06 +00004524 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
nicolasd32d5e52012-06-12 15:34:10 +00004525 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4526 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4527 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4528 cx[2]*alpha[14]+cx[3]*alpha[15])));
4529 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
4530 cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*
4531 pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+
4532 cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*
4533 pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15]));
cristy884f6002011-07-31 00:51:45 +00004534 break;
4535 }
cristya085a432011-07-30 01:39:32 +00004536 }
4537 return(status);
4538}
4539
4540/*
4541%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4542% %
4543% %
4544% %
cristy5c4e2582011-09-11 19:21:03 +00004545% I n t e r p o l a t e P i x e l C h a n n e l s %
4546% %
4547% %
4548% %
4549%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4550%
4551% InterpolatePixelChannels() applies a pixel interpolation method between a
4552% floating point coordinate and the pixels surrounding that coordinate. No
4553% pixel area resampling, or scaling of the result is performed.
4554%
anthonycf4e33d2012-06-08 07:33:23 +00004555% Interpolation is restricted to just the current channel setting of the
4556% destination image into which the color is to be stored
4557%
cristy5c4e2582011-09-11 19:21:03 +00004558% The format of the InterpolatePixelChannels method is:
4559%
4560% MagickBooleanType InterpolatePixelChannels(const Image *source,
4561% const CacheView *source_view,const Image *destination,
4562% const PixelInterpolateMethod method,const double x,const double y,
4563% Quantum *pixel,ExceptionInfo *exception)
4564%
4565% A description of each parameter follows:
4566%
4567% o source: the source.
4568%
4569% o source_view: the source view.
4570%
anthonycf4e33d2012-06-08 07:33:23 +00004571% o destination: the destination image, for the interpolated color
cristy5c4e2582011-09-11 19:21:03 +00004572%
4573% o method: the pixel color interpolation method.
4574%
4575% o x,y: A double representing the current (x,y) position of the pixel.
4576%
4577% o pixel: return the interpolated pixel here.
4578%
4579% o exception: return any errors or warnings in this structure.
4580%
4581*/
4582MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
4583 const CacheView *source_view,const Image *destination,
4584 const PixelInterpolateMethod method,const double x,const double y,
4585 Quantum *pixel,ExceptionInfo *exception)
4586{
4587 MagickBooleanType
4588 status;
4589
cristya19f1d72012-08-07 18:24:38 +00004590 double
cristy5c4e2582011-09-11 19:21:03 +00004591 alpha[16],
4592 gamma,
4593 pixels[16];
4594
4595 PixelChannel
4596 channel;
4597
4598 PixelTrait
4599 destination_traits,
4600 traits;
4601
4602 register const Quantum
4603 *p;
4604
cristy50e64b82012-06-22 17:46:19 +00004605 register ssize_t
cristy5c4e2582011-09-11 19:21:03 +00004606 i;
4607
4608 ssize_t
4609 x_offset,
4610 y_offset;
4611
anthonycf4e33d2012-06-08 07:33:23 +00004612 PixelInterpolateMethod
4613 interpolate;
4614
cristy5c4e2582011-09-11 19:21:03 +00004615 assert(source != (Image *) NULL);
4616 assert(source != (Image *) NULL);
4617 assert(source->signature == MagickSignature);
4618 assert(source_view != (CacheView *) NULL);
4619 status=MagickTrue;
4620 x_offset=(ssize_t) floor(x);
4621 y_offset=(ssize_t) floor(y);
anthonycf4e33d2012-06-08 07:33:23 +00004622 interpolate = method;
4623 if ( interpolate == UndefinedInterpolatePixel )
4624 interpolate = source->interpolate;
4625 switch (interpolate)
cristy5c4e2582011-09-11 19:21:03 +00004626 {
anthonycf4e33d2012-06-08 07:33:23 +00004627 case AverageInterpolatePixel: /* nearest 4 neighbours */
4628 case Average9InterpolatePixel: /* nearest 9 neighbours */
4629 case Average16InterpolatePixel: /* nearest 16 neighbours */
cristy5c4e2582011-09-11 19:21:03 +00004630 {
cristyfb122372012-10-17 23:31:21 +00004631 ssize_t
4632 count;
anthonycf4e33d2012-06-08 07:33:23 +00004633
cristyfb122372012-10-17 23:31:21 +00004634 count=2; /* size of the area to average - default nearest 4 */
anthonycf4e33d2012-06-08 07:33:23 +00004635 if (interpolate == Average9InterpolatePixel)
4636 {
4637 count=3;
4638 x_offset=(ssize_t) (floor(x+0.5)-1);
4639 y_offset=(ssize_t) (floor(y+0.5)-1);
4640 }
cristyfb122372012-10-17 23:31:21 +00004641 else
4642 if (interpolate == Average16InterpolatePixel)
4643 {
4644 count=4;
4645 x_offset--;
4646 y_offset--;
4647 }
anthonycf4e33d2012-06-08 07:33:23 +00004648 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,count,count,
cristy5c4e2582011-09-11 19:21:03 +00004649 exception);
4650 if (p == (const Quantum *) NULL)
4651 {
4652 status=MagickFalse;
4653 break;
4654 }
cristyfb122372012-10-17 23:31:21 +00004655 count*=count; /* Number of pixels to Average */
cristy50e64b82012-06-22 17:46:19 +00004656 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004657 {
4658 double
4659 sum;
4660
cristy50e64b82012-06-22 17:46:19 +00004661 register ssize_t
cristy5c4e2582011-09-11 19:21:03 +00004662 j;
4663
cristycf1296e2012-08-26 23:40:49 +00004664 channel=GetPixelChannelChannel(source,i);
4665 traits=GetPixelChannelTraits(source,channel);
4666 destination_traits=GetPixelChannelTraits(destination,channel);
cristy5c4e2582011-09-11 19:21:03 +00004667 if ((traits == UndefinedPixelTrait) ||
4668 (destination_traits == UndefinedPixelTrait))
4669 continue;
cristy50e64b82012-06-22 17:46:19 +00004670 for (j=0; j < (ssize_t) count; j++)
cristya19f1d72012-08-07 18:24:38 +00004671 pixels[j]=(double) p[j*GetPixelChannels(source)+i];
cristy4a7ae692011-12-14 12:24:11 +00004672 sum=0.0;
cristy5c4e2582011-09-11 19:21:03 +00004673 if ((traits & BlendPixelTrait) == 0)
4674 {
cristy50e64b82012-06-22 17:46:19 +00004675 for (j=0; j < (ssize_t) count; j++)
anthonycf4e33d2012-06-08 07:33:23 +00004676 sum+=pixels[j];
4677 sum/=count;
cristy4a7ae692011-12-14 12:24:11 +00004678 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004679 continue;
4680 }
cristy50e64b82012-06-22 17:46:19 +00004681 for (j=0; j < (ssize_t) count; j++)
cristy5c4e2582011-09-11 19:21:03 +00004682 {
4683 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4684 GetPixelChannels(source));
4685 pixels[j]*=alpha[j];
cristy3e3ec3a2012-11-03 23:11:06 +00004686 gamma=PerceptibleReciprocal(alpha[j]);
anthonycf4e33d2012-06-08 07:33:23 +00004687 sum+=gamma*pixels[j];
cristy5c4e2582011-09-11 19:21:03 +00004688 }
anthonycf4e33d2012-06-08 07:33:23 +00004689 sum/=count;
cristy4a7ae692011-12-14 12:24:11 +00004690 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004691 }
4692 break;
4693 }
anthonycf4e33d2012-06-08 07:33:23 +00004694 case BilinearInterpolatePixel:
4695 default:
4696 {
4697 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4698 if (p == (const Quantum *) NULL)
4699 {
4700 status=MagickFalse;
4701 break;
4702 }
cristy50e64b82012-06-22 17:46:19 +00004703 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
anthonycf4e33d2012-06-08 07:33:23 +00004704 {
4705 PointInfo
4706 delta,
4707 epsilon;
4708
cristycf1296e2012-08-26 23:40:49 +00004709 channel=GetPixelChannelChannel(source,i);
4710 traits=GetPixelChannelTraits(source,channel);
4711 destination_traits=GetPixelChannelTraits(destination,channel);
anthonycf4e33d2012-06-08 07:33:23 +00004712 if ((traits == UndefinedPixelTrait) ||
4713 (destination_traits == UndefinedPixelTrait))
4714 continue;
4715 delta.x=x-x_offset;
4716 delta.y=y-y_offset;
4717 epsilon.x=1.0-delta.x;
4718 epsilon.y=1.0-delta.y;
cristya19f1d72012-08-07 18:24:38 +00004719 pixels[0]=(double) p[i];
4720 pixels[1]=(double) p[GetPixelChannels(source)+i];
4721 pixels[2]=(double) p[2*GetPixelChannels(source)+i];
4722 pixels[3]=(double) p[3*GetPixelChannels(source)+i];
anthonycf4e33d2012-06-08 07:33:23 +00004723 if ((traits & BlendPixelTrait) == 0)
4724 {
4725 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
cristy3e3ec3a2012-11-03 23:11:06 +00004726 gamma=PerceptibleReciprocal(gamma);
anthonycf4e33d2012-06-08 07:33:23 +00004727 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
4728 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*
4729 pixels[2]+delta.x*pixels[3]))),pixel);
4730 continue;
4731 }
4732 alpha[0]=QuantumScale*GetPixelAlpha(source,p);
4733 alpha[1]=QuantumScale*GetPixelAlpha(source,p+GetPixelChannels(source));
4734 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
4735 GetPixelChannels(source));
4736 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
4737 GetPixelChannels(source));
4738 pixels[0]*=alpha[0];
4739 pixels[1]*=alpha[1];
4740 pixels[2]*=alpha[2];
4741 pixels[3]*=alpha[3];
4742 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4743 (epsilon.x*alpha[2]+delta.x*alpha[3])));
cristy3e3ec3a2012-11-03 23:11:06 +00004744 gamma=PerceptibleReciprocal(gamma);
anthonycf4e33d2012-06-08 07:33:23 +00004745 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
4746 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*pixels[2]+
4747 delta.x*pixels[3]))),pixel);
4748 }
4749 break;
4750 }
anthony5f78bca2012-10-05 06:51:00 +00004751 case BlendInterpolatePixel:
4752 {
4753 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4754 if (p == (const Quantum *) NULL)
4755 {
4756 status=MagickFalse;
4757 break;
4758 }
4759 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4760 {
4761 register ssize_t
4762 j;
4763
4764 channel=GetPixelChannelChannel(source,i);
4765 traits=GetPixelChannelTraits(source,channel);
4766 destination_traits=GetPixelChannelTraits(destination,channel);
4767 if ((traits == UndefinedPixelTrait) ||
4768 (destination_traits == UndefinedPixelTrait))
4769 continue;
4770 if ((traits & BlendPixelTrait) == 0)
4771 for (j=0; j < 4; j++)
4772 {
4773 alpha[j]=1.0;
4774 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+channel];
4775 }
4776 else
4777 for (j=0; j < 4; j++)
4778 {
4779 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4780 GetPixelChannels(source));
4781 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+channel];
4782 }
cristyfb122372012-10-17 23:31:21 +00004783 gamma=1.0; /* number of pixels blended together (its variable) */
4784 for (j=0; j <= 1L; j++)
4785 {
4786 if ((y-y_offset) >= 0.75)
4787 {
4788 alpha[j]=alpha[j+2]; /* take right pixels */
4789 pixels[j]=pixels[j+2];
4790 }
4791 else
4792 if ((y-y_offset) > 0.25)
4793 {
4794 gamma=2.0; /* blend both pixels in row */
4795 alpha[j]+=alpha[j+2]; /* add up alpha weights */
4796 pixels[j]+=pixels[j+2];
4797 }
4798 }
4799 if ((x-x_offset) >= 0.75)
4800 {
4801 alpha[0]=alpha[1]; /* take bottom row blend */
4802 pixels[0]=pixels[1];
anthony5f78bca2012-10-05 06:51:00 +00004803 }
cristyfb122372012-10-17 23:31:21 +00004804 else
4805 if ((x-x_offset) > 0.25)
4806 {
4807 gamma*=2.0; /* blend both rows */
4808 alpha[0]+=alpha[1]; /* add up alpha weights */
4809 pixels[0]+=pixels[1];
4810 }
anthony5f78bca2012-10-05 06:51:00 +00004811 if ((traits & BlendPixelTrait) == 0)
cristy3e3ec3a2012-11-03 23:11:06 +00004812 gamma=PerceptibleReciprocal(alpha[0]); /* (color) 1/alpha_weights */
anthony5f78bca2012-10-05 06:51:00 +00004813 else
cristy3e3ec3a2012-11-03 23:11:06 +00004814 gamma=PerceptibleReciprocal(gamma); /* (alpha) 1/number_of_pixels */
anthony5f78bca2012-10-05 06:51:00 +00004815 SetPixelChannel(destination,channel,ClampToQuantum(gamma*pixels[0]),
cristyfb122372012-10-17 23:31:21 +00004816 pixel);
anthony5f78bca2012-10-05 06:51:00 +00004817 }
4818 break;
4819 }
anthonycf4e33d2012-06-08 07:33:23 +00004820 case CatromInterpolatePixel:
cristy5c4e2582011-09-11 19:21:03 +00004821 {
cristya19f1d72012-08-07 18:24:38 +00004822 double
cristy380a11c2012-06-02 15:15:22 +00004823 cx[4],
4824 cy[4];
cristy5c4e2582011-09-11 19:21:03 +00004825
cristy5c4e2582011-09-11 19:21:03 +00004826 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4827 exception);
4828 if (p == (const Quantum *) NULL)
4829 {
4830 status=MagickFalse;
4831 break;
4832 }
cristy50e64b82012-06-22 17:46:19 +00004833 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004834 {
4835 register ssize_t
4836 j;
4837
cristycf1296e2012-08-26 23:40:49 +00004838 channel=GetPixelChannelChannel(source,i);
4839 traits=GetPixelChannelTraits(source,channel);
4840 destination_traits=GetPixelChannelTraits(destination,channel);
cristy5c4e2582011-09-11 19:21:03 +00004841 if ((traits == UndefinedPixelTrait) ||
4842 (destination_traits == UndefinedPixelTrait))
4843 continue;
4844 if ((traits & BlendPixelTrait) == 0)
4845 for (j=0; j < 16; j++)
4846 {
4847 alpha[j]=1.0;
cristya19f1d72012-08-07 18:24:38 +00004848 pixels[j]=(double) p[j*GetPixelChannels(source)+i];
cristy5c4e2582011-09-11 19:21:03 +00004849 }
4850 else
4851 for (j=0; j < 16; j++)
4852 {
4853 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4854 GetPixelChannels(source));
4855 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
4856 }
cristya19f1d72012-08-07 18:24:38 +00004857 CatromWeights((double) (x-x_offset),&cx);
4858 CatromWeights((double) (y-y_offset),&cy);
4859 gamma=((traits & BlendPixelTrait) ? (double) (1.0) :
cristy3e3ec3a2012-11-03 23:11:06 +00004860 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
nicolasd32d5e52012-06-12 15:34:10 +00004861 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4862 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4863 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4864 cx[2]*alpha[14]+cx[3]*alpha[15])));
cristy380a11c2012-06-02 15:15:22 +00004865 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]*
4866 pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]*
4867 (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+
4868 cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*
nicolasd32d5e52012-06-12 15:34:10 +00004869 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*
4870 pixels[14]+cx[3]*pixels[15]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004871 }
4872 break;
4873 }
anthonycf4e33d2012-06-08 07:33:23 +00004874#if 0
nicolas20075dc2012-06-12 20:47:38 +00004875 /* deprecated useless and very slow interpolator */
cristy5c4e2582011-09-11 19:21:03 +00004876 case FilterInterpolatePixel:
4877 {
cristy50e64b82012-06-22 17:46:19 +00004878 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004879 {
4880 CacheView
4881 *filter_view;
4882
4883 Image
4884 *excerpt_source,
4885 *filter_source;
4886
4887 RectangleInfo
4888 geometry;
4889
cristycf1296e2012-08-26 23:40:49 +00004890 channel=GetPixelChannelChannel(source,i);
4891 traits=GetPixelChannelTraits(source,channel);
4892 destination_traits=GetPixelChannelTraits(destination,channel);
cristy5c4e2582011-09-11 19:21:03 +00004893 if ((traits == UndefinedPixelTrait) ||
4894 (destination_traits == UndefinedPixelTrait))
4895 continue;
4896 geometry.width=4L;
4897 geometry.height=4L;
4898 geometry.x=x_offset-1;
4899 geometry.y=y_offset-1;
4900 excerpt_source=ExcerptImage(source,&geometry,exception);
4901 if (excerpt_source == (Image *) NULL)
4902 {
4903 status=MagickFalse;
4904 continue;
4905 }
cristyaa2c16c2012-03-25 22:21:35 +00004906 filter_source=ResizeImage(excerpt_source,1,1,source->filter,exception);
cristy5c4e2582011-09-11 19:21:03 +00004907 excerpt_source=DestroyImage(excerpt_source);
4908 if (filter_source == (Image *) NULL)
4909 continue;
cristy46ff2672012-12-14 15:32:26 +00004910 filter_view=AcquireVirtualCacheView(filter_source,exception);
cristy5c4e2582011-09-11 19:21:03 +00004911 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4912 if (p == (const Quantum *) NULL)
4913 status=MagickFalse;
4914 else
cristy1861c902011-12-14 02:30:00 +00004915 {
cristy4a7ae692011-12-14 12:24:11 +00004916 SetPixelChannel(destination,channel,p[i],pixel);
cristy1861c902011-12-14 02:30:00 +00004917 }
cristy5c4e2582011-09-11 19:21:03 +00004918 filter_view=DestroyCacheView(filter_view);
4919 filter_source=DestroyImage(filter_source);
4920 }
4921 break;
4922 }
anthonycf4e33d2012-06-08 07:33:23 +00004923#endif
cristy5c4e2582011-09-11 19:21:03 +00004924 case IntegerInterpolatePixel:
4925 {
4926 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
4927 if (p == (const Quantum *) NULL)
4928 {
4929 status=MagickFalse;
4930 break;
4931 }
cristy50e64b82012-06-22 17:46:19 +00004932 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004933 {
cristycf1296e2012-08-26 23:40:49 +00004934 channel=GetPixelChannelChannel(source,i);
4935 traits=GetPixelChannelTraits(source,channel);
4936 destination_traits=GetPixelChannelTraits(destination,channel);
cristy5c4e2582011-09-11 19:21:03 +00004937 if ((traits == UndefinedPixelTrait) ||
4938 (destination_traits == UndefinedPixelTrait))
4939 continue;
cristy4a7ae692011-12-14 12:24:11 +00004940 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004941 }
4942 break;
4943 }
anthonycf4e33d2012-06-08 07:33:23 +00004944 case NearestInterpolatePixel:
cristy5c4e2582011-09-11 19:21:03 +00004945 {
anthonycf4e33d2012-06-08 07:33:23 +00004946 x_offset=(ssize_t) floor(x+0.5);
4947 y_offset=(ssize_t) floor(y+0.5);
4948 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
cristy5c4e2582011-09-11 19:21:03 +00004949 if (p == (const Quantum *) NULL)
4950 {
4951 status=MagickFalse;
4952 break;
4953 }
cristy50e64b82012-06-22 17:46:19 +00004954 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004955 {
cristycf1296e2012-08-26 23:40:49 +00004956 channel=GetPixelChannelChannel(source,i);
4957 traits=GetPixelChannelTraits(source,channel);
4958 destination_traits=GetPixelChannelTraits(destination,channel);
cristy5c4e2582011-09-11 19:21:03 +00004959 if ((traits == UndefinedPixelTrait) ||
4960 (destination_traits == UndefinedPixelTrait))
4961 continue;
cristy4a7ae692011-12-14 12:24:11 +00004962 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004963 }
4964 break;
4965 }
4966 case MeshInterpolatePixel:
4967 {
4968 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4969 if (p == (const Quantum *) NULL)
4970 {
4971 status=MagickFalse;
4972 break;
4973 }
cristy50e64b82012-06-22 17:46:19 +00004974 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004975 {
4976 PointInfo
4977 delta,
4978 luminance;
4979
cristycf1296e2012-08-26 23:40:49 +00004980 channel=GetPixelChannelChannel(source,i);
4981 traits=GetPixelChannelTraits(source,channel);
4982 destination_traits=GetPixelChannelTraits(destination,channel);
cristy5c4e2582011-09-11 19:21:03 +00004983 if ((traits == UndefinedPixelTrait) ||
4984 (destination_traits == UndefinedPixelTrait))
4985 continue;
cristya19f1d72012-08-07 18:24:38 +00004986 pixels[0]=(double) p[i];
4987 pixels[1]=(double) p[GetPixelChannels(source)+i];
4988 pixels[2]=(double) p[2*GetPixelChannels(source)+i];
4989 pixels[3]=(double) p[3*GetPixelChannels(source)+i];
cristy1861c902011-12-14 02:30:00 +00004990 if ((traits & BlendPixelTrait) == 0)
4991 {
4992 alpha[0]=1.0;
4993 alpha[1]=1.0;
4994 alpha[2]=1.0;
4995 alpha[3]=1.0;
4996 }
4997 else
4998 {
4999 alpha[0]=QuantumScale*GetPixelAlpha(source,p);
5000 alpha[1]=QuantumScale*GetPixelAlpha(source,p+
5001 GetPixelChannels(source));
5002 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
5003 GetPixelChannels(source));
5004 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
5005 GetPixelChannels(source));
5006 }
5007 delta.x=x-x_offset;
5008 delta.y=y-y_offset;
cristyfb122372012-10-17 23:31:21 +00005009 luminance.x=fabs((double) (GetPixelLuminance(source,p)-
5010 GetPixelLuminance(source,p+3*GetPixelChannels(source))));
5011 luminance.y=fabs((double) (GetPixelLuminance(source,p+
5012 GetPixelChannels(source))-GetPixelLuminance(source,p+2*
5013 GetPixelChannels(source))));
anthonycf4e33d2012-06-08 07:33:23 +00005014 if (luminance.x < luminance.y)
cristy1861c902011-12-14 02:30:00 +00005015 {
5016 /*
5017 Diagonal 0-3 NW-SE.
5018 */
5019 if (delta.x <= delta.y)
5020 {
5021 /*
5022 Bottom-left triangle (pixel: 2, diagonal: 0-3).
5023 */
5024 delta.y=1.0-delta.y;
5025 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
cristy3e3ec3a2012-11-03 23:11:06 +00005026 gamma=PerceptibleReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00005027 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5028 MeshInterpolate(&delta,pixels[2],pixels[3],pixels[0])),pixel);
cristy1861c902011-12-14 02:30:00 +00005029 }
5030 else
5031 {
5032 /*
5033 Top-right triangle (pixel: 1, diagonal: 0-3).
5034 */
5035 delta.x=1.0-delta.x;
5036 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
cristy3e3ec3a2012-11-03 23:11:06 +00005037 gamma=PerceptibleReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00005038 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5039 MeshInterpolate(&delta,pixels[1],pixels[0],pixels[3])),pixel);
cristy1861c902011-12-14 02:30:00 +00005040 }
5041 }
5042 else
5043 {
5044 /*
5045 Diagonal 1-2 NE-SW.
5046 */
5047 if (delta.x <= (1.0-delta.y))
5048 {
5049 /*
5050 Top-left triangle (pixel: 0, diagonal: 1-2).
5051 */
5052 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
cristy3e3ec3a2012-11-03 23:11:06 +00005053 gamma=PerceptibleReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00005054 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5055 MeshInterpolate(&delta,pixels[0],pixels[1],pixels[2])),pixel);
cristy1861c902011-12-14 02:30:00 +00005056 }
5057 else
5058 {
5059 /*
5060 Bottom-right triangle (pixel: 3, diagonal: 1-2).
5061 */
5062 delta.x=1.0-delta.x;
5063 delta.y=1.0-delta.y;
5064 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
cristy3e3ec3a2012-11-03 23:11:06 +00005065 gamma=PerceptibleReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00005066 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5067 MeshInterpolate(&delta,pixels[3],pixels[2],pixels[1])),pixel);
cristy1861c902011-12-14 02:30:00 +00005068 }
5069 }
cristy5c4e2582011-09-11 19:21:03 +00005070 }
5071 break;
5072 }
5073 case SplineInterpolatePixel:
5074 {
cristya19f1d72012-08-07 18:24:38 +00005075 double
nicolasd32d5e52012-06-12 15:34:10 +00005076 cx[4],
5077 cy[4];
5078
cristy5c4e2582011-09-11 19:21:03 +00005079 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
5080 exception);
5081 if (p == (const Quantum *) NULL)
5082 {
5083 status=MagickFalse;
5084 break;
5085 }
cristy50e64b82012-06-22 17:46:19 +00005086 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00005087 {
cristy5c4e2582011-09-11 19:21:03 +00005088 register ssize_t
5089 j;
5090
cristycf1296e2012-08-26 23:40:49 +00005091 channel=GetPixelChannelChannel(source,i);
5092 traits=GetPixelChannelTraits(source,channel);
5093 destination_traits=GetPixelChannelTraits(destination,channel);
cristy5c4e2582011-09-11 19:21:03 +00005094 if ((traits == UndefinedPixelTrait) ||
5095 (destination_traits == UndefinedPixelTrait))
5096 continue;
5097 if ((traits & BlendPixelTrait) == 0)
5098 for (j=0; j < 16; j++)
5099 {
5100 alpha[j]=1.0;
cristya19f1d72012-08-07 18:24:38 +00005101 pixels[j]=(double) p[j*GetPixelChannels(source)+i];
cristy5c4e2582011-09-11 19:21:03 +00005102 }
5103 else
5104 for (j=0; j < 16; j++)
5105 {
5106 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
5107 GetPixelChannels(source));
5108 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
5109 }
cristya19f1d72012-08-07 18:24:38 +00005110 SplineWeights((double) (x-x_offset),&cx);
5111 SplineWeights((double) (y-y_offset),&cy);
5112 gamma=((traits & BlendPixelTrait) ? (double) (1.0) :
cristy3e3ec3a2012-11-03 23:11:06 +00005113 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
nicolasd32d5e52012-06-12 15:34:10 +00005114 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
5115 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
5116 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
5117 cx[2]*alpha[14]+cx[3]*alpha[15])));
5118 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]*
5119 pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]*
5120 (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+
5121 cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*
5122 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*
5123 pixels[14]+cx[3]*pixels[15]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00005124 }
5125 break;
5126 }
5127 }
5128 return(status);
5129}
5130
5131/*
5132%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5133% %
5134% %
5135% %
cristy9075cdb2011-07-30 01:06:23 +00005136% I n t e r p o l a t e P i x e l I n f o %
cristy4c08aed2011-07-01 19:47:50 +00005137% %
5138% %
5139% %
5140%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5141%
cristy884f6002011-07-31 00:51:45 +00005142% InterpolatePixelInfo() applies a pixel interpolation method between a
5143% floating point coordinate and the pixels surrounding that coordinate. No
5144% pixel area resampling, or scaling of the result is performed.
cristy4c08aed2011-07-01 19:47:50 +00005145%
anthonycf4e33d2012-06-08 07:33:23 +00005146% Interpolation is restricted to just RGBKA channels.
5147%
cristy4c08aed2011-07-01 19:47:50 +00005148% The format of the InterpolatePixelInfo method is:
5149%
5150% MagickBooleanType InterpolatePixelInfo(const Image *image,
cristy5c4e2582011-09-11 19:21:03 +00005151% const CacheView *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00005152% const double x,const double y,PixelInfo *pixel,
5153% ExceptionInfo *exception)
5154%
5155% A description of each parameter follows:
5156%
5157% o image: the image.
5158%
5159% o image_view: the image view.
5160%
5161% o method: the pixel color interpolation method.
5162%
5163% o x,y: A double representing the current (x,y) position of the pixel.
5164%
5165% o pixel: return the interpolated pixel here.
5166%
5167% o exception: return any errors or warnings in this structure.
5168%
5169*/
5170
5171static inline void AlphaBlendPixelInfo(const Image *image,
cristya19f1d72012-08-07 18:24:38 +00005172 const Quantum *pixel,PixelInfo *pixel_info,double *alpha)
cristy4c08aed2011-07-01 19:47:50 +00005173{
cristy8a46d822012-08-28 23:32:39 +00005174 if (image->alpha_trait != BlendPixelTrait)
cristy4c08aed2011-07-01 19:47:50 +00005175 {
5176 *alpha=1.0;
cristya19f1d72012-08-07 18:24:38 +00005177 pixel_info->red=(double) GetPixelRed(image,pixel);
5178 pixel_info->green=(double) GetPixelGreen(image,pixel);
5179 pixel_info->blue=(double) GetPixelBlue(image,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005180 pixel_info->black=0.0;
5181 if (image->colorspace == CMYKColorspace)
cristya19f1d72012-08-07 18:24:38 +00005182 pixel_info->black=(double) GetPixelBlack(image,pixel);
5183 pixel_info->alpha=(double) GetPixelAlpha(image,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005184 return;
5185 }
5186 *alpha=QuantumScale*GetPixelAlpha(image,pixel);
5187 pixel_info->red=(*alpha*GetPixelRed(image,pixel));
5188 pixel_info->green=(*alpha*GetPixelGreen(image,pixel));
5189 pixel_info->blue=(*alpha*GetPixelBlue(image,pixel));
5190 pixel_info->black=0.0;
5191 if (image->colorspace == CMYKColorspace)
5192 pixel_info->black=(*alpha*GetPixelBlack(image,pixel));
cristya19f1d72012-08-07 18:24:38 +00005193 pixel_info->alpha=(double) GetPixelAlpha(image,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005194}
5195
cristy4c08aed2011-07-01 19:47:50 +00005196MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
cristy5c4e2582011-09-11 19:21:03 +00005197 const CacheView *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00005198 const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception)
5199{
5200 MagickBooleanType
5201 status;
5202
cristya19f1d72012-08-07 18:24:38 +00005203 double
cristy4c08aed2011-07-01 19:47:50 +00005204 alpha[16],
5205 gamma;
5206
cristy865d58d2011-07-09 00:44:52 +00005207 PixelInfo
5208 pixels[16];
5209
cristy4c08aed2011-07-01 19:47:50 +00005210 register const Quantum
5211 *p;
5212
cristy50e64b82012-06-22 17:46:19 +00005213 register ssize_t
cristy4c08aed2011-07-01 19:47:50 +00005214 i;
5215
5216 ssize_t
5217 x_offset,
5218 y_offset;
5219
anthonycf4e33d2012-06-08 07:33:23 +00005220 PixelInterpolateMethod
5221 interpolate;
5222
cristy4c08aed2011-07-01 19:47:50 +00005223 assert(image != (Image *) NULL);
5224 assert(image->signature == MagickSignature);
5225 assert(image_view != (CacheView *) NULL);
5226 status=MagickTrue;
5227 x_offset=(ssize_t) floor(x);
5228 y_offset=(ssize_t) floor(y);
anthonycf4e33d2012-06-08 07:33:23 +00005229 interpolate = method;
5230 if ( interpolate == UndefinedInterpolatePixel )
5231 interpolate = image->interpolate;
5232 switch (interpolate)
cristy4c08aed2011-07-01 19:47:50 +00005233 {
anthonycf4e33d2012-06-08 07:33:23 +00005234 case AverageInterpolatePixel: /* nearest 4 neighbours */
5235 case Average9InterpolatePixel: /* nearest 9 neighbours */
5236 case Average16InterpolatePixel: /* nearest 16 neighbours */
cristy4c08aed2011-07-01 19:47:50 +00005237 {
cristyfb122372012-10-17 23:31:21 +00005238 ssize_t
5239 count;
anthonycf4e33d2012-06-08 07:33:23 +00005240
cristyfb122372012-10-17 23:31:21 +00005241 count=2; /* size of the area to average - default nearest 4 */
anthonycf4e33d2012-06-08 07:33:23 +00005242 if (interpolate == Average9InterpolatePixel)
5243 {
5244 count=3;
5245 x_offset=(ssize_t) (floor(x+0.5)-1);
5246 y_offset=(ssize_t) (floor(y+0.5)-1);
5247 }
5248 else if (interpolate == Average16InterpolatePixel)
5249 {
5250 count=4;
5251 x_offset--;
5252 y_offset--;
5253 }
5254 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,count,count,
cristy4c08aed2011-07-01 19:47:50 +00005255 exception);
5256 if (p == (const Quantum *) NULL)
5257 {
5258 status=MagickFalse;
5259 break;
5260 }
cristy4c08aed2011-07-01 19:47:50 +00005261 pixel->red=0.0;
5262 pixel->green=0.0;
5263 pixel->blue=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005264 pixel->black=0.0;
cristy865d58d2011-07-09 00:44:52 +00005265 pixel->alpha=0.0;
anthonycf4e33d2012-06-08 07:33:23 +00005266 count*=count; /* number of pixels - square of size */
cristy50e64b82012-06-22 17:46:19 +00005267 for (i=0; i < (ssize_t) count; i++)
cristy4c08aed2011-07-01 19:47:50 +00005268 {
anthonycf4e33d2012-06-08 07:33:23 +00005269 AlphaBlendPixelInfo(image,p,pixels,alpha);
cristy3e3ec3a2012-11-03 23:11:06 +00005270 gamma=PerceptibleReciprocal(alpha[0]);
cristyfb122372012-10-17 23:31:21 +00005271 pixel->red+=gamma*pixels[0].red;
5272 pixel->green+=gamma*pixels[0].green;
5273 pixel->blue+=gamma*pixels[0].blue;
5274 pixel->black+=gamma*pixels[0].black;
5275 pixel->alpha+=pixels[0].alpha;
anthonycf4e33d2012-06-08 07:33:23 +00005276 p += GetPixelChannels(image);
cristy4c08aed2011-07-01 19:47:50 +00005277 }
anthonycf4e33d2012-06-08 07:33:23 +00005278 gamma=1.0/count; /* average weighting of each pixel in area */
cristyfb122372012-10-17 23:31:21 +00005279 pixel->red*=gamma;
5280 pixel->green*=gamma;
5281 pixel->blue*=gamma;
5282 pixel->black*=gamma;
5283 pixel->alpha*=gamma;
cristy4c08aed2011-07-01 19:47:50 +00005284 break;
5285 }
anthonycf4e33d2012-06-08 07:33:23 +00005286 case BackgroundInterpolatePixel:
5287 {
cristyfb122372012-10-17 23:31:21 +00005288 *pixel=image->background_color; /* Copy PixelInfo Structure */
anthonycf4e33d2012-06-08 07:33:23 +00005289 break;
5290 }
5291 case BilinearInterpolatePixel:
5292 default:
5293 {
5294 PointInfo
5295 delta,
5296 epsilon;
5297
5298 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5299 if (p == (const Quantum *) NULL)
5300 {
5301 status=MagickFalse;
5302 break;
5303 }
5304 for (i=0; i < 4L; i++)
5305 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
5306 delta.x=x-x_offset;
5307 delta.y=y-y_offset;
5308 epsilon.x=1.0-delta.x;
5309 epsilon.y=1.0-delta.y;
5310 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
5311 (epsilon.x*alpha[2]+delta.x*alpha[3])));
cristy3e3ec3a2012-11-03 23:11:06 +00005312 gamma=PerceptibleReciprocal(gamma);
anthonycf4e33d2012-06-08 07:33:23 +00005313 pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x*
5314 pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red));
5315 pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x*
5316 pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x*
5317 pixels[3].green));
5318 pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x*
5319 pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x*
5320 pixels[3].blue));
5321 if (image->colorspace == CMYKColorspace)
5322 pixel->black=gamma*(epsilon.y*(epsilon.x*pixels[0].black+delta.x*
5323 pixels[1].black)+delta.y*(epsilon.x*pixels[2].black+delta.x*
5324 pixels[3].black));
5325 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
cristy3e3ec3a2012-11-03 23:11:06 +00005326 gamma=PerceptibleReciprocal(gamma);
anthonycf4e33d2012-06-08 07:33:23 +00005327 pixel->alpha=(epsilon.y*(epsilon.x*pixels[0].alpha+delta.x*
5328 pixels[1].alpha)+delta.y*(epsilon.x*pixels[2].alpha+delta.x*
5329 pixels[3].alpha));
5330 break;
5331 }
5332 case BlendInterpolatePixel:
5333 {
5334 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5335 if (p == (const Quantum *) NULL)
5336 {
5337 status=MagickFalse;
5338 break;
5339 }
5340 for (i=0; i < 4L; i++)
5341 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
cristyfb122372012-10-17 23:31:21 +00005342 gamma=1.0; /* number of pixels blended together (its variable) */
5343 for (i=0; i <= 1L; i++)
5344 {
5345 if ((y-y_offset) >= 0.75)
5346 {
5347 alpha[i]=alpha[i+2]; /* take right pixels */
5348 pixels[i]=pixels[i+2];
5349 }
5350 else
5351 if ((y-y_offset) > 0.25)
5352 {
5353 gamma=2.0; /* blend both pixels in row */
5354 alpha[i]+=alpha[i+2]; /* add up alpha weights */
5355 pixels[i].red+=pixels[i+2].red;
5356 pixels[i].green+=pixels[i+2].green;
5357 pixels[i].blue+=pixels[i+2].blue;
5358 pixels[i].black+=pixels[i+2].black;
5359 pixels[i].alpha+=pixels[i+2].alpha;
5360 }
5361 }
5362 if ((x-x_offset) >= 0.75)
5363 {
5364 alpha[0]=alpha[1];
5365 pixels[0]=pixels[1];
anthonycf4e33d2012-06-08 07:33:23 +00005366 }
cristyfb122372012-10-17 23:31:21 +00005367 else
5368 if ((x-x_offset) > 0.25)
5369 {
5370 gamma*=2.0; /* blend both rows */
5371 alpha[0]+= alpha[1]; /* add up alpha weights */
5372 pixels[0].red+=pixels[1].red;
5373 pixels[0].green+=pixels[1].green;
5374 pixels[0].blue+=pixels[1].blue;
5375 pixels[0].black+=pixels[1].black;
5376 pixels[0].alpha+=pixels[1].alpha;
5377 }
5378 gamma=1.0/gamma;
cristy3e3ec3a2012-11-03 23:11:06 +00005379 alpha[0]=PerceptibleReciprocal(alpha[0]);
cristyfb122372012-10-17 23:31:21 +00005380 pixel->red=alpha[0]*pixels[0].red;
5381 pixel->green=alpha[0]*pixels[0].green; /* divide by sum of alpha */
5382 pixel->blue=alpha[0]*pixels[0].blue;
5383 pixel->black=alpha[0]*pixels[0].black;
5384 pixel->alpha=gamma*pixels[0].alpha; /* divide by number of pixels */
anthonycf4e33d2012-06-08 07:33:23 +00005385 break;
5386 }
5387 case CatromInterpolatePixel:
cristy4c08aed2011-07-01 19:47:50 +00005388 {
cristya19f1d72012-08-07 18:24:38 +00005389 double
cristy380a11c2012-06-02 15:15:22 +00005390 cx[4],
5391 cy[4];
cristy4c08aed2011-07-01 19:47:50 +00005392
cristy4c08aed2011-07-01 19:47:50 +00005393 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5394 exception);
5395 if (p == (const Quantum *) NULL)
5396 {
5397 status=MagickFalse;
5398 break;
5399 }
anthonycf4e33d2012-06-08 07:33:23 +00005400 for (i=0; i < 16L; i++)
5401 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
cristya19f1d72012-08-07 18:24:38 +00005402 CatromWeights((double) (x-x_offset),&cx);
5403 CatromWeights((double) (y-y_offset),&cy);
cristyfb122372012-10-17 23:31:21 +00005404 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*pixels[1].red+cx[2]*
5405 pixels[2].red+cx[3]*pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
5406 pixels[5].red+cx[2]*pixels[6].red+cx[3]*pixels[7].red)+cy[2]*(cx[0]*
5407 pixels[8].red+cx[1]*pixels[9].red+cx[2]*pixels[10].red+cx[3]*
5408 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*pixels[13].red+cx[2]*
5409 pixels[14].red+cx[3]*pixels[15].red));
5410 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*pixels[1].green+cx[2]*
5411 pixels[2].green+cx[3]*pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+
5412 cx[1]*pixels[5].green+cx[2]*pixels[6].green+cx[3]*pixels[7].green)+
5413 cy[2]*(cx[0]*pixels[8].green+cx[1]*pixels[9].green+cx[2]*
5414 pixels[10].green+cx[3]*pixels[11].green)+cy[3]*(cx[0]*
5415 pixels[12].green+cx[1]*pixels[13].green+cx[2]*pixels[14].green+cx[3]*
5416 pixels[15].green));
5417 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*pixels[1].blue+cx[2]*
5418 pixels[2].blue+cx[3]*pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]*
5419 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*pixels[7].blue)+cy[2]*(cx[0]*
5420 pixels[8].blue+cx[1]*pixels[9].blue+cx[2]*pixels[10].blue+cx[3]*
5421 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*pixels[13].blue+
5422 cx[2]*pixels[14].blue+cx[3]*pixels[15].blue));
cristy380a11c2012-06-02 15:15:22 +00005423 if (image->colorspace == CMYKColorspace)
cristyfb122372012-10-17 23:31:21 +00005424 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*pixels[1].black+cx[2]*
5425 pixels[2].black+cx[3]*pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+
5426 cx[1]*pixels[5].black+cx[2]*pixels[6].black+cx[3]*pixels[7].black)+
5427 cy[2]*(cx[0]*pixels[8].black+cx[1]*pixels[9].black+cx[2]*
5428 pixels[10].black+cx[3]*pixels[11].black)+cy[3]*(cx[0]*
5429 pixels[12].black+cx[1]*pixels[13].black+cx[2]*pixels[14].black+cx[3]*
5430 pixels[15].black));
5431 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*pixels[1].alpha+cx[2]*
5432 pixels[2].alpha+cx[3]*pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+
5433 cx[1]*pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*pixels[7].alpha)+
5434 cy[2]*(cx[0]*pixels[8].alpha+cx[1]*pixels[9].alpha+cx[2]*
5435 pixels[10].alpha+cx[3]*pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+
5436 cx[1]*pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha));
cristy4c08aed2011-07-01 19:47:50 +00005437 break;
5438 }
anthonycf4e33d2012-06-08 07:33:23 +00005439#if 0
nicolas20075dc2012-06-12 20:47:38 +00005440 /* deprecated useless and very slow interpolator */
cristy4c08aed2011-07-01 19:47:50 +00005441 case FilterInterpolatePixel:
5442 {
5443 CacheView
5444 *filter_view;
5445
5446 Image
5447 *excerpt_image,
5448 *filter_image;
5449
5450 RectangleInfo
5451 geometry;
5452
5453 geometry.width=4L;
5454 geometry.height=4L;
5455 geometry.x=x_offset-1;
5456 geometry.y=y_offset-1;
5457 excerpt_image=ExcerptImage(image,&geometry,exception);
5458 if (excerpt_image == (Image *) NULL)
5459 {
5460 status=MagickFalse;
5461 break;
5462 }
cristyaa2c16c2012-03-25 22:21:35 +00005463 filter_image=ResizeImage(excerpt_image,1,1,image->filter,exception);
cristy4c08aed2011-07-01 19:47:50 +00005464 excerpt_image=DestroyImage(excerpt_image);
5465 if (filter_image == (Image *) NULL)
5466 break;
cristy46ff2672012-12-14 15:32:26 +00005467 filter_view=AcquireVirtualCacheView(filter_image,exception);
cristy4c08aed2011-07-01 19:47:50 +00005468 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
5469 if (p != (const Quantum *) NULL)
cristy803640d2011-11-17 02:11:32 +00005470 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005471 filter_view=DestroyCacheView(filter_view);
5472 filter_image=DestroyImage(filter_image);
5473 break;
5474 }
anthonycf4e33d2012-06-08 07:33:23 +00005475#endif
cristy4c08aed2011-07-01 19:47:50 +00005476 case IntegerInterpolatePixel:
5477 {
5478 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
5479 if (p == (const Quantum *) NULL)
5480 {
5481 status=MagickFalse;
5482 break;
5483 }
cristy803640d2011-11-17 02:11:32 +00005484 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005485 break;
5486 }
5487 case MeshInterpolatePixel:
5488 {
5489 PointInfo
5490 delta,
5491 luminance;
5492
cristy94ea1632011-07-30 20:40:25 +00005493 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
cristy4c08aed2011-07-01 19:47:50 +00005494 if (p == (const Quantum *) NULL)
5495 {
5496 status=MagickFalse;
5497 break;
5498 }
cristy94ea1632011-07-30 20:40:25 +00005499 delta.x=x-x_offset;
5500 delta.y=y-y_offset;
cristy884f6002011-07-31 00:51:45 +00005501 luminance.x=GetPixelLuminance(image,p)-(double)
cristy94ea1632011-07-30 20:40:25 +00005502 GetPixelLuminance(image,p+3*GetPixelChannels(image));
cristy28474bf2011-09-11 23:32:52 +00005503 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
cristy94ea1632011-07-30 20:40:25 +00005504 GetPixelLuminance(image,p+2*GetPixelChannels(image));
cristy5ce8df82011-07-07 14:52:23 +00005505 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005506 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005507 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5508 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
cristy4c08aed2011-07-01 19:47:50 +00005509 if (fabs(luminance.x) < fabs(luminance.y))
5510 {
5511 /*
5512 Diagonal 0-3 NW-SE.
5513 */
5514 if (delta.x <= delta.y)
5515 {
5516 /*
cristy94ea1632011-07-30 20:40:25 +00005517 Bottom-left triangle (pixel: 2, diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005518 */
5519 delta.y=1.0-delta.y;
5520 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
cristy3e3ec3a2012-11-03 23:11:06 +00005521 gamma=PerceptibleReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005522 pixel->red=gamma*MeshInterpolate(&delta,pixels[2].red,
5523 pixels[3].red,pixels[0].red);
5524 pixel->green=gamma*MeshInterpolate(&delta,pixels[2].green,
5525 pixels[3].green,pixels[0].green);
5526 pixel->blue=gamma*MeshInterpolate(&delta,pixels[2].blue,
5527 pixels[3].blue,pixels[0].blue);
cristy4c08aed2011-07-01 19:47:50 +00005528 if (image->colorspace == CMYKColorspace)
5529 pixel->black=gamma*MeshInterpolate(&delta,pixels[2].black,
5530 pixels[3].black,pixels[0].black);
cristy94ea1632011-07-30 20:40:25 +00005531 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005532 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[2].alpha,
5533 pixels[3].alpha,pixels[0].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005534 }
5535 else
5536 {
5537 /*
cristy94ea1632011-07-30 20:40:25 +00005538 Top-right triangle (pixel:1 , diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005539 */
5540 delta.x=1.0-delta.x;
5541 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
cristy3e3ec3a2012-11-03 23:11:06 +00005542 gamma=PerceptibleReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005543 pixel->red=gamma*MeshInterpolate(&delta,pixels[1].red,
5544 pixels[0].red,pixels[3].red);
5545 pixel->green=gamma*MeshInterpolate(&delta,pixels[1].green,
5546 pixels[0].green,pixels[3].green);
5547 pixel->blue=gamma*MeshInterpolate(&delta,pixels[1].blue,
5548 pixels[0].blue,pixels[3].blue);
cristy4c08aed2011-07-01 19:47:50 +00005549 if (image->colorspace == CMYKColorspace)
5550 pixel->black=gamma*MeshInterpolate(&delta,pixels[1].black,
5551 pixels[0].black,pixels[3].black);
cristy94ea1632011-07-30 20:40:25 +00005552 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005553 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[1].alpha,
5554 pixels[0].alpha,pixels[3].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005555 }
5556 }
5557 else
5558 {
5559 /*
5560 Diagonal 1-2 NE-SW.
5561 */
5562 if (delta.x <= (1.0-delta.y))
5563 {
5564 /*
cristy94ea1632011-07-30 20:40:25 +00005565 Top-left triangle (pixel: 0, diagonal: 1-2).
cristy4c08aed2011-07-01 19:47:50 +00005566 */
5567 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
cristy3e3ec3a2012-11-03 23:11:06 +00005568 gamma=PerceptibleReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005569 pixel->red=gamma*MeshInterpolate(&delta,pixels[0].red,
5570 pixels[1].red,pixels[2].red);
5571 pixel->green=gamma*MeshInterpolate(&delta,pixels[0].green,
5572 pixels[1].green,pixels[2].green);
5573 pixel->blue=gamma*MeshInterpolate(&delta,pixels[0].blue,
5574 pixels[1].blue,pixels[2].blue);
cristy4c08aed2011-07-01 19:47:50 +00005575 if (image->colorspace == CMYKColorspace)
5576 pixel->black=gamma*MeshInterpolate(&delta,pixels[0].black,
5577 pixels[1].black,pixels[2].black);
cristy94ea1632011-07-30 20:40:25 +00005578 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005579 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[0].alpha,
5580 pixels[1].alpha,pixels[2].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005581 }
5582 else
5583 {
5584 /*
5585 Bottom-right triangle (pixel: 3, diagonal: 1-2).
5586 */
5587 delta.x=1.0-delta.x;
5588 delta.y=1.0-delta.y;
5589 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
cristy3e3ec3a2012-11-03 23:11:06 +00005590 gamma=PerceptibleReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005591 pixel->red=gamma*MeshInterpolate(&delta,pixels[3].red,
5592 pixels[2].red,pixels[1].red);
5593 pixel->green=gamma*MeshInterpolate(&delta,pixels[3].green,
5594 pixels[2].green,pixels[1].green);
5595 pixel->blue=gamma*MeshInterpolate(&delta,pixels[3].blue,
5596 pixels[2].blue,pixels[1].blue);
cristy4c08aed2011-07-01 19:47:50 +00005597 if (image->colorspace == CMYKColorspace)
5598 pixel->black=gamma*MeshInterpolate(&delta,pixels[3].black,
5599 pixels[2].black,pixels[1].black);
cristy94ea1632011-07-30 20:40:25 +00005600 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005601 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[3].alpha,
5602 pixels[2].alpha,pixels[1].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005603 }
5604 }
5605 break;
5606 }
anthonycf4e33d2012-06-08 07:33:23 +00005607 case NearestInterpolatePixel:
cristy4c08aed2011-07-01 19:47:50 +00005608 {
anthonycf4e33d2012-06-08 07:33:23 +00005609 x_offset=(ssize_t) floor(x+0.5);
5610 y_offset=(ssize_t) floor(y+0.5);
5611 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00005612 if (p == (const Quantum *) NULL)
5613 {
5614 status=MagickFalse;
5615 break;
5616 }
cristy803640d2011-11-17 02:11:32 +00005617 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005618 break;
5619 }
5620 case SplineInterpolatePixel:
5621 {
cristya19f1d72012-08-07 18:24:38 +00005622 double
nicolasd32d5e52012-06-12 15:34:10 +00005623 cx[4],
5624 cy[4];
cristy4c08aed2011-07-01 19:47:50 +00005625
5626 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5627 exception);
5628 if (p == (const Quantum *) NULL)
5629 {
5630 status=MagickFalse;
5631 break;
5632 }
anthonycf4e33d2012-06-08 07:33:23 +00005633 for (i=0; i < 16L; i++)
5634 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
cristya19f1d72012-08-07 18:24:38 +00005635 SplineWeights((double) (x-x_offset),&cx);
5636 SplineWeights((double) (y-y_offset),&cy);
cristyfb122372012-10-17 23:31:21 +00005637 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*pixels[1].red+cx[2]*
5638 pixels[2].red+cx[3]*pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
5639 pixels[5].red+cx[2]*pixels[6].red+cx[3]*pixels[7].red)+cy[2]*(cx[0]*
5640 pixels[8].red+cx[1]*pixels[9].red+cx[2]*pixels[10].red+cx[3]*
5641 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*pixels[13].red+cx[2]*
5642 pixels[14].red+cx[3]*pixels[15].red));
5643 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*pixels[1].green+cx[2]*
5644 pixels[2].green+cx[3]*pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+
5645 cx[1]*pixels[5].green+cx[2]*pixels[6].green+cx[3]*pixels[7].green)+
5646 cy[2]*(cx[0]*pixels[8].green+cx[1]*pixels[9].green+cx[2]*
5647 pixels[10].green+cx[3]*pixels[11].green)+cy[3]*(cx[0]*pixels[12].green+
5648 cx[1]*pixels[13].green+cx[2]*pixels[14].green+cx[3]*pixels[15].green));
5649 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*pixels[1].blue+cx[2]*
5650 pixels[2].blue+cx[3]*pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]*
5651 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*pixels[7].blue)+cy[2]*(cx[0]*
5652 pixels[8].blue+cx[1]*pixels[9].blue+cx[2]*pixels[10].blue+cx[3]*
5653 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*pixels[13].blue+
5654 cx[2]*pixels[14].blue+cx[3]*pixels[15].blue));
nicolasd32d5e52012-06-12 15:34:10 +00005655 if (image->colorspace == CMYKColorspace)
cristyfb122372012-10-17 23:31:21 +00005656 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*pixels[1].black+cx[2]*
5657 pixels[2].black+cx[3]*pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+
5658 cx[1]*pixels[5].black+cx[2]*pixels[6].black+cx[3]*pixels[7].black)+
5659 cy[2]*(cx[0]*pixels[8].black+cx[1]*pixels[9].black+cx[2]*
5660 pixels[10].black+cx[3]*pixels[11].black)+cy[3]*(cx[0]*
5661 pixels[12].black+cx[1]*pixels[13].black+cx[2]*pixels[14].black+cx[3]*
5662 pixels[15].black));
5663 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*pixels[1].alpha+cx[2]*
5664 pixels[2].alpha+cx[3]*pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+
5665 cx[1]*pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*pixels[7].alpha)+
5666 cy[2]*(cx[0]*pixels[8].alpha+cx[1]*pixels[9].alpha+cx[2]*
5667 pixels[10].alpha+cx[3]*pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+
5668 cx[1]*pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha));
cristy4c08aed2011-07-01 19:47:50 +00005669 break;
5670 }
5671 }
5672 return(status);
5673}
5674
5675/*
5676%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5677% %
5678% %
5679% %
5680+ I s F u z z y E q u i v a l e n c e P i x e l %
5681% %
5682% %
5683% %
5684%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5685%
5686% IsFuzzyEquivalencePixel() returns MagickTrue if the distance between two
5687% pixels is less than the specified distance in a linear three (or four)u
5688% dimensional color space.
5689%
5690% The format of the IsFuzzyEquivalencePixel method is:
5691%
cristye4a40472011-12-22 02:56:19 +00005692% void IsFuzzyEquivalencePixel(const Image *source,const Quantum *p,
5693% const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005694%
5695% A description of each parameter follows:
5696%
cristye4a40472011-12-22 02:56:19 +00005697% o source: the source image.
cristy4c08aed2011-07-01 19:47:50 +00005698%
5699% o p: Pixel p.
5700%
cristye4a40472011-12-22 02:56:19 +00005701% o destination: the destination image.
5702%
cristy4c08aed2011-07-01 19:47:50 +00005703% o q: Pixel q.
5704%
5705*/
cristye4a40472011-12-22 02:56:19 +00005706MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source,
5707 const Quantum *p,const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005708{
cristya19f1d72012-08-07 18:24:38 +00005709 double
cristy4c08aed2011-07-01 19:47:50 +00005710 fuzz,
5711 pixel;
5712
cristya19f1d72012-08-07 18:24:38 +00005713 register double
cristy4c08aed2011-07-01 19:47:50 +00005714 distance,
5715 scale;
5716
cristya19f1d72012-08-07 18:24:38 +00005717 fuzz=MagickMax(source->fuzz,(double) MagickSQ1_2)*MagickMax(
5718 destination->fuzz,(double) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005719 scale=1.0;
5720 distance=0.0;
cristy8a46d822012-08-28 23:32:39 +00005721 if (source->alpha_trait == BlendPixelTrait)
cristy4c08aed2011-07-01 19:47:50 +00005722 {
5723 /*
5724 Transparencies are involved - set alpha distance
5725 */
cristya19f1d72012-08-07 18:24:38 +00005726 pixel=GetPixelAlpha(source,p)-(double)
cristy99abff32011-12-24 20:45:16 +00005727 GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005728 distance=pixel*pixel;
5729 if (distance > fuzz)
5730 return(MagickFalse);
5731 /*
5732 Generate a alpha scaling factor to generate a 4D cone on colorspace
5733 Note that if one color is transparent, distance has no color component.
5734 */
cristye4a40472011-12-22 02:56:19 +00005735 scale=QuantumScale*GetPixelAlpha(source,p);
5736 scale*=QuantumScale*GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005737 if (scale <= MagickEpsilon)
5738 return(MagickTrue);
5739 }
5740 /*
5741 RGB or CMY color cube
5742 */
5743 distance*=3.0; /* rescale appropriately */
5744 fuzz*=3.0;
cristya19f1d72012-08-07 18:24:38 +00005745 pixel=GetPixelRed(source,p)-(double) GetPixelRed(destination,q);
cristye4a40472011-12-22 02:56:19 +00005746 if ((source->colorspace == HSLColorspace) ||
5747 (source->colorspace == HSBColorspace) ||
5748 (source->colorspace == HWBColorspace))
cristy4c08aed2011-07-01 19:47:50 +00005749 {
5750 /*
5751 Compute an arc distance for hue. It should be a vector angle of
5752 'S'/'W' length with 'L'/'B' forming appropriate cones.
5753 */
5754 if (fabs((double) pixel) > (QuantumRange/2))
5755 pixel-=QuantumRange;
5756 pixel*=2;
5757 }
5758 distance+=scale*pixel*pixel;
5759 if (distance > fuzz)
5760 return(MagickFalse);
cristya19f1d72012-08-07 18:24:38 +00005761 pixel=GetPixelGreen(source,p)-(double) GetPixelGreen(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005762 distance+=scale*pixel*pixel;
5763 if (distance > fuzz)
5764 return(MagickFalse);
cristya19f1d72012-08-07 18:24:38 +00005765 pixel=GetPixelBlue(source,p)-(double) GetPixelBlue(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005766 distance+=scale*pixel*pixel;
5767 if (distance > fuzz)
5768 return(MagickFalse);
5769 return(MagickTrue);
5770}
5771
5772/*
5773%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5774% %
5775% %
5776% %
5777+ 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 %
5778% %
5779% %
5780% %
5781%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5782%
5783% IsFuzzyEquivalencePixelInfo() returns true if the distance between two
5784% colors is less than the specified distance in a linear three (or four)
5785% dimensional color space.
5786%
cristy5f95f4f2011-10-23 01:01:01 +00005787% This implements the equivalent of:
5788% fuzz < sqrt(color_distance^2 * u.a*v.a + alpha_distance^2)
cristy4c08aed2011-07-01 19:47:50 +00005789%
5790% Which produces a multi-dimensional cone for that colorspace along the
5791% transparency vector.
5792%
cristy5f95f4f2011-10-23 01:01:01 +00005793% For example for an RGB:
cristy4c08aed2011-07-01 19:47:50 +00005794% color_distance^2 = ( (u.r-v.r)^2 + (u.g-v.g)^2 + (u.b-v.b)^2 ) / 3
5795%
5796% See http://www.imagemagick.org/Usage/bugs/fuzz_distance/
5797%
5798% Hue colorspace distances need more work. Hue is not a distance, it is an
5799% angle!
5800%
5801% A check that q is in the same color space as p should be made and the
5802% appropriate mapping made. -- Anthony Thyssen 8 December 2010
5803%
5804% The format of the IsFuzzyEquivalencePixelInfo method is:
5805%
5806% MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5807% const PixelInfo *q)
5808%
5809% A description of each parameter follows:
5810%
5811% o p: Pixel p.
5812%
5813% o q: Pixel q.
5814%
5815*/
5816MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5817 const PixelInfo *q)
5818{
cristya19f1d72012-08-07 18:24:38 +00005819 double
cristy4c08aed2011-07-01 19:47:50 +00005820 fuzz,
5821 pixel;
5822
cristya19f1d72012-08-07 18:24:38 +00005823 register double
cristy4c08aed2011-07-01 19:47:50 +00005824 scale,
5825 distance;
5826
5827 if ((p->fuzz == 0.0) && (q->fuzz == 0.0))
5828 return(IsPixelInfoEquivalent(p,q));
5829 if (p->fuzz == 0.0)
cristya19f1d72012-08-07 18:24:38 +00005830 fuzz=MagickMax(q->fuzz,(double) MagickSQ1_2)*MagickMax(q->fuzz,
5831 (double) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005832 else if (q->fuzz == 0.0)
cristya19f1d72012-08-07 18:24:38 +00005833 fuzz=MagickMax(p->fuzz,(double) MagickSQ1_2)*MagickMax(p->fuzz,
5834 (double) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005835 else
cristya19f1d72012-08-07 18:24:38 +00005836 fuzz=MagickMax(p->fuzz,(double) MagickSQ1_2)*MagickMax(q->fuzz,
5837 (double) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005838 scale=1.0;
5839 distance=0.0;
cristy8a46d822012-08-28 23:32:39 +00005840 if ((p->alpha_trait == BlendPixelTrait) || (q->alpha_trait == BlendPixelTrait))
cristy4c08aed2011-07-01 19:47:50 +00005841 {
5842 /*
5843 Transparencies are involved - set alpha distance.
5844 */
cristy8a46d822012-08-28 23:32:39 +00005845 pixel=(p->alpha_trait == BlendPixelTrait ? p->alpha : OpaqueAlpha)-
5846 (q->alpha_trait == BlendPixelTrait ? q->alpha : OpaqueAlpha);
cristy4c08aed2011-07-01 19:47:50 +00005847 distance=pixel*pixel;
5848 if (distance > fuzz)
5849 return(MagickFalse);
5850 /*
5851 Generate a alpha scaling factor to generate a 4D cone on colorspace.
cristy5f95f4f2011-10-23 01:01:01 +00005852 If one color is transparent, distance has no color component.
cristy4c08aed2011-07-01 19:47:50 +00005853 */
cristy8a46d822012-08-28 23:32:39 +00005854 if (p->alpha_trait == BlendPixelTrait)
cristy4c08aed2011-07-01 19:47:50 +00005855 scale=(QuantumScale*p->alpha);
cristy8a46d822012-08-28 23:32:39 +00005856 if (q->alpha_trait == BlendPixelTrait)
cristy4c08aed2011-07-01 19:47:50 +00005857 scale*=(QuantumScale*q->alpha);
5858 if (scale <= MagickEpsilon )
5859 return(MagickTrue);
5860 }
5861 /*
5862 CMYK create a CMY cube with a multi-dimensional cone toward black.
5863 */
5864 if (p->colorspace == CMYKColorspace)
5865 {
5866 pixel=p->black-q->black;
5867 distance+=pixel*pixel*scale;
5868 if (distance > fuzz)
5869 return(MagickFalse);
cristya19f1d72012-08-07 18:24:38 +00005870 scale*=(double) (QuantumScale*(QuantumRange-p->black));
5871 scale*=(double) (QuantumScale*(QuantumRange-q->black));
cristy4c08aed2011-07-01 19:47:50 +00005872 }
5873 /*
5874 RGB or CMY color cube.
5875 */
5876 distance*=3.0; /* rescale appropriately */
5877 fuzz*=3.0;
5878 pixel=p->red-q->red;
5879 if ((p->colorspace == HSLColorspace) || (p->colorspace == HSBColorspace) ||
5880 (p->colorspace == HWBColorspace))
5881 {
cristy5f95f4f2011-10-23 01:01:01 +00005882 /*
5883 This calculates a arc distance for hue-- it should be a vector angle
5884 of 'S'/'W' length with 'L'/'B' forming appropriate cones. In other
5885 words this is a hack - Anthony.
cristy4c08aed2011-07-01 19:47:50 +00005886 */
5887 if (fabs((double) pixel) > (QuantumRange/2))
5888 pixel-=QuantumRange;
5889 pixel*=2;
5890 }
5891 distance+=pixel*pixel*scale;
5892 if (distance > fuzz)
5893 return(MagickFalse);
5894 pixel=p->green-q->green;
5895 distance+=pixel*pixel*scale;
5896 if (distance > fuzz)
5897 return(MagickFalse);
5898 pixel=p->blue-q->blue;
5899 distance+=pixel*pixel*scale;
5900 if (distance > fuzz)
5901 return(MagickFalse);
5902 return(MagickTrue);
5903}
5904
5905/*
5906%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5907% %
5908% %
5909% %
cristye2a912b2011-12-05 20:02:07 +00005910% S e t P i x e l C h a n n e l M a p M a s k %
cristy2b9582a2011-07-04 17:38:56 +00005911% %
5912% %
5913% %
5914%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5915%
cristycf1296e2012-08-26 23:40:49 +00005916% SetPixelChannelMask() sets the pixel channel map from the specified
cristye2a912b2011-12-05 20:02:07 +00005917% channel mask.
cristy2b9582a2011-07-04 17:38:56 +00005918%
cristycf1296e2012-08-26 23:40:49 +00005919% The format of the SetPixelChannelMask method is:
cristy2b9582a2011-07-04 17:38:56 +00005920%
cristycf1296e2012-08-26 23:40:49 +00005921% void SetPixelChannelMask(Image *image,const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005922%
5923% A description of each parameter follows:
5924%
5925% o image: the image.
5926%
cristydfdb19e2012-03-21 22:22:24 +00005927% o channel_mask: the channel mask.
cristy2b9582a2011-07-04 17:38:56 +00005928%
5929*/
cristycf1296e2012-08-26 23:40:49 +00005930MagickExport void SetPixelChannelMask(Image *image,
cristy07a67852011-08-26 13:25:03 +00005931 const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005932{
cristy6a917d62011-08-24 17:31:30 +00005933#define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01)
cristydafd2872011-07-24 22:06:13 +00005934
cristy2b9582a2011-07-04 17:38:56 +00005935 register ssize_t
5936 i;
5937
cristy177e41c2012-04-15 15:08:25 +00005938 if (image->debug != MagickFalse)
5939 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%08x]", \
5940 image->filename,channel_mask); \
cristy3c309812011-11-08 02:40:43 +00005941 image->channel_mask=channel_mask;
cristydafd2872011-07-24 22:06:13 +00005942 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
cristye2a912b2011-12-05 20:02:07 +00005943 {
5944 PixelChannel
5945 channel;
5946
cristycf1296e2012-08-26 23:40:49 +00005947 channel=GetPixelChannelChannel(image,i);
cristy297e3a42012-08-26 21:27:29 +00005948 SetPixelChannelTraits(image,channel,
cristye2a912b2011-12-05 20:02:07 +00005949 GetChannelBit(channel_mask,channel) == 0 ? CopyPixelTrait :
cristy8a46d822012-08-28 23:32:39 +00005950 image->alpha_trait != BlendPixelTrait || (channel == AlphaPixelChannel) ?
5951 UpdatePixelTrait : (PixelTrait) (UpdatePixelTrait | image->alpha_trait));
cristye2a912b2011-12-05 20:02:07 +00005952 }
cristy1685e722011-09-06 00:04:19 +00005953 if (image->storage_class == PseudoClass)
cristy297e3a42012-08-26 21:27:29 +00005954 SetPixelChannelTraits(image,IndexPixelChannel,CopyPixelTrait);
cristy183a5c72012-01-30 01:40:35 +00005955 if (image->mask != MagickFalse)
cristy297e3a42012-08-26 21:27:29 +00005956 SetPixelChannelTraits(image,MaskPixelChannel,CopyPixelTrait);
cristy6dcb9b82011-10-23 23:21:25 +00005957 if (image->debug != MagickFalse)
5958 LogPixelChannels(image);
cristy2b9582a2011-07-04 17:38:56 +00005959}
5960
5961/*
5962%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5963% %
5964% %
5965% %
cristy322d07d2012-03-18 21:17:23 +00005966% S e t P i x e l M e t a C h a n n e l s %
5967% %
5968% %
5969% %
5970%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5971%
5972% SetPixelMetaChannels() sets the image meta channels.
5973%
5974% The format of the SetPixelMetaChannels method is:
5975%
5976% MagickBooleanType SetPixelMetaChannels(Image *image,
5977% const size_t number_meta_channels,ExceptionInfo *exception)
5978%
5979% A description of each parameter follows:
5980%
5981% o image: the image.
5982%
5983% o number_meta_channels: the number of meta channels.
5984%
5985% o exception: return any errors or warnings in this structure.
5986%
5987*/
5988MagickExport MagickBooleanType SetPixelMetaChannels(Image *image,
5989 const size_t number_meta_channels,ExceptionInfo *exception)
5990{
5991 image->number_meta_channels=number_meta_channels;
5992 return(SyncImagePixelCache(image,exception));
5993}