blob: e1dcc4b2af9947a9480cdfd4389686f4111a2e4e [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% %
cristy1454be72011-12-19 01:52:48 +000019% Copyright 1999-2012 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"
62#include "MagickCore/quantum.h"
63#include "MagickCore/quantum-private.h"
64#include "MagickCore/resource_.h"
65#include "MagickCore/semaphore.h"
66#include "MagickCore/statistic.h"
67#include "MagickCore/stream.h"
68#include "MagickCore/string_.h"
69#include "MagickCore/transform.h"
70#include "MagickCore/utility.h"
71
cristy146a62b2011-10-23 23:40:46 +000072#define LogPixelChannels(image) \
73{ \
74 register ssize_t \
75 i; \
76 \
77 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%.20g]", \
78 image->filename,(double) image->number_channels); \
79 for (i=0; i < (ssize_t) image->number_channels; i++) \
80 { \
81 char \
82 traits[MaxTextExtent]; \
83 \
84 const char \
cristy46795722011-12-10 23:56:57 +000085 *name; \
86 \
87 PixelChannel \
88 channel; \
cristy146a62b2011-10-23 23:40:46 +000089 \
cristye2a912b2011-12-05 20:02:07 +000090 switch (GetPixelChannelMapChannel(image,i)) \
cristy146a62b2011-10-23 23:40:46 +000091 { \
92 case RedPixelChannel: \
93 { \
cristy46795722011-12-10 23:56:57 +000094 name="red"; \
cristy146a62b2011-10-23 23:40:46 +000095 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +000096 name="cyan"; \
cristy146a62b2011-10-23 23:40:46 +000097 if (image->colorspace == GRAYColorspace) \
cristy46795722011-12-10 23:56:57 +000098 name="gray"; \
cristy146a62b2011-10-23 23:40:46 +000099 break; \
100 } \
101 case GreenPixelChannel: \
102 { \
cristy46795722011-12-10 23:56:57 +0000103 name="green"; \
cristy146a62b2011-10-23 23:40:46 +0000104 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +0000105 name="magenta"; \
cristy146a62b2011-10-23 23:40:46 +0000106 break; \
107 } \
108 case BluePixelChannel: \
109 { \
cristy46795722011-12-10 23:56:57 +0000110 name="blue"; \
cristy146a62b2011-10-23 23:40:46 +0000111 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +0000112 name="yellow"; \
cristy146a62b2011-10-23 23:40:46 +0000113 break; \
114 } \
115 case BlackPixelChannel: \
116 { \
cristy46795722011-12-10 23:56:57 +0000117 name="black"; \
cristy146a62b2011-10-23 23:40:46 +0000118 if (image->storage_class == PseudoClass) \
cristy46795722011-12-10 23:56:57 +0000119 name="index"; \
cristy146a62b2011-10-23 23:40:46 +0000120 break; \
121 } \
cristye2a912b2011-12-05 20:02:07 +0000122 case IndexPixelChannel: \
123 { \
cristy46795722011-12-10 23:56:57 +0000124 name="index"; \
cristye2a912b2011-12-05 20:02:07 +0000125 break; \
126 } \
cristy146a62b2011-10-23 23:40:46 +0000127 case AlphaPixelChannel: \
128 { \
cristy46795722011-12-10 23:56:57 +0000129 name="alpha"; \
cristy146a62b2011-10-23 23:40:46 +0000130 break; \
131 } \
132 case MaskPixelChannel: \
133 { \
cristy46795722011-12-10 23:56:57 +0000134 name="mask"; \
cristy146a62b2011-10-23 23:40:46 +0000135 break; \
136 } \
cristye2a912b2011-12-05 20:02:07 +0000137 case MetaPixelChannel: \
cristy146a62b2011-10-23 23:40:46 +0000138 { \
cristy46795722011-12-10 23:56:57 +0000139 name="meta"; \
cristye2a912b2011-12-05 20:02:07 +0000140 break; \
cristy146a62b2011-10-23 23:40:46 +0000141 } \
cristye2a912b2011-12-05 20:02:07 +0000142 default: \
cristy46795722011-12-10 23:56:57 +0000143 name="undefined"; \
cristy146a62b2011-10-23 23:40:46 +0000144 } \
cristy46795722011-12-10 23:56:57 +0000145 channel=GetPixelChannelMapChannel(image,i); \
cristy146a62b2011-10-23 23:40:46 +0000146 *traits='\0'; \
cristy46795722011-12-10 23:56:57 +0000147 if ((GetPixelChannelMapTraits(image,channel) & UpdatePixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000148 (void) ConcatenateMagickString(traits,"update,",MaxTextExtent); \
cristy46795722011-12-10 23:56:57 +0000149 if ((GetPixelChannelMapTraits(image,channel) & BlendPixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000150 (void) ConcatenateMagickString(traits,"blend,",MaxTextExtent); \
cristy46795722011-12-10 23:56:57 +0000151 if ((GetPixelChannelMapTraits(image,channel) & CopyPixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000152 (void) ConcatenateMagickString(traits,"copy,",MaxTextExtent); \
153 if (*traits == '\0') \
154 (void) ConcatenateMagickString(traits,"undefined,",MaxTextExtent); \
155 traits[strlen(traits)-1]='\0'; \
156 (void) LogMagickEvent(PixelEvent,GetMagickModule()," %.20g: %s (%s)", \
cristy46795722011-12-10 23:56:57 +0000157 (double) i,name,traits); \
cristy146a62b2011-10-23 23:40:46 +0000158 } \
159}
160
161/*
cristy4c08aed2011-07-01 19:47:50 +0000162%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
163% %
164% %
165% %
cristyed231572011-07-14 02:18:59 +0000166+ 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 +0000167% %
168% %
169% %
170%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
171%
cristyed231572011-07-14 02:18:59 +0000172% AcquirePixelChannelMap() acquires a pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000173%
cristyed231572011-07-14 02:18:59 +0000174% The format of the AcquirePixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000175%
cristybd5a96c2011-08-21 00:04:26 +0000176% PixelChannelMap *AcquirePixelChannelMap(void)
cristy4c08aed2011-07-01 19:47:50 +0000177%
178*/
cristybd5a96c2011-08-21 00:04:26 +0000179MagickExport PixelChannelMap *AcquirePixelChannelMap(void)
cristy4c08aed2011-07-01 19:47:50 +0000180{
cristyed231572011-07-14 02:18:59 +0000181 PixelChannelMap
cristybd5a96c2011-08-21 00:04:26 +0000182 *channel_map;
cristy4c08aed2011-07-01 19:47:50 +0000183
184 register ssize_t
185 i;
186
cristybd5a96c2011-08-21 00:04:26 +0000187 channel_map=(PixelChannelMap *) AcquireQuantumMemory(MaxPixelChannels,
188 sizeof(*channel_map));
189 if (channel_map == (PixelChannelMap *) NULL)
cristy4c08aed2011-07-01 19:47:50 +0000190 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristybd5a96c2011-08-21 00:04:26 +0000191 (void) ResetMagickMemory(channel_map,0,MaxPixelChannels*sizeof(*channel_map));
192 for (i=0; i < MaxPixelChannels; i++)
193 channel_map[i].channel=(PixelChannel) i;
cristyed231572011-07-14 02:18:59 +0000194 return(channel_map);
cristy4c08aed2011-07-01 19:47:50 +0000195}
196
197/*
198%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
199% %
200% %
201% %
cristyed231572011-07-14 02:18:59 +0000202+ 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 +0000203% %
204% %
205% %
206%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
207%
cristyed231572011-07-14 02:18:59 +0000208% ClonePixelChannelMap() clones a pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000209%
cristyed231572011-07-14 02:18:59 +0000210% The format of the ClonePixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000211%
cristybd5a96c2011-08-21 00:04:26 +0000212% PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000213%
214% A description of each parameter follows:
215%
cristyed231572011-07-14 02:18:59 +0000216% o channel_map: the pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000217%
218*/
cristybd5a96c2011-08-21 00:04:26 +0000219MagickExport PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000220{
cristyed231572011-07-14 02:18:59 +0000221 PixelChannelMap
cristybd5a96c2011-08-21 00:04:26 +0000222 *clone_map;
cristy4c08aed2011-07-01 19:47:50 +0000223
cristybd5a96c2011-08-21 00:04:26 +0000224 assert(channel_map != (PixelChannelMap *) NULL);
cristyed231572011-07-14 02:18:59 +0000225 clone_map=AcquirePixelChannelMap();
cristybd5a96c2011-08-21 00:04:26 +0000226 if (clone_map == (PixelChannelMap *) NULL)
227 return((PixelChannelMap *) NULL);
228 (void) CopyMagickMemory(clone_map,channel_map,MaxPixelChannels*
229 sizeof(*channel_map));
cristy4c08aed2011-07-01 19:47:50 +0000230 return(clone_map);
231}
232
233/*
234%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235% %
236% %
237% %
238+ C l o n e P i x e l I n f o %
239% %
240% %
241% %
242%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
243%
244% ClonePixelInfo() makes a duplicate of the given pixel info structure, or if
245% pixel info is NULL, a new one.
246%
247% The format of the ClonePixelInfo method is:
248%
249% PixelInfo *ClonePixelInfo(const PixelInfo *pixel_info)
250%
251% A description of each parameter follows:
252%
253% o pixel_info: the pixel info.
254%
255*/
256MagickExport PixelInfo *ClonePixelInfo(const PixelInfo *pixel)
257{
258 PixelInfo
259 *pixel_info;
260
cristya64b85d2011-09-14 01:02:31 +0000261 pixel_info=(PixelInfo *) AcquireQuantumMemory(1,sizeof(*pixel_info));
cristy4c08aed2011-07-01 19:47:50 +0000262 if (pixel_info == (PixelInfo *) NULL)
263 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
264 *pixel_info=(*pixel);
265 return(pixel_info);
266}
267
268/*
269%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
270% %
271% %
272% %
cristyed231572011-07-14 02:18:59 +0000273+ 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 +0000274% %
275% %
276% %
277%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
278%
cristyed231572011-07-14 02:18:59 +0000279% DestroyPixelChannelMap() deallocates memory associated with the pixel
280% channel map.
cristy4c08aed2011-07-01 19:47:50 +0000281%
cristyed231572011-07-14 02:18:59 +0000282% The format of the DestroyPixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000283%
cristybd5a96c2011-08-21 00:04:26 +0000284% PixelChannelMap *DestroyPixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000285%
286% A description of each parameter follows:
287%
cristyed231572011-07-14 02:18:59 +0000288% o channel_map: the pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000289%
290*/
cristybd5a96c2011-08-21 00:04:26 +0000291MagickExport PixelChannelMap *DestroyPixelChannelMap(
292 PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000293{
cristybd5a96c2011-08-21 00:04:26 +0000294 assert(channel_map != (PixelChannelMap *) NULL);
295 channel_map=(PixelChannelMap *) RelinquishMagickMemory(channel_map);
296 return((PixelChannelMap *) RelinquishMagickMemory(channel_map));
cristy4c08aed2011-07-01 19:47:50 +0000297}
298
299/*
300%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
301% %
302% %
303% %
304% E x p o r t I m a g e P i x e l s %
305% %
306% %
307% %
308%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
309%
310% ExportImagePixels() extracts pixel data from an image and returns it to you.
311% The method returns MagickTrue on success otherwise MagickFalse if an error is
cristyb5a45a32012-01-10 13:31:13 +0000312% encountered. The data is returned as char, short int, Quantum, unsigned int,
cristycafe0412012-01-10 13:29:58 +0000313% unsigned long long, float, or double in the order specified by map.
cristy4c08aed2011-07-01 19:47:50 +0000314%
315% Suppose you want to extract the first scanline of a 640x480 image as
316% character data in red-green-blue order:
317%
318% ExportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels,exception);
319%
320% The format of the ExportImagePixels method is:
321%
cristycafe0412012-01-10 13:29:58 +0000322% MagickBooleanType ExportImagePixels(const Image *image,const ssize_t x,
323% const ssize_t y,const size_t width,const size_t height,
324% const char *map,const StorageType type,void *pixels,
cristy46f4be22012-01-07 00:26:39 +0000325% ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +0000326%
327% A description of each parameter follows:
328%
329% o image: the image.
330%
cristycafe0412012-01-10 13:29:58 +0000331% o x,y,width,height: These values define the perimeter
cristy4c08aed2011-07-01 19:47:50 +0000332% of a region of pixels you want to extract.
333%
334% o map: This string reflects the expected ordering of the pixel array.
335% It can be any combination or order of R = red, G = green, B = blue,
336% A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
337% Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
338% P = pad.
339%
340% o type: Define the data type of the pixels. Float and double types are
341% normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
cristy6c9e1682012-01-07 21:37:44 +0000342% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
cristyff6834e2012-01-10 03:00:25 +0000343% LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
cristy6c9e1682012-01-07 21:37:44 +0000344% QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
cristy4c08aed2011-07-01 19:47:50 +0000345%
346% o pixels: This array of values contain the pixel components as defined by
347% map and type. You must preallocate this array where the expected
348% length varies depending on the values of width, height, map, and type.
349%
350% o exception: return any errors or warnings in this structure.
351%
352*/
cristye5370942012-01-06 03:49:31 +0000353
cristycafe0412012-01-10 13:29:58 +0000354static void ExportCharPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000355 const char *restrict map,const QuantumType *quantum_map,void *pixels,
356 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000357{
358 register const Quantum
359 *restrict p;
360
361 register ssize_t
362 x;
363
364 register unsigned char
cristy3fe11452012-01-09 01:27:42 +0000365 *restrict q;
cristye5370942012-01-06 03:49:31 +0000366
367 ssize_t
368 y;
369
cristy46f4be22012-01-07 00:26:39 +0000370 q=(unsigned char *) pixels;
cristye5370942012-01-06 03:49:31 +0000371 if (LocaleCompare(map,"BGR") == 0)
372 {
cristycafe0412012-01-10 13:29:58 +0000373 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000374 {
cristycafe0412012-01-10 13:29:58 +0000375 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000376 if (p == (const Quantum *) NULL)
377 break;
cristycafe0412012-01-10 13:29:58 +0000378 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000379 {
380 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
381 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
382 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
383 p+=GetPixelChannels(image);
384 }
385 }
386 return;
387 }
388 if (LocaleCompare(map,"BGRA") == 0)
389 {
cristycafe0412012-01-10 13:29:58 +0000390 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000391 {
cristycafe0412012-01-10 13:29:58 +0000392 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000393 if (p == (const Quantum *) NULL)
394 break;
cristycafe0412012-01-10 13:29:58 +0000395 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000396 {
397 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
398 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
399 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
400 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
401 p+=GetPixelChannels(image);
402 }
403 }
404 return;
405 }
406 if (LocaleCompare(map,"BGRP") == 0)
407 {
cristycafe0412012-01-10 13:29:58 +0000408 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000409 {
cristycafe0412012-01-10 13:29:58 +0000410 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000411 if (p == (const Quantum *) NULL)
412 break;
cristycafe0412012-01-10 13:29:58 +0000413 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000414 {
415 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
416 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
417 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
418 *q++=ScaleQuantumToChar((Quantum) 0);
419 p+=GetPixelChannels(image);
420 }
421 }
422 return;
423 }
424 if (LocaleCompare(map,"I") == 0)
425 {
cristycafe0412012-01-10 13:29:58 +0000426 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000427 {
cristycafe0412012-01-10 13:29:58 +0000428 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000429 if (p == (const Quantum *) NULL)
430 break;
cristycafe0412012-01-10 13:29:58 +0000431 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000432 {
433 *q++=ScaleQuantumToChar(GetPixelIntensity(image,p));
434 p+=GetPixelChannels(image);
435 }
436 }
437 return;
438 }
439 if (LocaleCompare(map,"RGB") == 0)
440 {
cristycafe0412012-01-10 13:29:58 +0000441 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000442 {
cristycafe0412012-01-10 13:29:58 +0000443 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000444 if (p == (const Quantum *) NULL)
445 break;
cristycafe0412012-01-10 13:29:58 +0000446 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000447 {
448 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
449 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
450 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
451 p+=GetPixelChannels(image);
452 }
453 }
454 return;
455 }
456 if (LocaleCompare(map,"RGBA") == 0)
457 {
cristycafe0412012-01-10 13:29:58 +0000458 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000459 {
cristycafe0412012-01-10 13:29:58 +0000460 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000461 if (p == (const Quantum *) NULL)
462 break;
cristycafe0412012-01-10 13:29:58 +0000463 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000464 {
465 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
466 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
467 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
468 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
469 p+=GetPixelChannels(image);
470 }
471 }
472 return;
473 }
474 if (LocaleCompare(map,"RGBP") == 0)
475 {
cristycafe0412012-01-10 13:29:58 +0000476 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000477 {
cristycafe0412012-01-10 13:29:58 +0000478 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000479 if (p == (const Quantum *) NULL)
480 break;
cristycafe0412012-01-10 13:29:58 +0000481 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000482 {
483 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
484 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
485 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
486 *q++=ScaleQuantumToChar((Quantum) 0);
487 p+=GetPixelChannels(image);
488 }
489 }
490 return;
491 }
cristycafe0412012-01-10 13:29:58 +0000492 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000493 {
cristycafe0412012-01-10 13:29:58 +0000494 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000495 if (p == (const Quantum *) NULL)
496 break;
cristycafe0412012-01-10 13:29:58 +0000497 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000498 {
499 register ssize_t
500 i;
501
502 for (i=0; i < (ssize_t) strlen(map); i++)
503 {
504 *q=0;
505 switch (quantum_map[i])
506 {
507 case RedQuantum:
508 case CyanQuantum:
509 {
510 *q=ScaleQuantumToChar(GetPixelRed(image,p));
511 break;
512 }
513 case GreenQuantum:
514 case MagentaQuantum:
515 {
516 *q=ScaleQuantumToChar(GetPixelGreen(image,p));
517 break;
518 }
519 case BlueQuantum:
520 case YellowQuantum:
521 {
522 *q=ScaleQuantumToChar(GetPixelBlue(image,p));
523 break;
524 }
525 case AlphaQuantum:
526 {
527 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
528 break;
529 }
530 case OpacityQuantum:
531 {
532 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
533 break;
534 }
535 case BlackQuantum:
536 {
537 if (image->colorspace == CMYKColorspace)
538 *q=ScaleQuantumToChar(GetPixelBlack(image,p));
539 break;
540 }
541 case IndexQuantum:
542 {
543 *q=ScaleQuantumToChar(GetPixelIntensity(image,p));
544 break;
545 }
546 default:
547 break;
548 }
549 q++;
550 }
551 p+=GetPixelChannels(image);
552 }
553 }
554}
555
cristycafe0412012-01-10 13:29:58 +0000556static void ExportDoublePixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000557 const char *restrict map,const QuantumType *quantum_map,void *pixels,
558 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000559{
560 register const Quantum
561 *restrict p;
562
563 register double
cristy3fe11452012-01-09 01:27:42 +0000564 *restrict q;
cristye5370942012-01-06 03:49:31 +0000565
566 register ssize_t
567 x;
568
569 ssize_t
570 y;
571
572 q=(double *) pixels;
573 if (LocaleCompare(map,"BGR") == 0)
574 {
cristycafe0412012-01-10 13:29:58 +0000575 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000576 {
cristycafe0412012-01-10 13:29:58 +0000577 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000578 if (p == (const Quantum *) NULL)
579 break;
cristycafe0412012-01-10 13:29:58 +0000580 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000581 {
582 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
583 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
584 *q++=(double) (QuantumScale*GetPixelRed(image,p));
585 p+=GetPixelChannels(image);
586 }
587 }
588 return;
589 }
590 if (LocaleCompare(map,"BGRA") == 0)
591 {
cristycafe0412012-01-10 13:29:58 +0000592 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000593 {
cristycafe0412012-01-10 13:29:58 +0000594 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000595 if (p == (const Quantum *) NULL)
596 break;
cristycafe0412012-01-10 13:29:58 +0000597 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000598 {
599 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
600 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
601 *q++=(double) (QuantumScale*GetPixelRed(image,p));
602 *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
603 p+=GetPixelChannels(image);
604 }
605 }
606 return;
607 }
608 if (LocaleCompare(map,"BGRP") == 0)
609 {
cristycafe0412012-01-10 13:29:58 +0000610 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000611 {
cristycafe0412012-01-10 13:29:58 +0000612 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000613 if (p == (const Quantum *) NULL)
614 break;
cristycafe0412012-01-10 13:29:58 +0000615 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000616 {
617 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
618 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
619 *q++=(double) (QuantumScale*GetPixelRed(image,p));
620 *q++=0.0;
621 p+=GetPixelChannels(image);
622 }
623 }
624 return;
625 }
626 if (LocaleCompare(map,"I") == 0)
627 {
cristycafe0412012-01-10 13:29:58 +0000628 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000629 {
cristycafe0412012-01-10 13:29:58 +0000630 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000631 if (p == (const Quantum *) NULL)
632 break;
cristycafe0412012-01-10 13:29:58 +0000633 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000634 {
635 *q++=(double) (QuantumScale*GetPixelIntensity(image,p));
636 p+=GetPixelChannels(image);
637 }
638 }
639 return;
640 }
641 if (LocaleCompare(map,"RGB") == 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*GetPixelRed(image,p));
651 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
652 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
653 p+=GetPixelChannels(image);
654 }
655 }
656 return;
657 }
658 if (LocaleCompare(map,"RGBA") == 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*GetPixelRed(image,p));
668 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
669 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
670 *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
671 p+=GetPixelChannels(image);
672 }
673 }
674 return;
675 }
676 if (LocaleCompare(map,"RGBP") == 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*GetPixelRed(image,p));
686 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
687 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
688 *q++=0.0;
689 p+=GetPixelChannels(image);
690 }
691 }
692 return;
693 }
cristycafe0412012-01-10 13:29:58 +0000694 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000695 {
cristycafe0412012-01-10 13:29:58 +0000696 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000697 if (p == (const Quantum *) NULL)
698 break;
cristycafe0412012-01-10 13:29:58 +0000699 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000700 {
701 register ssize_t
702 i;
703
704 for (i=0; i < (ssize_t) strlen(map); i++)
705 {
706 *q=0;
707 switch (quantum_map[i])
708 {
709 case RedQuantum:
710 case CyanQuantum:
711 {
712 *q=(double) (QuantumScale*GetPixelRed(image,p));
713 break;
714 }
715 case GreenQuantum:
716 case MagentaQuantum:
717 {
718 *q=(double) (QuantumScale*GetPixelGreen(image,p));
719 break;
720 }
721 case BlueQuantum:
722 case YellowQuantum:
723 {
724 *q=(double) (QuantumScale*GetPixelBlue(image,p));
725 break;
726 }
727 case AlphaQuantum:
728 {
729 *q=(double) (QuantumScale*GetPixelAlpha(image,p));
730 break;
731 }
732 case OpacityQuantum:
733 {
734 *q=(double) (QuantumScale*GetPixelAlpha(image,p));
735 break;
736 }
737 case BlackQuantum:
738 {
739 if (image->colorspace == CMYKColorspace)
740 *q=(double) (QuantumScale*
741 GetPixelBlack(image,p));
742 break;
743 }
744 case IndexQuantum:
745 {
746 *q=(double) (QuantumScale*GetPixelIntensity(image,p));
747 break;
748 }
749 default:
750 *q=0;
751 }
752 q++;
753 }
754 p+=GetPixelChannels(image);
755 }
756 }
757}
758
cristycafe0412012-01-10 13:29:58 +0000759static void ExportFloatPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000760 const char *restrict map,const QuantumType *quantum_map,void *pixels,
761 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000762{
763 register const Quantum
764 *restrict p;
765
766 register float
cristy3fe11452012-01-09 01:27:42 +0000767 *restrict q;
cristye5370942012-01-06 03:49:31 +0000768
769 register ssize_t
770 x;
771
772 ssize_t
773 y;
774
775 q=(float *) pixels;
776 if (LocaleCompare(map,"BGR") == 0)
777 {
cristycafe0412012-01-10 13:29:58 +0000778 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000779 {
cristycafe0412012-01-10 13:29:58 +0000780 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000781 if (p == (const Quantum *) NULL)
782 break;
cristycafe0412012-01-10 13:29:58 +0000783 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000784 {
785 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
786 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
787 *q++=(float) (QuantumScale*GetPixelRed(image,p));
788 p+=GetPixelChannels(image);
789 }
790 }
791 return;
792 }
793 if (LocaleCompare(map,"BGRA") == 0)
794 {
cristycafe0412012-01-10 13:29:58 +0000795 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000796 {
cristycafe0412012-01-10 13:29:58 +0000797 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000798 if (p == (const Quantum *) NULL)
799 break;
cristycafe0412012-01-10 13:29:58 +0000800 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000801 {
802 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
803 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
804 *q++=(float) (QuantumScale*GetPixelRed(image,p));
805 *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
806 p+=GetPixelChannels(image);
807 }
808 }
809 return;
810 }
811 if (LocaleCompare(map,"BGRP") == 0)
812 {
cristycafe0412012-01-10 13:29:58 +0000813 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000814 {
cristycafe0412012-01-10 13:29:58 +0000815 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000816 if (p == (const Quantum *) NULL)
817 break;
cristycafe0412012-01-10 13:29:58 +0000818 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000819 {
820 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
821 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
822 *q++=(float) (QuantumScale*GetPixelRed(image,p));
823 *q++=0.0;
824 p+=GetPixelChannels(image);
825 }
826 }
827 return;
828 }
829 if (LocaleCompare(map,"I") == 0)
830 {
cristycafe0412012-01-10 13:29:58 +0000831 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000832 {
cristycafe0412012-01-10 13:29:58 +0000833 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000834 if (p == (const Quantum *) NULL)
835 break;
cristycafe0412012-01-10 13:29:58 +0000836 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000837 {
838 *q++=(float) (QuantumScale*GetPixelIntensity(image,p));
839 p+=GetPixelChannels(image);
840 }
841 }
842 return;
843 }
844 if (LocaleCompare(map,"RGB") == 0)
845 {
cristycafe0412012-01-10 13:29:58 +0000846 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000847 {
cristycafe0412012-01-10 13:29:58 +0000848 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000849 if (p == (const Quantum *) NULL)
850 break;
cristycafe0412012-01-10 13:29:58 +0000851 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000852 {
853 *q++=(float) (QuantumScale*GetPixelRed(image,p));
854 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
855 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
856 p+=GetPixelChannels(image);
857 }
858 }
859 return;
860 }
861 if (LocaleCompare(map,"RGBA") == 0)
862 {
cristycafe0412012-01-10 13:29:58 +0000863 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000864 {
cristycafe0412012-01-10 13:29:58 +0000865 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000866 if (p == (const Quantum *) NULL)
867 break;
cristycafe0412012-01-10 13:29:58 +0000868 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000869 {
870 *q++=(float) (QuantumScale*GetPixelRed(image,p));
871 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
872 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
873 *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
874 p+=GetPixelChannels(image);
875 }
876 }
877 return;
878 }
879 if (LocaleCompare(map,"RGBP") == 0)
880 {
cristycafe0412012-01-10 13:29:58 +0000881 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000882 {
cristycafe0412012-01-10 13:29:58 +0000883 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000884 if (p == (const Quantum *) NULL)
885 break;
cristycafe0412012-01-10 13:29:58 +0000886 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000887 {
888 *q++=(float) (QuantumScale*GetPixelRed(image,p));
889 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
890 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
891 *q++=0.0;
892 p+=GetPixelChannels(image);
893 }
894 }
895 return;
896 }
cristycafe0412012-01-10 13:29:58 +0000897 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000898 {
cristycafe0412012-01-10 13:29:58 +0000899 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000900 if (p == (const Quantum *) NULL)
901 break;
cristycafe0412012-01-10 13:29:58 +0000902 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000903 {
904 register ssize_t
905 i;
906
907 for (i=0; i < (ssize_t) strlen(map); i++)
908 {
909 *q=0;
910 switch (quantum_map[i])
911 {
912 case RedQuantum:
913 case CyanQuantum:
914 {
915 *q=(float) (QuantumScale*GetPixelRed(image,p));
916 break;
917 }
918 case GreenQuantum:
919 case MagentaQuantum:
920 {
921 *q=(float) (QuantumScale*GetPixelGreen(image,p));
922 break;
923 }
924 case BlueQuantum:
925 case YellowQuantum:
926 {
927 *q=(float) (QuantumScale*GetPixelBlue(image,p));
928 break;
929 }
930 case AlphaQuantum:
931 {
932 *q=(float) (QuantumScale*((Quantum) (GetPixelAlpha(image,p))));
933 break;
934 }
935 case OpacityQuantum:
936 {
937 *q=(float) (QuantumScale*GetPixelAlpha(image,p));
938 break;
939 }
940 case BlackQuantum:
941 {
942 if (image->colorspace == CMYKColorspace)
943 *q=(float) (QuantumScale* GetPixelBlack(image,p));
944 break;
945 }
946 case IndexQuantum:
947 {
948 *q=(float) (QuantumScale*GetPixelIntensity(image,p));
949 break;
950 }
951 default:
952 *q=0;
953 }
954 q++;
955 }
956 p+=GetPixelChannels(image);
957 }
958 }
959}
960
cristycafe0412012-01-10 13:29:58 +0000961static void ExportLongPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000962 const char *restrict map,const QuantumType *quantum_map,void *pixels,
963 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000964{
965 register const Quantum
966 *restrict p;
967
968 register ssize_t
969 x;
970
971 register unsigned int
cristy3fe11452012-01-09 01:27:42 +0000972 *restrict q;
cristye5370942012-01-06 03:49:31 +0000973
974 ssize_t
975 y;
976
977 q=(unsigned int *) pixels;
978 if (LocaleCompare(map,"BGR") == 0)
979 {
cristycafe0412012-01-10 13:29:58 +0000980 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000981 {
cristycafe0412012-01-10 13:29:58 +0000982 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000983 if (p == (const Quantum *) NULL)
984 break;
cristycafe0412012-01-10 13:29:58 +0000985 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000986 {
cristy6c9e1682012-01-07 21:37:44 +0000987 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
988 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
989 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +0000990 p+=GetPixelChannels(image);
991 }
992 }
993 return;
994 }
995 if (LocaleCompare(map,"BGRA") == 0)
996 {
cristycafe0412012-01-10 13:29:58 +0000997 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000998 {
cristycafe0412012-01-10 13:29:58 +0000999 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001000 if (p == (const Quantum *) NULL)
1001 break;
cristycafe0412012-01-10 13:29:58 +00001002 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001003 {
cristy6c9e1682012-01-07 21:37:44 +00001004 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1005 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1006 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1007 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001008 p+=GetPixelChannels(image);
1009 }
1010 }
1011 return;
1012 }
1013 if (LocaleCompare(map,"BGRP") == 0)
1014 {
cristycafe0412012-01-10 13:29:58 +00001015 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001016 {
cristycafe0412012-01-10 13:29:58 +00001017 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001018 if (p == (const Quantum *) NULL)
1019 break;
cristycafe0412012-01-10 13:29:58 +00001020 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001021 {
cristy6c9e1682012-01-07 21:37:44 +00001022 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1023 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1024 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1025 *q++=0;
cristye5370942012-01-06 03:49:31 +00001026 p+=GetPixelChannels(image);
1027 }
1028 }
1029 return;
1030 }
1031 if (LocaleCompare(map,"I") == 0)
1032 {
cristycafe0412012-01-10 13:29:58 +00001033 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001034 {
cristycafe0412012-01-10 13:29:58 +00001035 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001036 if (p == (const Quantum *) NULL)
1037 break;
cristycafe0412012-01-10 13:29:58 +00001038 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001039 {
cristy6c9e1682012-01-07 21:37:44 +00001040 *q++=ScaleQuantumToLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001041 p+=GetPixelChannels(image);
1042 }
1043 }
1044 return;
1045 }
1046 if (LocaleCompare(map,"RGB") == 0)
1047 {
cristycafe0412012-01-10 13:29:58 +00001048 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001049 {
cristycafe0412012-01-10 13:29:58 +00001050 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001051 if (p == (const Quantum *) NULL)
1052 break;
cristycafe0412012-01-10 13:29:58 +00001053 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001054 {
cristy6c9e1682012-01-07 21:37:44 +00001055 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1056 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1057 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001058 p+=GetPixelChannels(image);
1059 }
1060 }
1061 return;
1062 }
1063 if (LocaleCompare(map,"RGBA") == 0)
1064 {
cristycafe0412012-01-10 13:29:58 +00001065 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001066 {
cristycafe0412012-01-10 13:29:58 +00001067 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001068 if (p == (const Quantum *) NULL)
1069 break;
cristycafe0412012-01-10 13:29:58 +00001070 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001071 {
cristy6c9e1682012-01-07 21:37:44 +00001072 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1073 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1074 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1075 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001076 p+=GetPixelChannels(image);
1077 }
1078 }
1079 return;
1080 }
1081 if (LocaleCompare(map,"RGBP") == 0)
1082 {
cristycafe0412012-01-10 13:29:58 +00001083 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001084 {
cristycafe0412012-01-10 13:29:58 +00001085 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001086 if (p == (const Quantum *) NULL)
1087 break;
cristycafe0412012-01-10 13:29:58 +00001088 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001089 {
cristy6c9e1682012-01-07 21:37:44 +00001090 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1091 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1092 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1093 *q++=0;
cristye5370942012-01-06 03:49:31 +00001094 p+=GetPixelChannels(image);
1095 }
1096 }
1097 return;
1098 }
cristycafe0412012-01-10 13:29:58 +00001099 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001100 {
cristycafe0412012-01-10 13:29:58 +00001101 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001102 if (p == (const Quantum *) NULL)
1103 break;
cristycafe0412012-01-10 13:29:58 +00001104 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001105 {
1106 register ssize_t
1107 i;
1108
1109 for (i=0; i < (ssize_t) strlen(map); i++)
1110 {
1111 *q=0;
1112 switch (quantum_map[i])
1113 {
1114 case RedQuantum:
1115 case CyanQuantum:
1116 {
cristy6c9e1682012-01-07 21:37:44 +00001117 *q=ScaleQuantumToLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001118 break;
1119 }
1120 case GreenQuantum:
1121 case MagentaQuantum:
1122 {
cristy6c9e1682012-01-07 21:37:44 +00001123 *q=ScaleQuantumToLong(GetPixelGreen(image,p));
cristye5370942012-01-06 03:49:31 +00001124 break;
1125 }
1126 case BlueQuantum:
1127 case YellowQuantum:
1128 {
cristy6c9e1682012-01-07 21:37:44 +00001129 *q=ScaleQuantumToLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001130 break;
1131 }
1132 case AlphaQuantum:
1133 {
cristy6c9e1682012-01-07 21:37:44 +00001134 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001135 break;
1136 }
1137 case OpacityQuantum:
1138 {
cristy6c9e1682012-01-07 21:37:44 +00001139 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001140 break;
1141 }
1142 case BlackQuantum:
1143 {
1144 if (image->colorspace == CMYKColorspace)
cristy6c9e1682012-01-07 21:37:44 +00001145 *q=ScaleQuantumToLong(GetPixelBlack(image,p));
cristye5370942012-01-06 03:49:31 +00001146 break;
1147 }
1148 case IndexQuantum:
1149 {
cristy6c9e1682012-01-07 21:37:44 +00001150 *q=ScaleQuantumToLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001151 break;
1152 }
1153 default:
cristy6c9e1682012-01-07 21:37:44 +00001154 break;
cristye5370942012-01-06 03:49:31 +00001155 }
1156 q++;
1157 }
1158 p+=GetPixelChannels(image);
1159 }
1160 }
1161}
1162
cristycafe0412012-01-10 13:29:58 +00001163static void ExportLongLongPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00001164 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1165 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001166{
1167 register const Quantum
1168 *restrict p;
1169
1170 register ssize_t
1171 x;
1172
cristyb13e12a2012-01-06 21:48:27 +00001173 register MagickSizeType
cristy3fe11452012-01-09 01:27:42 +00001174 *restrict q;
cristye5370942012-01-06 03:49:31 +00001175
1176 ssize_t
1177 y;
1178
cristyb13e12a2012-01-06 21:48:27 +00001179 q=(MagickSizeType *) pixels;
cristye5370942012-01-06 03:49:31 +00001180 if (LocaleCompare(map,"BGR") == 0)
1181 {
cristycafe0412012-01-10 13:29:58 +00001182 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001183 {
cristycafe0412012-01-10 13:29:58 +00001184 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001185 if (p == (const Quantum *) NULL)
1186 break;
cristycafe0412012-01-10 13:29:58 +00001187 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001188 {
cristyb13e12a2012-01-06 21:48:27 +00001189 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1190 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1191 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001192 p+=GetPixelChannels(image);
1193 }
1194 }
1195 return;
1196 }
1197 if (LocaleCompare(map,"BGRA") == 0)
1198 {
cristycafe0412012-01-10 13:29:58 +00001199 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001200 {
cristycafe0412012-01-10 13:29:58 +00001201 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001202 if (p == (const Quantum *) NULL)
1203 break;
cristycafe0412012-01-10 13:29:58 +00001204 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001205 {
cristyb13e12a2012-01-06 21:48:27 +00001206 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1207 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1208 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1209 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001210 p+=GetPixelChannels(image);
1211 }
1212 }
1213 return;
1214 }
1215 if (LocaleCompare(map,"BGRP") == 0)
1216 {
cristycafe0412012-01-10 13:29:58 +00001217 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001218 {
cristycafe0412012-01-10 13:29:58 +00001219 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001220 if (p == (const Quantum *) NULL)
1221 break;
cristycafe0412012-01-10 13:29:58 +00001222 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001223 {
cristyb13e12a2012-01-06 21:48:27 +00001224 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1225 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1226 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001227 *q++=0;
1228 p+=GetPixelChannels(image);
1229 }
1230 }
1231 return;
1232 }
1233 if (LocaleCompare(map,"I") == 0)
1234 {
cristycafe0412012-01-10 13:29:58 +00001235 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001236 {
cristycafe0412012-01-10 13:29:58 +00001237 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001238 if (p == (const Quantum *) NULL)
1239 break;
cristycafe0412012-01-10 13:29:58 +00001240 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001241 {
cristyb13e12a2012-01-06 21:48:27 +00001242 *q++=ScaleQuantumToLongLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001243 p+=GetPixelChannels(image);
1244 }
1245 }
1246 return;
1247 }
1248 if (LocaleCompare(map,"RGB") == 0)
1249 {
cristycafe0412012-01-10 13:29:58 +00001250 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001251 {
cristycafe0412012-01-10 13:29:58 +00001252 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001253 if (p == (const Quantum *) NULL)
1254 break;
cristycafe0412012-01-10 13:29:58 +00001255 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001256 {
cristyb13e12a2012-01-06 21:48:27 +00001257 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1258 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1259 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001260 p+=GetPixelChannels(image);
1261 }
1262 }
1263 return;
1264 }
1265 if (LocaleCompare(map,"RGBA") == 0)
1266 {
cristycafe0412012-01-10 13:29:58 +00001267 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001268 {
cristycafe0412012-01-10 13:29:58 +00001269 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001270 if (p == (const Quantum *) NULL)
1271 break;
cristycafe0412012-01-10 13:29:58 +00001272 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001273 {
cristyb13e12a2012-01-06 21:48:27 +00001274 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1275 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1276 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1277 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001278 p+=GetPixelChannels(image);
1279 }
1280 }
1281 return;
1282 }
1283 if (LocaleCompare(map,"RGBP") == 0)
1284 {
cristycafe0412012-01-10 13:29:58 +00001285 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001286 {
cristycafe0412012-01-10 13:29:58 +00001287 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001288 if (p == (const Quantum *) NULL)
1289 break;
cristycafe0412012-01-10 13:29:58 +00001290 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001291 {
cristyb13e12a2012-01-06 21:48:27 +00001292 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1293 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1294 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001295 *q++=0;
1296 p+=GetPixelChannels(image);
1297 }
1298 }
1299 return;
1300 }
cristycafe0412012-01-10 13:29:58 +00001301 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001302 {
cristycafe0412012-01-10 13:29:58 +00001303 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001304 if (p == (const Quantum *) NULL)
1305 break;
cristycafe0412012-01-10 13:29:58 +00001306 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001307 {
1308 register ssize_t
1309 i;
1310
1311 for (i=0; i < (ssize_t) strlen(map); i++)
1312 {
1313 *q=0;
1314 switch (quantum_map[i])
1315 {
1316 case RedQuantum:
1317 case CyanQuantum:
1318 {
cristyb13e12a2012-01-06 21:48:27 +00001319 *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001320 break;
1321 }
1322 case GreenQuantum:
1323 case MagentaQuantum:
1324 {
cristyb13e12a2012-01-06 21:48:27 +00001325 *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
cristye5370942012-01-06 03:49:31 +00001326 break;
1327 }
1328 case BlueQuantum:
1329 case YellowQuantum:
1330 {
cristyb13e12a2012-01-06 21:48:27 +00001331 *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001332 break;
1333 }
1334 case AlphaQuantum:
1335 {
cristyb13e12a2012-01-06 21:48:27 +00001336 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001337 break;
1338 }
1339 case OpacityQuantum:
1340 {
cristyb13e12a2012-01-06 21:48:27 +00001341 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001342 break;
1343 }
1344 case BlackQuantum:
1345 {
1346 if (image->colorspace == CMYKColorspace)
cristyb13e12a2012-01-06 21:48:27 +00001347 *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
cristye5370942012-01-06 03:49:31 +00001348 break;
1349 }
1350 case IndexQuantum:
1351 {
cristyb13e12a2012-01-06 21:48:27 +00001352 *q=ScaleQuantumToLongLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001353 break;
1354 }
1355 default:
1356 break;
1357 }
1358 q++;
1359 }
1360 p+=GetPixelChannels(image);
1361 }
1362 }
1363}
1364
cristycafe0412012-01-10 13:29:58 +00001365static void ExportQuantumPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00001366 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1367 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001368{
1369 register const Quantum
1370 *restrict p;
1371
1372 register Quantum
cristy3fe11452012-01-09 01:27:42 +00001373 *restrict q;
cristye5370942012-01-06 03:49:31 +00001374
1375 register ssize_t
1376 x;
1377
1378 ssize_t
1379 y;
1380
1381 q=(Quantum *) pixels;
1382 if (LocaleCompare(map,"BGR") == 0)
1383 {
cristycafe0412012-01-10 13:29:58 +00001384 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001385 {
cristycafe0412012-01-10 13:29:58 +00001386 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001387 if (p == (const Quantum *) NULL)
1388 break;
cristycafe0412012-01-10 13:29:58 +00001389 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001390 {
1391 *q++=GetPixelBlue(image,p);
1392 *q++=GetPixelGreen(image,p);
1393 *q++=GetPixelRed(image,p);
1394 p+=GetPixelChannels(image);
1395 }
1396 }
1397 return;
1398 }
1399 if (LocaleCompare(map,"BGRA") == 0)
1400 {
cristycafe0412012-01-10 13:29:58 +00001401 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001402 {
cristycafe0412012-01-10 13:29:58 +00001403 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001404 if (p == (const Quantum *) NULL)
1405 break;
cristycafe0412012-01-10 13:29:58 +00001406 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001407 {
1408 *q++=GetPixelBlue(image,p);
1409 *q++=GetPixelGreen(image,p);
1410 *q++=GetPixelRed(image,p);
1411 *q++=(Quantum) (GetPixelAlpha(image,p));
1412 p+=GetPixelChannels(image);
1413 }
1414 }
1415 return;
1416 }
1417 if (LocaleCompare(map,"BGRP") == 0)
1418 {
cristycafe0412012-01-10 13:29:58 +00001419 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001420 {
cristycafe0412012-01-10 13:29:58 +00001421 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001422 if (p == (const Quantum *) NULL)
1423 break;
cristycafe0412012-01-10 13:29:58 +00001424 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001425 {
1426 *q++=GetPixelBlue(image,p);
1427 *q++=GetPixelGreen(image,p);
1428 *q++=GetPixelRed(image,p);
1429 *q++=(Quantum) 0;
1430 p+=GetPixelChannels(image);
1431 }
1432 }
1433 return;
1434 }
1435 if (LocaleCompare(map,"I") == 0)
1436 {
cristycafe0412012-01-10 13:29:58 +00001437 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001438 {
cristycafe0412012-01-10 13:29:58 +00001439 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001440 if (p == (const Quantum *) NULL)
1441 break;
cristycafe0412012-01-10 13:29:58 +00001442 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001443 {
1444 *q++=GetPixelIntensity(image,p);
1445 p+=GetPixelChannels(image);
1446 }
1447 }
1448 return;
1449 }
1450 if (LocaleCompare(map,"RGB") == 0)
1451 {
cristycafe0412012-01-10 13:29:58 +00001452 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001453 {
cristycafe0412012-01-10 13:29:58 +00001454 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001455 if (p == (const Quantum *) NULL)
1456 break;
cristycafe0412012-01-10 13:29:58 +00001457 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001458 {
1459 *q++=GetPixelRed(image,p);
1460 *q++=GetPixelGreen(image,p);
1461 *q++=GetPixelBlue(image,p);
1462 p+=GetPixelChannels(image);
1463 }
1464 }
1465 return;
1466 }
1467 if (LocaleCompare(map,"RGBA") == 0)
1468 {
cristycafe0412012-01-10 13:29:58 +00001469 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001470 {
cristycafe0412012-01-10 13:29:58 +00001471 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001472 if (p == (const Quantum *) NULL)
1473 break;
cristycafe0412012-01-10 13:29:58 +00001474 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001475 {
1476 *q++=GetPixelRed(image,p);
1477 *q++=GetPixelGreen(image,p);
1478 *q++=GetPixelBlue(image,p);
1479 *q++=(Quantum) (GetPixelAlpha(image,p));
1480 p+=GetPixelChannels(image);
1481 }
1482 }
1483 return;
1484 }
1485 if (LocaleCompare(map,"RGBP") == 0)
1486 {
cristycafe0412012-01-10 13:29:58 +00001487 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001488 {
cristycafe0412012-01-10 13:29:58 +00001489 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001490 if (p == (const Quantum *) NULL)
1491 break;
cristycafe0412012-01-10 13:29:58 +00001492 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001493 {
1494 *q++=GetPixelRed(image,p);
1495 *q++=GetPixelGreen(image,p);
1496 *q++=GetPixelBlue(image,p);
1497 *q++=(Quantum) 0;
1498 p+=GetPixelChannels(image);
1499 }
1500 }
1501 return;
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 register ssize_t
1511 i;
1512
1513 for (i=0; i < (ssize_t) strlen(map); i++)
1514 {
1515 *q=(Quantum) 0;
1516 switch (quantum_map[i])
1517 {
1518 case RedQuantum:
1519 case CyanQuantum:
1520 {
1521 *q=GetPixelRed(image,p);
1522 break;
1523 }
1524 case GreenQuantum:
1525 case MagentaQuantum:
1526 {
1527 *q=GetPixelGreen(image,p);
1528 break;
1529 }
1530 case BlueQuantum:
1531 case YellowQuantum:
1532 {
1533 *q=GetPixelBlue(image,p);
1534 break;
1535 }
1536 case AlphaQuantum:
1537 {
1538 *q=GetPixelAlpha(image,p);
1539 break;
1540 }
1541 case OpacityQuantum:
1542 {
1543 *q=GetPixelAlpha(image,p);
1544 break;
1545 }
1546 case BlackQuantum:
1547 {
1548 if (image->colorspace == CMYKColorspace)
1549 *q=GetPixelBlack(image,p);
1550 break;
1551 }
1552 case IndexQuantum:
1553 {
1554 *q=(GetPixelIntensity(image,p));
1555 break;
1556 }
1557 default:
1558 {
1559 *q=(Quantum) 0;
1560 break;
1561 }
1562 }
1563 q++;
1564 }
1565 p+=GetPixelChannels(image);
1566 }
1567 }
1568}
1569
cristycafe0412012-01-10 13:29:58 +00001570static void ExportShortPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00001571 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1572 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001573{
1574 register const Quantum
1575 *restrict p;
1576
1577 register ssize_t
1578 x;
1579
1580 ssize_t
1581 y;
1582
1583 register unsigned short
cristy3fe11452012-01-09 01:27:42 +00001584 *restrict q;
cristye5370942012-01-06 03:49:31 +00001585
1586 q=(unsigned short *) pixels;
1587 if (LocaleCompare(map,"BGR") == 0)
1588 {
cristycafe0412012-01-10 13:29:58 +00001589 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001590 {
cristycafe0412012-01-10 13:29:58 +00001591 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001592 if (p == (const Quantum *) NULL)
1593 break;
cristycafe0412012-01-10 13:29:58 +00001594 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001595 {
1596 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1597 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1598 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1599 p+=GetPixelChannels(image);
1600 }
1601 }
1602 return;
1603 }
1604 if (LocaleCompare(map,"BGRA") == 0)
1605 {
cristycafe0412012-01-10 13:29:58 +00001606 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001607 {
cristycafe0412012-01-10 13:29:58 +00001608 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001609 if (p == (const Quantum *) NULL)
1610 break;
cristycafe0412012-01-10 13:29:58 +00001611 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001612 {
1613 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1614 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1615 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1616 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1617 p+=GetPixelChannels(image);
1618 }
1619 }
1620 return;
1621 }
1622 if (LocaleCompare(map,"BGRP") == 0)
1623 {
cristycafe0412012-01-10 13:29:58 +00001624 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001625 {
cristycafe0412012-01-10 13:29:58 +00001626 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001627 if (p == (const Quantum *) NULL)
1628 break;
cristycafe0412012-01-10 13:29:58 +00001629 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001630 {
1631 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1632 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1633 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1634 *q++=0;
1635 p+=GetPixelChannels(image);
1636 }
1637 }
1638 return;
1639 }
1640 if (LocaleCompare(map,"I") == 0)
1641 {
cristycafe0412012-01-10 13:29:58 +00001642 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001643 {
cristycafe0412012-01-10 13:29:58 +00001644 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001645 if (p == (const Quantum *) NULL)
1646 break;
cristycafe0412012-01-10 13:29:58 +00001647 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001648 {
1649 *q++=ScaleQuantumToShort(GetPixelIntensity(image,p));
1650 p+=GetPixelChannels(image);
1651 }
1652 }
1653 return;
1654 }
1655 if (LocaleCompare(map,"RGB") == 0)
1656 {
cristycafe0412012-01-10 13:29:58 +00001657 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001658 {
cristycafe0412012-01-10 13:29:58 +00001659 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001660 if (p == (const Quantum *) NULL)
1661 break;
cristycafe0412012-01-10 13:29:58 +00001662 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001663 {
1664 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1665 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1666 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1667 p+=GetPixelChannels(image);
1668 }
1669 }
1670 return;
1671 }
1672 if (LocaleCompare(map,"RGBA") == 0)
1673 {
cristycafe0412012-01-10 13:29:58 +00001674 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001675 {
cristycafe0412012-01-10 13:29:58 +00001676 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001677 if (p == (const Quantum *) NULL)
1678 break;
cristycafe0412012-01-10 13:29:58 +00001679 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001680 {
1681 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1682 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1683 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1684 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1685 p+=GetPixelChannels(image);
1686 }
1687 }
1688 return;
1689 }
1690 if (LocaleCompare(map,"RGBP") == 0)
1691 {
cristycafe0412012-01-10 13:29:58 +00001692 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001693 {
cristycafe0412012-01-10 13:29:58 +00001694 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001695 if (p == (const Quantum *) NULL)
1696 break;
cristycafe0412012-01-10 13:29:58 +00001697 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001698 {
1699 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1700 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1701 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1702 *q++=0;
1703 p+=GetPixelChannels(image);
1704 }
1705 }
1706 return;
1707 }
cristycafe0412012-01-10 13:29:58 +00001708 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001709 {
cristycafe0412012-01-10 13:29:58 +00001710 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001711 if (p == (const Quantum *) NULL)
1712 break;
cristycafe0412012-01-10 13:29:58 +00001713 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001714 {
1715 register ssize_t
1716 i;
1717
1718 for (i=0; i < (ssize_t) strlen(map); i++)
1719 {
1720 *q=0;
1721 switch (quantum_map[i])
1722 {
1723 case RedQuantum:
1724 case CyanQuantum:
1725 {
1726 *q=ScaleQuantumToShort(GetPixelRed(image,p));
1727 break;
1728 }
1729 case GreenQuantum:
1730 case MagentaQuantum:
1731 {
1732 *q=ScaleQuantumToShort(GetPixelGreen(image,p));
1733 break;
1734 }
1735 case BlueQuantum:
1736 case YellowQuantum:
1737 {
1738 *q=ScaleQuantumToShort(GetPixelBlue(image,p));
1739 break;
1740 }
1741 case AlphaQuantum:
1742 {
1743 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1744 break;
1745 }
1746 case OpacityQuantum:
1747 {
1748 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1749 break;
1750 }
1751 case BlackQuantum:
1752 {
1753 if (image->colorspace == CMYKColorspace)
1754 *q=ScaleQuantumToShort(GetPixelBlack(image,p));
1755 break;
1756 }
1757 case IndexQuantum:
1758 {
1759 *q=ScaleQuantumToShort(GetPixelIntensity(image,p));
1760 break;
1761 }
1762 default:
1763 break;
1764 }
1765 q++;
1766 }
1767 p+=GetPixelChannels(image);
1768 }
1769 }
1770}
1771
cristy4c08aed2011-07-01 19:47:50 +00001772MagickExport MagickBooleanType ExportImagePixels(const Image *image,
cristycafe0412012-01-10 13:29:58 +00001773 const ssize_t x,const ssize_t y,const size_t width,const size_t height,
1774 const char *map,const StorageType type,void *pixels,ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00001775{
1776 QuantumType
1777 *quantum_map;
1778
cristycafe0412012-01-10 13:29:58 +00001779 RectangleInfo
1780 roi;
1781
cristy4c08aed2011-07-01 19:47:50 +00001782 register ssize_t
cristye5370942012-01-06 03:49:31 +00001783 i;
cristy4c08aed2011-07-01 19:47:50 +00001784
1785 assert(image != (Image *) NULL);
1786 assert(image->signature == MagickSignature);
1787 if (image->debug != MagickFalse)
1788 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristye5370942012-01-06 03:49:31 +00001789 quantum_map=(QuantumType *) AcquireQuantumMemory(strlen(map),
1790 sizeof(*quantum_map));
cristy4c08aed2011-07-01 19:47:50 +00001791 if (quantum_map == (QuantumType *) NULL)
1792 {
1793 (void) ThrowMagickException(exception,GetMagickModule(),
anthonye5b39652012-04-21 05:37:29 +00001794 ResourceLimitError,"MemoryAllocationFailed","'%s'",image->filename);
cristy4c08aed2011-07-01 19:47:50 +00001795 return(MagickFalse);
1796 }
cristye5370942012-01-06 03:49:31 +00001797 for (i=0; i < (ssize_t) strlen(map); i++)
cristy4c08aed2011-07-01 19:47:50 +00001798 {
1799 switch (map[i])
1800 {
1801 case 'A':
1802 case 'a':
1803 {
1804 quantum_map[i]=AlphaQuantum;
1805 break;
1806 }
1807 case 'B':
1808 case 'b':
1809 {
1810 quantum_map[i]=BlueQuantum;
1811 break;
1812 }
1813 case 'C':
1814 case 'c':
1815 {
1816 quantum_map[i]=CyanQuantum;
1817 if (image->colorspace == CMYKColorspace)
1818 break;
1819 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1820 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
anthonye5b39652012-04-21 05:37:29 +00001821 "ColorSeparatedImageRequired","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001822 return(MagickFalse);
1823 }
1824 case 'g':
1825 case 'G':
1826 {
1827 quantum_map[i]=GreenQuantum;
1828 break;
1829 }
1830 case 'I':
1831 case 'i':
1832 {
1833 quantum_map[i]=IndexQuantum;
1834 break;
1835 }
1836 case 'K':
1837 case 'k':
1838 {
1839 quantum_map[i]=BlackQuantum;
1840 if (image->colorspace == CMYKColorspace)
1841 break;
1842 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1843 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
anthonye5b39652012-04-21 05:37:29 +00001844 "ColorSeparatedImageRequired","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001845 return(MagickFalse);
1846 }
1847 case 'M':
1848 case 'm':
1849 {
1850 quantum_map[i]=MagentaQuantum;
1851 if (image->colorspace == CMYKColorspace)
1852 break;
1853 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1854 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
anthonye5b39652012-04-21 05:37:29 +00001855 "ColorSeparatedImageRequired","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001856 return(MagickFalse);
1857 }
1858 case 'o':
1859 case 'O':
1860 {
1861 quantum_map[i]=OpacityQuantum;
1862 break;
1863 }
1864 case 'P':
1865 case 'p':
1866 {
1867 quantum_map[i]=UndefinedQuantum;
1868 break;
1869 }
1870 case 'R':
1871 case 'r':
1872 {
1873 quantum_map[i]=RedQuantum;
1874 break;
1875 }
1876 case 'Y':
1877 case 'y':
1878 {
1879 quantum_map[i]=YellowQuantum;
1880 if (image->colorspace == CMYKColorspace)
1881 break;
1882 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1883 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
anthonye5b39652012-04-21 05:37:29 +00001884 "ColorSeparatedImageRequired","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001885 return(MagickFalse);
1886 }
1887 default:
1888 {
1889 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1890 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthonye5b39652012-04-21 05:37:29 +00001891 "UnrecognizedPixelMap","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001892 return(MagickFalse);
1893 }
1894 }
1895 }
cristycafe0412012-01-10 13:29:58 +00001896 roi.width=width;
1897 roi.height=height;
1898 roi.x=x;
1899 roi.y=y;
cristy4c08aed2011-07-01 19:47:50 +00001900 switch (type)
1901 {
1902 case CharPixel:
1903 {
cristycafe0412012-01-10 13:29:58 +00001904 ExportCharPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001905 break;
1906 }
1907 case DoublePixel:
1908 {
cristycafe0412012-01-10 13:29:58 +00001909 ExportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001910 break;
1911 }
1912 case FloatPixel:
1913 {
cristycafe0412012-01-10 13:29:58 +00001914 ExportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001915 break;
1916 }
cristy4c08aed2011-07-01 19:47:50 +00001917 case LongPixel:
1918 {
cristycafe0412012-01-10 13:29:58 +00001919 ExportLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001920 break;
1921 }
cristy6c9e1682012-01-07 21:37:44 +00001922 case LongLongPixel:
1923 {
cristycafe0412012-01-10 13:29:58 +00001924 ExportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy6c9e1682012-01-07 21:37:44 +00001925 break;
1926 }
cristy4c08aed2011-07-01 19:47:50 +00001927 case QuantumPixel:
1928 {
cristycafe0412012-01-10 13:29:58 +00001929 ExportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001930 break;
1931 }
1932 case ShortPixel:
1933 {
cristycafe0412012-01-10 13:29:58 +00001934 ExportShortPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001935 break;
1936 }
1937 default:
1938 {
1939 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1940 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthonye5b39652012-04-21 05:37:29 +00001941 "UnrecognizedPixelMap","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001942 break;
1943 }
1944 }
1945 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1946 return(MagickTrue);
1947}
1948
1949/*
1950%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1951% %
1952% %
1953% %
cristyaa8634f2011-10-01 13:25:12 +00001954% G e t P i x e l I n f o %
cristy4c08aed2011-07-01 19:47:50 +00001955% %
1956% %
1957% %
1958%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1959%
1960% GetPixelInfo() initializes the PixelInfo structure.
1961%
1962% The format of the GetPixelInfo method is:
1963%
1964% GetPixelInfo(const Image *image,PixelInfo *pixel)
1965%
1966% A description of each parameter follows:
1967%
1968% o image: the image.
1969%
cristy101ab702011-10-13 13:06:32 +00001970% o pixel: Specifies a pointer to a PixelInfo structure.
cristy4c08aed2011-07-01 19:47:50 +00001971%
1972*/
cristyaa8634f2011-10-01 13:25:12 +00001973MagickExport void GetPixelInfo(const Image *image,PixelInfo *pixel)
cristy4c08aed2011-07-01 19:47:50 +00001974{
1975 pixel->storage_class=DirectClass;
cristy7020ae62012-04-18 12:58:34 +00001976 pixel->colorspace=sRGBColorspace;
cristy4c08aed2011-07-01 19:47:50 +00001977 pixel->matte=MagickFalse;
1978 pixel->fuzz=0.0;
1979 pixel->depth=MAGICKCORE_QUANTUM_DEPTH;
1980 pixel->red=0.0;
1981 pixel->green=0.0;
1982 pixel->blue=0.0;
1983 pixel->black=0.0;
1984 pixel->alpha=(MagickRealType) OpaqueAlpha;
1985 pixel->index=0.0;
1986 if (image == (const Image *) NULL)
1987 return;
1988 pixel->storage_class=image->storage_class;
1989 pixel->colorspace=image->colorspace;
1990 pixel->matte=image->matte;
1991 pixel->depth=image->depth;
1992 pixel->fuzz=image->fuzz;
1993}
1994
1995/*
1996%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1997% %
1998% %
1999% %
2000% I m p o r t I m a g e P i x e l s %
2001% %
2002% %
2003% %
2004%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2005%
2006% ImportImagePixels() accepts pixel data and stores in the image at the
2007% location you specify. The method returns MagickTrue on success otherwise
2008% MagickFalse if an error is encountered. The pixel data can be either char,
cristyb5a45a32012-01-10 13:31:13 +00002009% Quantum, short int, unsigned int, unsigned long long, float, or double in
2010% the order specified by map.
cristy4c08aed2011-07-01 19:47:50 +00002011%
2012% Suppose your want to upload the first scanline of a 640x480 image from
2013% character data in red-green-blue order:
2014%
2015% ImportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels);
2016%
2017% The format of the ImportImagePixels method is:
2018%
cristycafe0412012-01-10 13:29:58 +00002019% MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
2020% const ssize_t y,const size_t width,const size_t height,
2021% const char *map,const StorageType type,const void *pixels,
2022% ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00002023%
2024% A description of each parameter follows:
2025%
2026% o image: the image.
2027%
cristycafe0412012-01-10 13:29:58 +00002028% o x,y,width,height: These values define the perimeter
cristy4c08aed2011-07-01 19:47:50 +00002029% of a region of pixels you want to define.
2030%
2031% o map: This string reflects the expected ordering of the pixel array.
2032% It can be any combination or order of R = red, G = green, B = blue,
2033% A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
2034% Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
2035% P = pad.
2036%
2037% o type: Define the data type of the pixels. Float and double types are
2038% normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
cristy6c9e1682012-01-07 21:37:44 +00002039% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
cristyff6834e2012-01-10 03:00:25 +00002040% LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
cristy6c9e1682012-01-07 21:37:44 +00002041% QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
cristy4c08aed2011-07-01 19:47:50 +00002042%
2043% o pixels: This array of values contain the pixel components as defined by
2044% map and type. You must preallocate this array where the expected
2045% length varies depending on the values of width, height, map, and type.
2046%
cristy018f07f2011-09-04 21:15:19 +00002047% o exception: return any errors or warnings in this structure.
2048%
cristy4c08aed2011-07-01 19:47:50 +00002049*/
cristye5370942012-01-06 03:49:31 +00002050
cristycafe0412012-01-10 13:29:58 +00002051static void ImportCharPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002052 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2053 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002054{
2055 register const unsigned char
2056 *restrict p;
2057
2058 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002059 *restrict q;
cristye5370942012-01-06 03:49:31 +00002060
2061 register ssize_t
2062 x;
2063
2064 ssize_t
2065 y;
2066
2067 p=(const unsigned char *) pixels;
2068 if (LocaleCompare(map,"BGR") == 0)
2069 {
cristycafe0412012-01-10 13:29:58 +00002070 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002071 {
cristycafe0412012-01-10 13:29:58 +00002072 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002073 if (q == (Quantum *) NULL)
2074 break;
cristycafe0412012-01-10 13:29:58 +00002075 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002076 {
2077 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2078 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2079 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2080 q+=GetPixelChannels(image);
2081 }
2082 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2083 break;
2084 }
2085 return;
2086 }
2087 if (LocaleCompare(map,"BGRA") == 0)
2088 {
cristycafe0412012-01-10 13:29:58 +00002089 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002090 {
cristycafe0412012-01-10 13:29:58 +00002091 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002092 if (q == (Quantum *) NULL)
2093 break;
cristycafe0412012-01-10 13:29:58 +00002094 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002095 {
2096 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2097 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2098 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2099 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2100 q+=GetPixelChannels(image);
2101 }
2102 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2103 break;
2104 }
2105 return;
2106 }
2107 if (LocaleCompare(map,"BGRO") == 0)
2108 {
cristycafe0412012-01-10 13:29:58 +00002109 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002110 {
cristycafe0412012-01-10 13:29:58 +00002111 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002112 if (q == (Quantum *) NULL)
2113 break;
cristycafe0412012-01-10 13:29:58 +00002114 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002115 {
2116 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2117 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2118 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2119 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2120 q+=GetPixelChannels(image);
2121 }
2122 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2123 break;
2124 }
2125 return;
2126 }
2127 if (LocaleCompare(map,"BGRP") == 0)
2128 {
cristycafe0412012-01-10 13:29:58 +00002129 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002130 {
cristycafe0412012-01-10 13:29:58 +00002131 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002132 if (q == (Quantum *) NULL)
2133 break;
cristycafe0412012-01-10 13:29:58 +00002134 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002135 {
2136 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2137 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2138 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2139 p++;
2140 q+=GetPixelChannels(image);
2141 }
2142 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2143 break;
2144 }
2145 return;
2146 }
2147 if (LocaleCompare(map,"I") == 0)
2148 {
cristycafe0412012-01-10 13:29:58 +00002149 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002150 {
cristycafe0412012-01-10 13:29:58 +00002151 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002152 if (q == (Quantum *) NULL)
2153 break;
cristycafe0412012-01-10 13:29:58 +00002154 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002155 {
2156 SetPixelGray(image,ScaleCharToQuantum(*p++),q);
2157 q+=GetPixelChannels(image);
2158 }
2159 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2160 break;
2161 }
2162 return;
2163 }
2164 if (LocaleCompare(map,"RGB") == 0)
2165 {
cristycafe0412012-01-10 13:29:58 +00002166 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002167 {
cristycafe0412012-01-10 13:29:58 +00002168 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002169 if (q == (Quantum *) NULL)
2170 break;
cristycafe0412012-01-10 13:29:58 +00002171 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002172 {
2173 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2174 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2175 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2176 q+=GetPixelChannels(image);
2177 }
2178 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2179 break;
2180 }
2181 return;
2182 }
2183 if (LocaleCompare(map,"RGBA") == 0)
2184 {
cristycafe0412012-01-10 13:29:58 +00002185 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002186 {
cristycafe0412012-01-10 13:29:58 +00002187 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002188 if (q == (Quantum *) NULL)
2189 break;
cristycafe0412012-01-10 13:29:58 +00002190 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002191 {
2192 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2193 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2194 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2195 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2196 q+=GetPixelChannels(image);
2197 }
2198 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2199 break;
2200 }
2201 return;
2202 }
2203 if (LocaleCompare(map,"RGBO") == 0)
2204 {
cristycafe0412012-01-10 13:29:58 +00002205 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002206 {
cristycafe0412012-01-10 13:29:58 +00002207 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002208 if (q == (Quantum *) NULL)
2209 break;
cristycafe0412012-01-10 13:29:58 +00002210 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002211 {
2212 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2213 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2214 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2215 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2216 q+=GetPixelChannels(image);
2217 }
2218 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2219 break;
2220 }
2221 return;
2222 }
2223 if (LocaleCompare(map,"RGBP") == 0)
2224 {
cristycafe0412012-01-10 13:29:58 +00002225 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002226 {
cristycafe0412012-01-10 13:29:58 +00002227 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002228 if (q == (Quantum *) NULL)
2229 break;
cristycafe0412012-01-10 13:29:58 +00002230 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002231 {
2232 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2233 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2234 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2235 p++;
2236 q+=GetPixelChannels(image);
2237 }
2238 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2239 break;
2240 }
2241 return;
2242 }
cristycafe0412012-01-10 13:29:58 +00002243 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002244 {
cristycafe0412012-01-10 13:29:58 +00002245 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002246 if (q == (Quantum *) NULL)
2247 break;
cristycafe0412012-01-10 13:29:58 +00002248 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002249 {
2250 register ssize_t
2251 i;
2252
2253 for (i=0; i < (ssize_t) strlen(map); i++)
2254 {
2255 switch (quantum_map[i])
2256 {
2257 case RedQuantum:
2258 case CyanQuantum:
2259 {
2260 SetPixelRed(image,ScaleCharToQuantum(*p),q);
2261 break;
2262 }
2263 case GreenQuantum:
2264 case MagentaQuantum:
2265 {
2266 SetPixelGreen(image,ScaleCharToQuantum(*p),q);
2267 break;
2268 }
2269 case BlueQuantum:
2270 case YellowQuantum:
2271 {
2272 SetPixelBlue(image,ScaleCharToQuantum(*p),q);
2273 break;
2274 }
2275 case AlphaQuantum:
2276 {
2277 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2278 break;
2279 }
2280 case OpacityQuantum:
2281 {
2282 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2283 break;
2284 }
2285 case BlackQuantum:
2286 {
2287 SetPixelBlack(image,ScaleCharToQuantum(*p),q);
2288 break;
2289 }
2290 case IndexQuantum:
2291 {
2292 SetPixelGray(image,ScaleCharToQuantum(*p),q);
2293 break;
2294 }
2295 default:
2296 break;
2297 }
2298 p++;
2299 }
2300 q+=GetPixelChannels(image);
2301 }
2302 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2303 break;
2304 }
2305}
2306
cristycafe0412012-01-10 13:29:58 +00002307static void ImportDoublePixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002308 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2309 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002310{
2311 register const double
2312 *restrict p;
2313
2314 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002315 *restrict q;
cristye5370942012-01-06 03:49:31 +00002316
2317 register ssize_t
2318 x;
2319
2320 ssize_t
2321 y;
2322
2323 p=(const double *) pixels;
2324 if (LocaleCompare(map,"BGR") == 0)
2325 {
cristycafe0412012-01-10 13:29:58 +00002326 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002327 {
cristycafe0412012-01-10 13:29:58 +00002328 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002329 if (q == (Quantum *) NULL)
2330 break;
cristycafe0412012-01-10 13:29:58 +00002331 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002332 {
2333 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2334 (*p)),q);
2335 p++;
2336 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2337 (*p)),q);
2338 p++;
2339 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2340 (*p)),q);
2341 p++;
2342 q+=GetPixelChannels(image);
2343 }
2344 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2345 break;
2346 }
2347 return;
2348 }
2349 if (LocaleCompare(map,"BGRA") == 0)
2350 {
cristycafe0412012-01-10 13:29:58 +00002351 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002352 {
cristycafe0412012-01-10 13:29:58 +00002353 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002354 if (q == (Quantum *) NULL)
2355 break;
cristycafe0412012-01-10 13:29:58 +00002356 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002357 {
2358 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2359 (*p)),q);
2360 p++;
2361 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2362 (*p)),q);
2363 p++;
2364 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2365 (*p)),q);
2366 p++;
2367 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2368 (*p)),q);
2369 p++;
2370 q+=GetPixelChannels(image);
2371 }
2372 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2373 break;
2374 }
2375 return;
2376 }
2377 if (LocaleCompare(map,"BGRP") == 0)
2378 {
cristycafe0412012-01-10 13:29:58 +00002379 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002380 {
cristycafe0412012-01-10 13:29:58 +00002381 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002382 if (q == (Quantum *) NULL)
2383 break;
cristycafe0412012-01-10 13:29:58 +00002384 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002385 {
2386 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2387 (*p)),q);
2388 p++;
2389 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2390 (*p)),q);
2391 p++;
2392 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2393 (*p)),q);
2394 p++;
2395 p++;
2396 q+=GetPixelChannels(image);
2397 }
2398 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2399 break;
2400 }
2401 return;
2402 }
2403 if (LocaleCompare(map,"I") == 0)
2404 {
cristycafe0412012-01-10 13:29:58 +00002405 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002406 {
cristycafe0412012-01-10 13:29:58 +00002407 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002408 if (q == (Quantum *) NULL)
2409 break;
cristycafe0412012-01-10 13:29:58 +00002410 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002411 {
2412 SetPixelGray(image,ClampToQuantum((MagickRealType) QuantumRange*
2413 (*p)),q);
2414 p++;
2415 q+=GetPixelChannels(image);
2416 }
2417 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2418 break;
2419 }
2420 return;
2421 }
2422 if (LocaleCompare(map,"RGB") == 0)
2423 {
cristycafe0412012-01-10 13:29:58 +00002424 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002425 {
cristycafe0412012-01-10 13:29:58 +00002426 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002427 if (q == (Quantum *) NULL)
2428 break;
cristycafe0412012-01-10 13:29:58 +00002429 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002430 {
2431 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2432 (*p)),q);
2433 p++;
2434 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2435 (*p)),q);
2436 p++;
2437 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2438 (*p)),q);
2439 p++;
2440 q+=GetPixelChannels(image);
2441 }
2442 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2443 break;
2444 }
2445 return;
2446 }
2447 if (LocaleCompare(map,"RGBA") == 0)
2448 {
cristycafe0412012-01-10 13:29:58 +00002449 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002450 {
cristycafe0412012-01-10 13:29:58 +00002451 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002452 if (q == (Quantum *) NULL)
2453 break;
cristycafe0412012-01-10 13:29:58 +00002454 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002455 {
2456 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2457 (*p)),q);
2458 p++;
2459 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2460 (*p)),q);
2461 p++;
2462 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2463 (*p)),q);
2464 p++;
2465 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2466 (*p)),q);
2467 p++;
2468 q+=GetPixelChannels(image);
2469 }
2470 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2471 break;
2472 }
2473 return;
2474 }
2475 if (LocaleCompare(map,"RGBP") == 0)
2476 {
cristycafe0412012-01-10 13:29:58 +00002477 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002478 {
cristycafe0412012-01-10 13:29:58 +00002479 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002480 if (q == (Quantum *) NULL)
2481 break;
cristycafe0412012-01-10 13:29:58 +00002482 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002483 {
2484 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2485 (*p)),q);
2486 p++;
2487 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2488 (*p)),q);
2489 p++;
2490 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2491 (*p)),q);
2492 p++;
2493 q+=GetPixelChannels(image);
2494 }
2495 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2496 break;
2497 }
2498 return;
2499 }
cristycafe0412012-01-10 13:29:58 +00002500 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002501 {
cristycafe0412012-01-10 13:29:58 +00002502 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002503 if (q == (Quantum *) NULL)
2504 break;
cristycafe0412012-01-10 13:29:58 +00002505 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002506 {
2507 register ssize_t
2508 i;
2509
2510 for (i=0; i < (ssize_t) strlen(map); i++)
2511 {
2512 switch (quantum_map[i])
2513 {
2514 case RedQuantum:
2515 case CyanQuantum:
2516 {
2517 SetPixelRed(image,ClampToQuantum((MagickRealType)
2518 QuantumRange*(*p)),q);
2519 break;
2520 }
2521 case GreenQuantum:
2522 case MagentaQuantum:
2523 {
2524 SetPixelGreen(image,ClampToQuantum((MagickRealType)
2525 QuantumRange*(*p)),q);
2526 break;
2527 }
2528 case BlueQuantum:
2529 case YellowQuantum:
2530 {
2531 SetPixelBlue(image,ClampToQuantum((MagickRealType)
2532 QuantumRange*(*p)),q);
2533 break;
2534 }
2535 case AlphaQuantum:
2536 {
2537 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2538 QuantumRange*(*p)),q);
2539 break;
2540 }
2541 case OpacityQuantum:
2542 {
2543 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2544 QuantumRange*(*p)),q);
2545 break;
2546 }
2547 case BlackQuantum:
2548 {
2549 SetPixelBlack(image,ClampToQuantum((MagickRealType)
2550 QuantumRange*(*p)),q);
2551 break;
2552 }
2553 case IndexQuantum:
2554 {
2555 SetPixelGray(image,ClampToQuantum((MagickRealType)
2556 QuantumRange*(*p)),q);
2557 break;
2558 }
2559 default:
2560 break;
2561 }
2562 p++;
2563 }
2564 q+=GetPixelChannels(image);
2565 }
2566 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2567 break;
2568 }
2569}
2570
cristycafe0412012-01-10 13:29:58 +00002571static void ImportFloatPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002572 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2573 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002574{
2575 register const float
2576 *restrict p;
2577
2578 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002579 *restrict q;
cristye5370942012-01-06 03:49:31 +00002580
2581 register ssize_t
2582 x;
2583
2584 ssize_t
2585 y;
2586
2587 p=(const float *) pixels;
2588 if (LocaleCompare(map,"BGR") == 0)
2589 {
cristycafe0412012-01-10 13:29:58 +00002590 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002591 {
cristycafe0412012-01-10 13:29:58 +00002592 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002593 if (q == (Quantum *) NULL)
2594 break;
cristycafe0412012-01-10 13:29:58 +00002595 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002596 {
2597 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2598 (*p)),q);
2599 p++;
2600 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2601 (*p)),q);
2602 p++;
2603 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2604 (*p)),q);
2605 p++;
2606 q+=GetPixelChannels(image);
2607 }
2608 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2609 break;
2610 }
2611 return;
2612 }
2613 if (LocaleCompare(map,"BGRA") == 0)
2614 {
cristycafe0412012-01-10 13:29:58 +00002615 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002616 {
cristycafe0412012-01-10 13:29:58 +00002617 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002618 if (q == (Quantum *) NULL)
2619 break;
cristycafe0412012-01-10 13:29:58 +00002620 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002621 {
2622 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2623 (*p)),q);
2624 p++;
2625 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2626 (*p)),q);
2627 p++;
2628 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2629 (*p)),q);
2630 p++;
2631 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2632 (*p)),q);
2633 p++;
2634 q+=GetPixelChannels(image);
2635 }
2636 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2637 break;
2638 }
2639 return;
2640 }
2641 if (LocaleCompare(map,"BGRP") == 0)
2642 {
cristycafe0412012-01-10 13:29:58 +00002643 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002644 {
cristycafe0412012-01-10 13:29:58 +00002645 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002646 if (q == (Quantum *) NULL)
2647 break;
cristycafe0412012-01-10 13:29:58 +00002648 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002649 {
2650 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2651 (*p)),q);
2652 p++;
2653 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2654 (*p)),q);
2655 p++;
2656 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2657 (*p)),q);
2658 p++;
2659 p++;
2660 q+=GetPixelChannels(image);
2661 }
2662 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2663 break;
2664 }
2665 return;
2666 }
2667 if (LocaleCompare(map,"I") == 0)
2668 {
cristycafe0412012-01-10 13:29:58 +00002669 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002670 {
cristycafe0412012-01-10 13:29:58 +00002671 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002672 if (q == (Quantum *) NULL)
2673 break;
cristycafe0412012-01-10 13:29:58 +00002674 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002675 {
2676 SetPixelGray(image,ClampToQuantum((MagickRealType) QuantumRange*
2677 (*p)),q);
2678 p++;
2679 q+=GetPixelChannels(image);
2680 }
2681 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2682 break;
2683 }
2684 return;
2685 }
2686 if (LocaleCompare(map,"RGB") == 0)
2687 {
cristycafe0412012-01-10 13:29:58 +00002688 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002689 {
cristycafe0412012-01-10 13:29:58 +00002690 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002691 if (q == (Quantum *) NULL)
2692 break;
cristycafe0412012-01-10 13:29:58 +00002693 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002694 {
2695 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2696 (*p)),q);
2697 p++;
2698 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2699 (*p)),q);
2700 p++;
2701 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2702 (*p)),q);
2703 p++;
2704 q+=GetPixelChannels(image);
2705 }
2706 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2707 break;
2708 }
2709 return;
2710 }
2711 if (LocaleCompare(map,"RGBA") == 0)
2712 {
cristycafe0412012-01-10 13:29:58 +00002713 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002714 {
cristycafe0412012-01-10 13:29:58 +00002715 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002716 if (q == (Quantum *) NULL)
2717 break;
cristycafe0412012-01-10 13:29:58 +00002718 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002719 {
2720 SetPixelRed(image,ClampToQuantum((MagickRealType)
2721 QuantumRange*(*p)),q);
2722 p++;
2723 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2724 (*p)),q);
2725 p++;
2726 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2727 (*p)),q);
2728 p++;
2729 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2730 (*p)),q);
2731 p++;
2732 q+=GetPixelChannels(image);
2733 }
2734 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2735 break;
2736 }
2737 return;
2738 }
2739 if (LocaleCompare(map,"RGBP") == 0)
2740 {
cristycafe0412012-01-10 13:29:58 +00002741 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002742 {
cristycafe0412012-01-10 13:29:58 +00002743 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002744 if (q == (Quantum *) NULL)
2745 break;
cristycafe0412012-01-10 13:29:58 +00002746 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002747 {
2748 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2749 (*p)),q);
2750 p++;
2751 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2752 (*p)),q);
2753 p++;
2754 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2755 (*p)),q);
2756 p++;
2757 q+=GetPixelChannels(image);
2758 }
2759 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2760 break;
2761 }
2762 return;
2763 }
cristycafe0412012-01-10 13:29:58 +00002764 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002765 {
cristycafe0412012-01-10 13:29:58 +00002766 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002767 if (q == (Quantum *) NULL)
2768 break;
cristycafe0412012-01-10 13:29:58 +00002769 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002770 {
2771 register ssize_t
2772 i;
2773
2774 for (i=0; i < (ssize_t) strlen(map); i++)
2775 {
2776 switch (quantum_map[i])
2777 {
2778 case RedQuantum:
2779 case CyanQuantum:
2780 {
2781 SetPixelRed(image,ClampToQuantum((MagickRealType)
2782 QuantumRange*(*p)),q);
2783 break;
2784 }
2785 case GreenQuantum:
2786 case MagentaQuantum:
2787 {
2788 SetPixelGreen(image,ClampToQuantum((MagickRealType)
2789 QuantumRange*(*p)),q);
2790 break;
2791 }
2792 case BlueQuantum:
2793 case YellowQuantum:
2794 {
2795 SetPixelBlue(image,ClampToQuantum((MagickRealType)
2796 QuantumRange*(*p)),q);
2797 break;
2798 }
2799 case AlphaQuantum:
2800 {
2801 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2802 QuantumRange*(*p)),q);
2803 break;
2804 }
2805 case OpacityQuantum:
2806 {
2807 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2808 QuantumRange*(*p)),q);
2809 break;
2810 }
2811 case BlackQuantum:
2812 {
2813 SetPixelBlack(image,ClampToQuantum((MagickRealType)
2814 QuantumRange*(*p)),q);
2815 break;
2816 }
2817 case IndexQuantum:
2818 {
2819 SetPixelGray(image,ClampToQuantum((MagickRealType)
2820 QuantumRange*(*p)),q);
2821 break;
2822 }
2823 default:
2824 break;
2825 }
2826 p++;
2827 }
2828 q+=GetPixelChannels(image);
2829 }
2830 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2831 break;
2832 }
2833}
2834
cristycafe0412012-01-10 13:29:58 +00002835static void ImportLongPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002836 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2837 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002838{
2839 register const unsigned int
2840 *restrict p;
2841
2842 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002843 *restrict q;
cristye5370942012-01-06 03:49:31 +00002844
2845 register ssize_t
2846 x;
2847
2848 ssize_t
2849 y;
2850
2851 p=(const unsigned int *) pixels;
2852 if (LocaleCompare(map,"BGR") == 0)
2853 {
cristycafe0412012-01-10 13:29:58 +00002854 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002855 {
cristycafe0412012-01-10 13:29:58 +00002856 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002857 if (q == (Quantum *) NULL)
2858 break;
cristycafe0412012-01-10 13:29:58 +00002859 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002860 {
2861 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2862 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2863 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2864 q+=GetPixelChannels(image);
2865 }
2866 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2867 break;
2868 }
2869 return;
2870 }
2871 if (LocaleCompare(map,"BGRA") == 0)
2872 {
cristycafe0412012-01-10 13:29:58 +00002873 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002874 {
cristycafe0412012-01-10 13:29:58 +00002875 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002876 if (q == (Quantum *) NULL)
2877 break;
cristycafe0412012-01-10 13:29:58 +00002878 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002879 {
2880 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2881 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2882 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2883 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
2884 q+=GetPixelChannels(image);
2885 }
2886 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2887 break;
2888 }
2889 return;
2890 }
2891 if (LocaleCompare(map,"BGRP") == 0)
2892 {
cristycafe0412012-01-10 13:29:58 +00002893 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002894 {
cristycafe0412012-01-10 13:29:58 +00002895 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002896 if (q == (Quantum *) NULL)
2897 break;
cristycafe0412012-01-10 13:29:58 +00002898 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002899 {
2900 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2901 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2902 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2903 p++;
2904 q+=GetPixelChannels(image);
2905 }
2906 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2907 break;
2908 }
2909 return;
2910 }
2911 if (LocaleCompare(map,"I") == 0)
2912 {
cristycafe0412012-01-10 13:29:58 +00002913 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002914 {
cristycafe0412012-01-10 13:29:58 +00002915 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002916 if (q == (Quantum *) NULL)
2917 break;
cristycafe0412012-01-10 13:29:58 +00002918 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002919 {
2920 SetPixelGray(image,ScaleLongToQuantum(*p++),q);
2921 q+=GetPixelChannels(image);
2922 }
2923 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2924 break;
2925 }
2926 return;
2927 }
2928 if (LocaleCompare(map,"RGB") == 0)
2929 {
cristycafe0412012-01-10 13:29:58 +00002930 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002931 {
cristycafe0412012-01-10 13:29:58 +00002932 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002933 if (q == (Quantum *) NULL)
2934 break;
cristycafe0412012-01-10 13:29:58 +00002935 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002936 {
2937 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2938 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2939 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2940 q+=GetPixelChannels(image);
2941 }
2942 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2943 break;
2944 }
2945 return;
2946 }
2947 if (LocaleCompare(map,"RGBA") == 0)
2948 {
cristycafe0412012-01-10 13:29:58 +00002949 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002950 {
cristycafe0412012-01-10 13:29:58 +00002951 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002952 if (q == (Quantum *) NULL)
2953 break;
cristycafe0412012-01-10 13:29:58 +00002954 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002955 {
2956 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2957 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2958 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2959 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
2960 q+=GetPixelChannels(image);
2961 }
2962 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2963 break;
2964 }
2965 return;
2966 }
2967 if (LocaleCompare(map,"RGBP") == 0)
2968 {
cristycafe0412012-01-10 13:29:58 +00002969 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002970 {
cristycafe0412012-01-10 13:29:58 +00002971 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002972 if (q == (Quantum *) NULL)
2973 break;
cristycafe0412012-01-10 13:29:58 +00002974 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002975 {
2976 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2977 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2978 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2979 p++;
2980 q+=GetPixelChannels(image);
2981 }
2982 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2983 break;
2984 }
2985 return;
2986 }
cristycafe0412012-01-10 13:29:58 +00002987 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002988 {
cristycafe0412012-01-10 13:29:58 +00002989 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002990 if (q == (Quantum *) NULL)
2991 break;
cristycafe0412012-01-10 13:29:58 +00002992 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002993 {
2994 register ssize_t
2995 i;
2996
2997 for (i=0; i < (ssize_t) strlen(map); i++)
2998 {
2999 switch (quantum_map[i])
3000 {
3001 case RedQuantum:
3002 case CyanQuantum:
3003 {
3004 SetPixelRed(image,ScaleLongToQuantum(*p),q);
3005 break;
3006 }
3007 case GreenQuantum:
3008 case MagentaQuantum:
3009 {
3010 SetPixelGreen(image,ScaleLongToQuantum(*p),q);
3011 break;
3012 }
3013 case BlueQuantum:
3014 case YellowQuantum:
3015 {
3016 SetPixelBlue(image,ScaleLongToQuantum(*p),q);
3017 break;
3018 }
3019 case AlphaQuantum:
3020 {
3021 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3022 break;
3023 }
3024 case OpacityQuantum:
3025 {
3026 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3027 break;
3028 }
3029 case BlackQuantum:
3030 {
3031 SetPixelBlack(image,ScaleLongToQuantum(*p),q);
3032 break;
3033 }
3034 case IndexQuantum:
3035 {
3036 SetPixelGray(image,ScaleLongToQuantum(*p),q);
3037 break;
3038 }
3039 default:
3040 break;
3041 }
3042 p++;
3043 }
3044 q+=GetPixelChannels(image);
3045 }
3046 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3047 break;
3048 }
3049}
3050
cristycafe0412012-01-10 13:29:58 +00003051static void ImportLongLongPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003052 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3053 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003054{
cristyb13e12a2012-01-06 21:48:27 +00003055 register const MagickSizeType
cristye5370942012-01-06 03:49:31 +00003056 *restrict p;
3057
3058 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003059 *restrict q;
cristye5370942012-01-06 03:49:31 +00003060
3061 register ssize_t
3062 x;
3063
3064 ssize_t
3065 y;
3066
cristyb13e12a2012-01-06 21:48:27 +00003067 p=(const MagickSizeType *) pixels;
cristye5370942012-01-06 03:49:31 +00003068 if (LocaleCompare(map,"BGR") == 0)
3069 {
cristycafe0412012-01-10 13:29:58 +00003070 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003071 {
cristycafe0412012-01-10 13:29:58 +00003072 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003073 if (q == (Quantum *) NULL)
3074 break;
cristycafe0412012-01-10 13:29:58 +00003075 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003076 {
cristyb13e12a2012-01-06 21:48:27 +00003077 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3078 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3079 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003080 q+=GetPixelChannels(image);
3081 }
3082 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3083 break;
3084 }
3085 return;
3086 }
3087 if (LocaleCompare(map,"BGRA") == 0)
3088 {
cristycafe0412012-01-10 13:29:58 +00003089 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003090 {
cristycafe0412012-01-10 13:29:58 +00003091 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003092 if (q == (Quantum *) NULL)
3093 break;
cristycafe0412012-01-10 13:29:58 +00003094 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003095 {
cristyb13e12a2012-01-06 21:48:27 +00003096 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3097 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3098 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3099 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003100 q+=GetPixelChannels(image);
3101 }
3102 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3103 break;
3104 }
3105 return;
3106 }
3107 if (LocaleCompare(map,"BGRP") == 0)
3108 {
cristycafe0412012-01-10 13:29:58 +00003109 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003110 {
cristycafe0412012-01-10 13:29:58 +00003111 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003112 if (q == (Quantum *) NULL)
3113 break;
cristycafe0412012-01-10 13:29:58 +00003114 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003115 {
cristyb13e12a2012-01-06 21:48:27 +00003116 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3117 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3118 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003119 p++;
3120 q+=GetPixelChannels(image);
3121 }
3122 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3123 break;
3124 }
3125 return;
3126 }
3127 if (LocaleCompare(map,"I") == 0)
3128 {
cristycafe0412012-01-10 13:29:58 +00003129 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003130 {
cristycafe0412012-01-10 13:29:58 +00003131 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003132 if (q == (Quantum *) NULL)
3133 break;
cristycafe0412012-01-10 13:29:58 +00003134 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003135 {
cristyb13e12a2012-01-06 21:48:27 +00003136 SetPixelGray(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003137 q+=GetPixelChannels(image);
3138 }
3139 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3140 break;
3141 }
3142 return;
3143 }
3144 if (LocaleCompare(map,"RGB") == 0)
3145 {
cristycafe0412012-01-10 13:29:58 +00003146 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003147 {
cristycafe0412012-01-10 13:29:58 +00003148 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003149 if (q == (Quantum *) NULL)
3150 break;
cristycafe0412012-01-10 13:29:58 +00003151 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003152 {
cristyb13e12a2012-01-06 21:48:27 +00003153 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3154 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3155 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003156 q+=GetPixelChannels(image);
3157 }
3158 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3159 break;
3160 }
3161 return;
3162 }
3163 if (LocaleCompare(map,"RGBA") == 0)
3164 {
cristycafe0412012-01-10 13:29:58 +00003165 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003166 {
cristycafe0412012-01-10 13:29:58 +00003167 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003168 if (q == (Quantum *) NULL)
3169 break;
cristycafe0412012-01-10 13:29:58 +00003170 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003171 {
cristyb13e12a2012-01-06 21:48:27 +00003172 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3173 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3174 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3175 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003176 q+=GetPixelChannels(image);
3177 }
3178 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3179 break;
3180 }
3181 return;
3182 }
3183 if (LocaleCompare(map,"RGBP") == 0)
3184 {
cristycafe0412012-01-10 13:29:58 +00003185 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003186 {
cristycafe0412012-01-10 13:29:58 +00003187 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003188 if (q == (Quantum *) NULL)
3189 break;
cristycafe0412012-01-10 13:29:58 +00003190 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003191 {
cristyb13e12a2012-01-06 21:48:27 +00003192 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3193 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3194 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003195 p++;
3196 q+=GetPixelChannels(image);
3197 }
3198 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3199 break;
3200 }
3201 return;
3202 }
cristycafe0412012-01-10 13:29:58 +00003203 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003204 {
cristycafe0412012-01-10 13:29:58 +00003205 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003206 if (q == (Quantum *) NULL)
3207 break;
cristycafe0412012-01-10 13:29:58 +00003208 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003209 {
3210 register ssize_t
3211 i;
3212
3213 for (i=0; i < (ssize_t) strlen(map); i++)
3214 {
3215 switch (quantum_map[i])
3216 {
3217 case RedQuantum:
3218 case CyanQuantum:
3219 {
cristyb13e12a2012-01-06 21:48:27 +00003220 SetPixelRed(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003221 break;
3222 }
3223 case GreenQuantum:
3224 case MagentaQuantum:
3225 {
cristyb13e12a2012-01-06 21:48:27 +00003226 SetPixelGreen(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003227 break;
3228 }
3229 case BlueQuantum:
3230 case YellowQuantum:
3231 {
cristyb13e12a2012-01-06 21:48:27 +00003232 SetPixelBlue(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003233 break;
3234 }
3235 case AlphaQuantum:
3236 {
cristyb13e12a2012-01-06 21:48:27 +00003237 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003238 break;
3239 }
3240 case OpacityQuantum:
3241 {
cristyb13e12a2012-01-06 21:48:27 +00003242 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003243 break;
3244 }
3245 case BlackQuantum:
3246 {
cristyb13e12a2012-01-06 21:48:27 +00003247 SetPixelBlack(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003248 break;
3249 }
3250 case IndexQuantum:
3251 {
cristyb13e12a2012-01-06 21:48:27 +00003252 SetPixelGray(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003253 break;
3254 }
3255 default:
3256 break;
3257 }
3258 p++;
3259 }
3260 q+=GetPixelChannels(image);
3261 }
3262 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3263 break;
3264 }
3265}
3266
cristycafe0412012-01-10 13:29:58 +00003267static void ImportQuantumPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003268 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3269 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003270{
3271 register const Quantum
3272 *restrict p;
3273
3274 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003275 *restrict q;
cristye5370942012-01-06 03:49:31 +00003276
3277 register ssize_t
3278 x;
3279
3280 ssize_t
3281 y;
3282
3283 p=(const Quantum *) pixels;
3284 if (LocaleCompare(map,"BGR") == 0)
3285 {
cristycafe0412012-01-10 13:29:58 +00003286 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003287 {
cristycafe0412012-01-10 13:29:58 +00003288 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003289 if (q == (Quantum *) NULL)
3290 break;
cristycafe0412012-01-10 13:29:58 +00003291 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003292 {
3293 SetPixelBlue(image,*p++,q);
3294 SetPixelGreen(image,*p++,q);
3295 SetPixelRed(image,*p++,q);
3296 q+=GetPixelChannels(image);
3297 }
3298 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3299 break;
3300 }
3301 return;
3302 }
3303 if (LocaleCompare(map,"BGRA") == 0)
3304 {
cristycafe0412012-01-10 13:29:58 +00003305 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003306 {
cristycafe0412012-01-10 13:29:58 +00003307 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003308 if (q == (Quantum *) NULL)
3309 break;
cristycafe0412012-01-10 13:29:58 +00003310 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003311 {
3312 SetPixelBlue(image,*p++,q);
3313 SetPixelGreen(image,*p++,q);
3314 SetPixelRed(image,*p++,q);
3315 SetPixelAlpha(image,*p++,q);
3316 q+=GetPixelChannels(image);
3317 }
3318 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3319 break;
3320 }
3321 return;
3322 }
3323 if (LocaleCompare(map,"BGRP") == 0)
3324 {
cristycafe0412012-01-10 13:29:58 +00003325 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003326 {
cristycafe0412012-01-10 13:29:58 +00003327 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003328 if (q == (Quantum *) NULL)
3329 break;
cristycafe0412012-01-10 13:29:58 +00003330 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003331 {
3332 SetPixelBlue(image,*p++,q);
3333 SetPixelGreen(image,*p++,q);
3334 SetPixelRed(image,*p++,q);
3335 p++;
3336 q+=GetPixelChannels(image);
3337 }
3338 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3339 break;
3340 }
3341 return;
3342 }
3343 if (LocaleCompare(map,"I") == 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 SetPixelGray(image,*p++,q);
3353 q+=GetPixelChannels(image);
3354 }
3355 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3356 break;
3357 }
3358 return;
3359 }
3360 if (LocaleCompare(map,"RGB") == 0)
3361 {
cristycafe0412012-01-10 13:29:58 +00003362 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003363 {
cristycafe0412012-01-10 13:29:58 +00003364 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003365 if (q == (Quantum *) NULL)
3366 break;
cristycafe0412012-01-10 13:29:58 +00003367 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003368 {
3369 SetPixelRed(image,*p++,q);
3370 SetPixelGreen(image,*p++,q);
3371 SetPixelBlue(image,*p++,q);
3372 q+=GetPixelChannels(image);
3373 }
3374 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3375 break;
3376 }
3377 return;
3378 }
3379 if (LocaleCompare(map,"RGBA") == 0)
3380 {
cristycafe0412012-01-10 13:29:58 +00003381 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003382 {
cristycafe0412012-01-10 13:29:58 +00003383 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003384 if (q == (Quantum *) NULL)
3385 break;
cristycafe0412012-01-10 13:29:58 +00003386 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003387 {
3388 SetPixelRed(image,*p++,q);
3389 SetPixelGreen(image,*p++,q);
3390 SetPixelBlue(image,*p++,q);
3391 SetPixelAlpha(image,*p++,q);
3392 q+=GetPixelChannels(image);
3393 }
3394 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3395 break;
3396 }
3397 return;
3398 }
3399 if (LocaleCompare(map,"RGBP") == 0)
3400 {
cristycafe0412012-01-10 13:29:58 +00003401 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003402 {
cristycafe0412012-01-10 13:29:58 +00003403 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003404 if (q == (Quantum *) NULL)
3405 break;
cristycafe0412012-01-10 13:29:58 +00003406 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003407 {
3408 SetPixelRed(image,*p++,q);
3409 SetPixelGreen(image,*p++,q);
3410 SetPixelBlue(image,*p++,q);
3411 p++;
3412 q+=GetPixelChannels(image);
3413 }
3414 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3415 break;
3416 }
3417 return;
3418 }
cristycafe0412012-01-10 13:29:58 +00003419 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003420 {
cristycafe0412012-01-10 13:29:58 +00003421 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003422 if (q == (Quantum *) NULL)
3423 break;
cristycafe0412012-01-10 13:29:58 +00003424 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003425 {
3426 register ssize_t
3427 i;
3428
3429 for (i=0; i < (ssize_t) strlen(map); i++)
3430 {
3431 switch (quantum_map[i])
3432 {
3433 case RedQuantum:
3434 case CyanQuantum:
3435 {
3436 SetPixelRed(image,*p,q);
3437 break;
3438 }
3439 case GreenQuantum:
3440 case MagentaQuantum:
3441 {
3442 SetPixelGreen(image,*p,q);
3443 break;
3444 }
3445 case BlueQuantum:
3446 case YellowQuantum:
3447 {
3448 SetPixelBlue(image,*p,q);
3449 break;
3450 }
3451 case AlphaQuantum:
3452 {
3453 SetPixelAlpha(image,*p,q);
3454 break;
3455 }
3456 case OpacityQuantum:
3457 {
3458 SetPixelAlpha(image,*p,q);
3459 break;
3460 }
3461 case BlackQuantum:
3462 {
3463 SetPixelBlack(image,*p,q);
3464 break;
3465 }
3466 case IndexQuantum:
3467 {
3468 SetPixelGray(image,*p,q);
3469 break;
3470 }
3471 default:
3472 break;
3473 }
3474 p++;
3475 }
3476 q+=GetPixelChannels(image);
3477 }
3478 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3479 break;
3480 }
3481}
3482
cristycafe0412012-01-10 13:29:58 +00003483static void ImportShortPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003484 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3485 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003486{
3487 register const unsigned short
3488 *restrict p;
3489
3490 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003491 *restrict q;
cristye5370942012-01-06 03:49:31 +00003492
3493 register ssize_t
3494 x;
3495
3496 ssize_t
3497 y;
3498
3499 p=(const unsigned short *) pixels;
3500 if (LocaleCompare(map,"BGR") == 0)
3501 {
cristycafe0412012-01-10 13:29:58 +00003502 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003503 {
cristycafe0412012-01-10 13:29:58 +00003504 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003505 if (q == (Quantum *) NULL)
3506 break;
cristycafe0412012-01-10 13:29:58 +00003507 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003508 {
3509 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3510 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3511 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3512 q+=GetPixelChannels(image);
3513 }
3514 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3515 break;
3516 }
3517 return;
3518 }
3519 if (LocaleCompare(map,"BGRA") == 0)
3520 {
cristycafe0412012-01-10 13:29:58 +00003521 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003522 {
cristycafe0412012-01-10 13:29:58 +00003523 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003524 if (q == (Quantum *) NULL)
3525 break;
cristycafe0412012-01-10 13:29:58 +00003526 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003527 {
3528 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3529 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3530 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3531 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3532 q+=GetPixelChannels(image);
3533 }
3534 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3535 break;
3536 }
3537 return;
3538 }
3539 if (LocaleCompare(map,"BGRP") == 0)
3540 {
cristycafe0412012-01-10 13:29:58 +00003541 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003542 {
cristycafe0412012-01-10 13:29:58 +00003543 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003544 if (q == (Quantum *) NULL)
3545 break;
cristycafe0412012-01-10 13:29:58 +00003546 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003547 {
3548 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3549 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3550 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3551 p++;
3552 q+=GetPixelChannels(image);
3553 }
3554 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3555 break;
3556 }
3557 return;
3558 }
3559 if (LocaleCompare(map,"I") == 0)
3560 {
cristycafe0412012-01-10 13:29:58 +00003561 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003562 {
cristycafe0412012-01-10 13:29:58 +00003563 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003564 if (q == (Quantum *) NULL)
3565 break;
cristycafe0412012-01-10 13:29:58 +00003566 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003567 {
3568 SetPixelGray(image,ScaleShortToQuantum(*p++),q);
3569 q+=GetPixelChannels(image);
3570 }
3571 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3572 break;
3573 }
3574 return;
3575 }
3576 if (LocaleCompare(map,"RGB") == 0)
3577 {
cristycafe0412012-01-10 13:29:58 +00003578 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003579 {
cristycafe0412012-01-10 13:29:58 +00003580 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003581 if (q == (Quantum *) NULL)
3582 break;
cristycafe0412012-01-10 13:29:58 +00003583 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003584 {
3585 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3586 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3587 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3588 q+=GetPixelChannels(image);
3589 }
3590 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3591 break;
3592 }
3593 return;
3594 }
3595 if (LocaleCompare(map,"RGBA") == 0)
3596 {
cristycafe0412012-01-10 13:29:58 +00003597 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003598 {
cristycafe0412012-01-10 13:29:58 +00003599 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003600 if (q == (Quantum *) NULL)
3601 break;
cristycafe0412012-01-10 13:29:58 +00003602 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003603 {
3604 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3605 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3606 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3607 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3608 q+=GetPixelChannels(image);
3609 }
3610 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3611 break;
3612 }
3613 return;
3614 }
3615 if (LocaleCompare(map,"RGBP") == 0)
3616 {
cristycafe0412012-01-10 13:29:58 +00003617 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003618 {
cristycafe0412012-01-10 13:29:58 +00003619 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003620 if (q == (Quantum *) NULL)
3621 break;
cristycafe0412012-01-10 13:29:58 +00003622 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003623 {
3624 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3625 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3626 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3627 p++;
3628 q+=GetPixelChannels(image);
3629 }
3630 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3631 break;
3632 }
3633 return;
3634 }
cristycafe0412012-01-10 13:29:58 +00003635 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003636 {
cristycafe0412012-01-10 13:29:58 +00003637 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003638 if (q == (Quantum *) NULL)
3639 break;
cristycafe0412012-01-10 13:29:58 +00003640 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003641 {
3642 register ssize_t
3643 i;
3644
3645 for (i=0; i < (ssize_t) strlen(map); i++)
3646 {
3647 switch (quantum_map[i])
3648 {
3649 case RedQuantum:
3650 case CyanQuantum:
3651 {
3652 SetPixelRed(image,ScaleShortToQuantum(*p),q);
3653 break;
3654 }
3655 case GreenQuantum:
3656 case MagentaQuantum:
3657 {
3658 SetPixelGreen(image,ScaleShortToQuantum(*p),q);
3659 break;
3660 }
3661 case BlueQuantum:
3662 case YellowQuantum:
3663 {
3664 SetPixelBlue(image,ScaleShortToQuantum(*p),q);
3665 break;
3666 }
3667 case AlphaQuantum:
3668 {
3669 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
3670 break;
3671 }
3672 case OpacityQuantum:
3673 {
3674 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
3675 break;
3676 }
3677 case BlackQuantum:
3678 {
3679 SetPixelBlack(image,ScaleShortToQuantum(*p),q);
3680 break;
3681 }
3682 case IndexQuantum:
3683 {
3684 SetPixelGray(image,ScaleShortToQuantum(*p),q);
3685 break;
3686 }
3687 default:
3688 break;
3689 }
3690 p++;
3691 }
3692 q+=GetPixelChannels(image);
3693 }
3694 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3695 break;
3696 }
3697}
3698
cristycafe0412012-01-10 13:29:58 +00003699MagickExport MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
3700 const ssize_t y,const size_t width,const size_t height,const char *map,
3701 const StorageType type,const void *pixels,ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00003702{
cristy4c08aed2011-07-01 19:47:50 +00003703 QuantumType
3704 *quantum_map;
3705
cristycafe0412012-01-10 13:29:58 +00003706 RectangleInfo
3707 roi;
3708
cristy4c08aed2011-07-01 19:47:50 +00003709 register ssize_t
cristye5370942012-01-06 03:49:31 +00003710 i;
cristy4c08aed2011-07-01 19:47:50 +00003711
3712 /*
3713 Allocate image structure.
3714 */
3715 assert(image != (Image *) NULL);
3716 assert(image->signature == MagickSignature);
3717 if (image->debug != MagickFalse)
3718 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristye5370942012-01-06 03:49:31 +00003719 quantum_map=(QuantumType *) AcquireQuantumMemory(strlen(map),
3720 sizeof(*quantum_map));
cristy4c08aed2011-07-01 19:47:50 +00003721 if (quantum_map == (QuantumType *) NULL)
3722 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
3723 image->filename);
cristye5370942012-01-06 03:49:31 +00003724 for (i=0; i < (ssize_t) strlen(map); i++)
cristy4c08aed2011-07-01 19:47:50 +00003725 {
3726 switch (map[i])
3727 {
3728 case 'a':
3729 case 'A':
3730 {
3731 quantum_map[i]=AlphaQuantum;
3732 image->matte=MagickTrue;
3733 break;
3734 }
3735 case 'B':
3736 case 'b':
3737 {
3738 quantum_map[i]=BlueQuantum;
3739 break;
3740 }
3741 case 'C':
3742 case 'c':
3743 {
3744 quantum_map[i]=CyanQuantum;
cristy63240882011-08-05 19:05:27 +00003745 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003746 break;
3747 }
3748 case 'g':
3749 case 'G':
3750 {
3751 quantum_map[i]=GreenQuantum;
3752 break;
3753 }
3754 case 'K':
3755 case 'k':
3756 {
3757 quantum_map[i]=BlackQuantum;
cristy63240882011-08-05 19:05:27 +00003758 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003759 break;
3760 }
3761 case 'I':
3762 case 'i':
3763 {
3764 quantum_map[i]=IndexQuantum;
3765 break;
3766 }
3767 case 'm':
3768 case 'M':
3769 {
3770 quantum_map[i]=MagentaQuantum;
cristy63240882011-08-05 19:05:27 +00003771 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003772 break;
3773 }
3774 case 'O':
3775 case 'o':
3776 {
3777 quantum_map[i]=OpacityQuantum;
3778 image->matte=MagickTrue;
3779 break;
3780 }
3781 case 'P':
3782 case 'p':
3783 {
3784 quantum_map[i]=UndefinedQuantum;
3785 break;
3786 }
3787 case 'R':
3788 case 'r':
3789 {
3790 quantum_map[i]=RedQuantum;
3791 break;
3792 }
3793 case 'Y':
3794 case 'y':
3795 {
3796 quantum_map[i]=YellowQuantum;
cristy63240882011-08-05 19:05:27 +00003797 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003798 break;
3799 }
3800 default:
3801 {
3802 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
cristy63240882011-08-05 19:05:27 +00003803 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthonye5b39652012-04-21 05:37:29 +00003804 "UnrecognizedPixelMap","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00003805 return(MagickFalse);
3806 }
3807 }
3808 }
cristy63240882011-08-05 19:05:27 +00003809 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
cristy4c08aed2011-07-01 19:47:50 +00003810 return(MagickFalse);
3811 /*
cristye5370942012-01-06 03:49:31 +00003812 Transfer the pixels from the pixel data to the image.
cristy4c08aed2011-07-01 19:47:50 +00003813 */
cristycafe0412012-01-10 13:29:58 +00003814 roi.width=width;
3815 roi.height=height;
3816 roi.x=x;
3817 roi.y=y;
cristy4c08aed2011-07-01 19:47:50 +00003818 switch (type)
3819 {
3820 case CharPixel:
3821 {
cristycafe0412012-01-10 13:29:58 +00003822 ImportCharPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003823 break;
3824 }
3825 case DoublePixel:
3826 {
cristycafe0412012-01-10 13:29:58 +00003827 ImportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003828 break;
3829 }
3830 case FloatPixel:
3831 {
cristycafe0412012-01-10 13:29:58 +00003832 ImportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003833 break;
3834 }
cristy4c08aed2011-07-01 19:47:50 +00003835 case LongPixel:
3836 {
cristycafe0412012-01-10 13:29:58 +00003837 ImportLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003838 break;
3839 }
cristy6c9e1682012-01-07 21:37:44 +00003840 case LongLongPixel:
3841 {
cristycafe0412012-01-10 13:29:58 +00003842 ImportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy6c9e1682012-01-07 21:37:44 +00003843 break;
3844 }
cristy4c08aed2011-07-01 19:47:50 +00003845 case QuantumPixel:
3846 {
cristycafe0412012-01-10 13:29:58 +00003847 ImportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003848 break;
3849 }
3850 case ShortPixel:
3851 {
cristycafe0412012-01-10 13:29:58 +00003852 ImportShortPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003853 break;
3854 }
3855 default:
3856 {
3857 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
cristyc82a27b2011-10-21 01:07:16 +00003858 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthonye5b39652012-04-21 05:37:29 +00003859 "UnrecognizedPixelMap","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00003860 break;
3861 }
3862 }
3863 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
3864 return(MagickTrue);
3865}
3866
3867/*
3868%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3869% %
3870% %
3871% %
cristybd5a96c2011-08-21 00:04:26 +00003872+ 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 %
3873% %
3874% %
3875% %
3876%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3877%
3878% InitializePixelChannelMap() defines the standard pixel component map.
3879%
3880% The format of the InitializePixelChannelMap() method is:
3881%
3882% void InitializePixelChannelMap(Image *image)
3883%
3884% A description of each parameter follows:
3885%
3886% o image: the image.
3887%
3888*/
cristye2a912b2011-12-05 20:02:07 +00003889MagickExport void InitializePixelChannelMap(Image *image)
cristy77c30f52011-10-24 18:56:57 +00003890{
cristye2a912b2011-12-05 20:02:07 +00003891 PixelTrait
3892 trait;
3893
cristy77c30f52011-10-24 18:56:57 +00003894 register ssize_t
3895 i;
3896
cristyd26338f2011-12-14 02:39:30 +00003897 ssize_t
cristy77c30f52011-10-24 18:56:57 +00003898 n;
3899
3900 assert(image != (Image *) NULL);
3901 assert(image->signature == MagickSignature);
cristye2a912b2011-12-05 20:02:07 +00003902 (void) ResetMagickMemory(image->channel_map,0,MaxPixelChannels*
3903 sizeof(*image->channel_map));
3904 trait=UpdatePixelTrait;
3905 if (image->matte != MagickFalse)
cristy61f18ad2011-12-08 21:12:37 +00003906 trait=(PixelTrait) (trait | BlendPixelTrait);
cristy77c30f52011-10-24 18:56:57 +00003907 n=0;
cristyc06c5802011-12-31 23:36:16 +00003908 if (image->colorspace == GRAYColorspace)
cristy77c30f52011-10-24 18:56:57 +00003909 {
cristy3c316282011-12-15 15:43:24 +00003910 SetPixelChannelMap(image,BluePixelChannel,trait,n);
cristye2a912b2011-12-05 20:02:07 +00003911 SetPixelChannelMap(image,GreenPixelChannel,trait,n);
cristy3c316282011-12-15 15:43:24 +00003912 SetPixelChannelMap(image,RedPixelChannel,trait,n++);
3913 }
3914 else
3915 {
3916 SetPixelChannelMap(image,RedPixelChannel,trait,n++);
3917 SetPixelChannelMap(image,GreenPixelChannel,trait,n++);
cristye2a912b2011-12-05 20:02:07 +00003918 SetPixelChannelMap(image,BluePixelChannel,trait,n++);
cristy77c30f52011-10-24 18:56:57 +00003919 }
3920 if (image->colorspace == CMYKColorspace)
cristye2a912b2011-12-05 20:02:07 +00003921 SetPixelChannelMap(image,BlackPixelChannel,trait,n++);
cristy77c30f52011-10-24 18:56:57 +00003922 if (image->matte != MagickFalse)
cristye2a912b2011-12-05 20:02:07 +00003923 SetPixelChannelMap(image,AlphaPixelChannel,CopyPixelTrait,n++);
3924 if (image->storage_class == PseudoClass)
3925 SetPixelChannelMap(image,IndexPixelChannel,CopyPixelTrait,n++);
cristy183a5c72012-01-30 01:40:35 +00003926 if (image->mask != MagickFalse)
cristy10a6c612012-01-29 21:41:05 +00003927 SetPixelChannelMap(image,MaskPixelChannel,CopyPixelTrait,n++);
cristye2a912b2011-12-05 20:02:07 +00003928 assert((n+image->number_meta_channels) < MaxPixelChannels);
3929 for (i=0; i < (ssize_t) image->number_meta_channels; i++)
cristy61f18ad2011-12-08 21:12:37 +00003930 SetPixelChannelMap(image,(PixelChannel) (MetaPixelChannel+i),CopyPixelTrait,
cristye2a912b2011-12-05 20:02:07 +00003931 n++);
cristyd26338f2011-12-14 02:39:30 +00003932 image->number_channels=(size_t) n;
cristy77c30f52011-10-24 18:56:57 +00003933 if (image->debug != MagickFalse)
3934 LogPixelChannels(image);
3935 (void) SetPixelChannelMask(image,image->channel_mask);
3936}
cristybd5a96c2011-08-21 00:04:26 +00003937
3938/*
3939%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3940% %
3941% %
3942% %
cristya085a432011-07-30 01:39:32 +00003943% I n t e r p o l a t e P i x e l C h a n n e l %
3944% %
3945% %
3946% %
3947%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3948%
cristy884f6002011-07-31 00:51:45 +00003949% InterpolatePixelChannel() applies a pixel interpolation method between a
3950% floating point coordinate and the pixels surrounding that coordinate. No
3951% pixel area resampling, or scaling of the result is performed.
cristya085a432011-07-30 01:39:32 +00003952%
3953% The format of the InterpolatePixelChannel method is:
3954%
3955% MagickBooleanType InterpolatePixelChannel(const Image *image,
cristy444eda62011-08-10 02:07:46 +00003956% const CacheView *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00003957% const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00003958% double *pixel,ExceptionInfo *exception)
3959%
3960% A description of each parameter follows:
3961%
3962% o image: the image.
3963%
3964% o image_view: the image view.
3965%
3966% o channel: the pixel channel to interpolate.
3967%
3968% o method: the pixel color interpolation method.
3969%
3970% o x,y: A double representing the current (x,y) position of the pixel.
3971%
3972% o pixel: return the interpolated pixel here.
3973%
3974% o exception: return any errors or warnings in this structure.
3975%
3976*/
cristy94ea1632011-07-30 20:40:25 +00003977
cristy884f6002011-07-31 00:51:45 +00003978static inline double MagickMax(const MagickRealType x,const MagickRealType y)
3979{
3980 if (x > y)
3981 return(x);
3982 return(y);
3983}
3984
3985static inline MagickRealType CubicWeightingFunction(const MagickRealType x)
3986{
3987 MagickRealType
3988 alpha,
3989 gamma;
3990
3991 alpha=MagickMax(x+2.0,0.0);
3992 gamma=1.0*alpha*alpha*alpha;
3993 alpha=MagickMax(x+1.0,0.0);
3994 gamma-=4.0*alpha*alpha*alpha;
3995 alpha=MagickMax(x+0.0,0.0);
3996 gamma+=6.0*alpha*alpha*alpha;
3997 alpha=MagickMax(x-1.0,0.0);
3998 gamma-=4.0*alpha*alpha*alpha;
3999 return(gamma/6.0);
4000}
4001
cristy94ea1632011-07-30 20:40:25 +00004002static inline double MeshInterpolate(const PointInfo *delta,const double p,
4003 const double x,const double y)
4004{
4005 return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p);
4006}
4007
cristy884f6002011-07-31 00:51:45 +00004008static inline ssize_t NearestNeighbor(const MagickRealType x)
4009{
4010 if (x >= 0.0)
4011 return((ssize_t) (x+0.5));
4012 return((ssize_t) (x-0.5));
4013}
4014
cristya085a432011-07-30 01:39:32 +00004015MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
4016 const CacheView *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00004017 const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00004018 double *pixel,ExceptionInfo *exception)
4019{
4020 MagickBooleanType
4021 status;
4022
cristy94ea1632011-07-30 20:40:25 +00004023 MagickRealType
4024 alpha[16],
cristy884f6002011-07-31 00:51:45 +00004025 gamma,
4026 pixels[16];
cristy94ea1632011-07-30 20:40:25 +00004027
4028 PixelTrait
4029 traits;
4030
cristy94ea1632011-07-30 20:40:25 +00004031 register const Quantum
4032 *p;
4033
4034 register ssize_t
4035 i;
4036
cristya085a432011-07-30 01:39:32 +00004037 ssize_t
4038 x_offset,
4039 y_offset;
4040
4041 assert(image != (Image *) NULL);
4042 assert(image != (Image *) NULL);
4043 assert(image->signature == MagickSignature);
4044 assert(image_view != (CacheView *) NULL);
4045 status=MagickTrue;
cristy884f6002011-07-31 00:51:45 +00004046 *pixel=0.0;
cristy94ea1632011-07-30 20:40:25 +00004047 traits=GetPixelChannelMapTraits(image,channel);
cristya085a432011-07-30 01:39:32 +00004048 x_offset=(ssize_t) floor(x);
4049 y_offset=(ssize_t) floor(y);
4050 switch (method == UndefinedInterpolatePixel ? image->interpolate : method)
4051 {
cristy884f6002011-07-31 00:51:45 +00004052 case AverageInterpolatePixel:
4053 {
4054 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4055 exception);
4056 if (p == (const Quantum *) NULL)
4057 {
4058 status=MagickFalse;
4059 break;
4060 }
cristy222b19c2011-08-04 01:35:11 +00004061 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004062 for (i=0; i < 16; i++)
4063 {
4064 alpha[i]=1.0;
4065 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4066 }
4067 else
4068 for (i=0; i < 16; i++)
4069 {
4070 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4071 GetPixelChannels(image));
4072 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4073 }
4074 for (i=0; i < 16; i++)
4075 {
4076 gamma=1.0/(fabs((double) alpha[i]) <= MagickEpsilon ? 1.0 : alpha[i]);
4077 *pixel+=gamma*0.0625*pixels[i];
4078 }
4079 break;
4080 }
4081 case BicubicInterpolatePixel:
4082 {
4083 MagickRealType
4084 u[4],
4085 v[4];
4086
4087 PointInfo
4088 delta;
4089
4090 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4091 exception);
4092 if (p == (const Quantum *) NULL)
4093 {
4094 status=MagickFalse;
4095 break;
4096 }
cristy222b19c2011-08-04 01:35:11 +00004097 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004098 for (i=0; i < 16; i++)
4099 {
4100 alpha[i]=1.0;
4101 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4102 }
4103 else
4104 for (i=0; i < 16; i++)
4105 {
4106 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4107 GetPixelChannels(image));
4108 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4109 }
4110 delta.x=x-x_offset;
4111 delta.y=y-y_offset;
4112 for (i=0; i < 4; i++)
4113 {
4114 u[0]=(pixels[4*i+3]-pixels[4*i+2])-(pixels[4*i+0]-pixels[4*i+1]);
4115 u[1]=(pixels[4*i+0]-pixels[4*i+1])-u[0];
4116 u[2]=pixels[4*i+2]-pixels[4*i+0];
4117 u[3]=pixels[4*i+1];
4118 v[i]=(delta.x*delta.x*delta.x*u[0])+(delta.x*delta.x*u[1])+(delta.x*
4119 u[2])+u[3];
4120 }
4121 u[0]=(v[3]-v[2])-(v[0]-v[1]);
4122 u[1]=(v[0]-v[1])-u[0];
4123 u[2]=v[2]-v[0];
4124 u[3]=v[1];
4125 *pixel=(delta.y*delta.y*delta.y*u[0])+(delta.y*delta.y*u[1])+(delta.y*
4126 u[2])+u[3];
4127 break;
4128 }
4129 case BilinearInterpolatePixel:
cristy94ea1632011-07-30 20:40:25 +00004130 default:
cristya085a432011-07-30 01:39:32 +00004131 {
cristy94ea1632011-07-30 20:40:25 +00004132 PointInfo
4133 delta,
cristy884f6002011-07-31 00:51:45 +00004134 epsilon;
4135
4136 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4137 if (p == (const Quantum *) NULL)
4138 {
4139 status=MagickFalse;
4140 break;
4141 }
cristy222b19c2011-08-04 01:35:11 +00004142 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004143 for (i=0; i < 4; i++)
4144 {
4145 alpha[i]=1.0;
4146 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4147 }
4148 else
4149 for (i=0; i < 4; i++)
4150 {
4151 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4152 GetPixelChannels(image));
4153 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4154 }
4155 delta.x=x-x_offset;
4156 delta.y=y-y_offset;
4157 epsilon.x=1.0-delta.x;
4158 epsilon.y=1.0-delta.y;
4159 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4160 (epsilon.x*alpha[2]+delta.x*alpha[3])));
4161 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4162 *pixel=gamma*(epsilon.y*(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*
4163 (epsilon.x*pixels[2]+delta.x*pixels[3]));
4164 break;
4165 }
4166 case FilterInterpolatePixel:
4167 {
4168 CacheView
4169 *filter_view;
4170
4171 Image
4172 *excerpt_image,
4173 *filter_image;
4174
4175 RectangleInfo
4176 geometry;
4177
4178 geometry.width=4L;
4179 geometry.height=4L;
4180 geometry.x=x_offset-1;
4181 geometry.y=y_offset-1;
4182 excerpt_image=ExcerptImage(image,&geometry,exception);
4183 if (excerpt_image == (Image *) NULL)
4184 {
4185 status=MagickFalse;
4186 break;
4187 }
cristyaa2c16c2012-03-25 22:21:35 +00004188 filter_image=ResizeImage(excerpt_image,1,1,image->filter,exception);
cristy884f6002011-07-31 00:51:45 +00004189 excerpt_image=DestroyImage(excerpt_image);
4190 if (filter_image == (Image *) NULL)
4191 break;
cristydb070952012-04-20 14:33:00 +00004192 filter_view=AcquireVirtualCacheView(filter_image,exception);
cristy884f6002011-07-31 00:51:45 +00004193 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4194 if (p == (const Quantum *) NULL)
4195 status=MagickFalse;
4196 else
cristy0beccfa2011-09-25 20:47:53 +00004197 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004198 filter_view=DestroyCacheView(filter_view);
4199 filter_image=DestroyImage(filter_image);
4200 break;
4201 }
4202 case IntegerInterpolatePixel:
4203 {
4204 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
4205 if (p == (const Quantum *) NULL)
4206 {
4207 status=MagickFalse;
4208 break;
4209 }
cristy0beccfa2011-09-25 20:47:53 +00004210 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004211 break;
4212 }
4213 case NearestNeighborInterpolatePixel:
4214 {
4215 p=GetCacheViewVirtualPixels(image_view,NearestNeighbor(x),
4216 NearestNeighbor(y),1,1,exception);
4217 if (p == (const Quantum *) NULL)
4218 {
4219 status=MagickFalse;
4220 break;
4221 }
cristy0beccfa2011-09-25 20:47:53 +00004222 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004223 break;
4224 }
4225 case MeshInterpolatePixel:
4226 {
4227 PointInfo
4228 delta,
cristy94ea1632011-07-30 20:40:25 +00004229 luminance;
4230
4231 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4232 if (p == (const Quantum *) NULL)
4233 {
4234 status=MagickFalse;
4235 break;
4236 }
cristy222b19c2011-08-04 01:35:11 +00004237 if ((traits & BlendPixelTrait) == 0)
cristy94ea1632011-07-30 20:40:25 +00004238 for (i=0; i < 4; i++)
4239 {
4240 alpha[i]=1.0;
cristy884f6002011-07-31 00:51:45 +00004241 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
cristy94ea1632011-07-30 20:40:25 +00004242 }
4243 else
4244 for (i=0; i < 4; i++)
4245 {
4246 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4247 GetPixelChannels(image));
4248 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4249 }
cristy884f6002011-07-31 00:51:45 +00004250 delta.x=x-x_offset;
4251 delta.y=y-y_offset;
4252 luminance.x=GetPixelLuminance(image,p)-(double)
4253 GetPixelLuminance(image,p+3*GetPixelChannels(image));
cristy28474bf2011-09-11 23:32:52 +00004254 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
cristy884f6002011-07-31 00:51:45 +00004255 GetPixelLuminance(image,p+2*GetPixelChannels(image));
cristy94ea1632011-07-30 20:40:25 +00004256 if (fabs(luminance.x) < fabs(luminance.y))
4257 {
4258 /*
4259 Diagonal 0-3 NW-SE.
4260 */
4261 if (delta.x <= delta.y)
4262 {
4263 /*
4264 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4265 */
4266 delta.y=1.0-delta.y;
4267 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
4268 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4269 *pixel=gamma*MeshInterpolate(&delta,pixels[2],pixels[3],
4270 pixels[0]);
4271 }
4272 else
4273 {
4274 /*
4275 Top-right triangle (pixel: 1, diagonal: 0-3).
4276 */
4277 delta.x=1.0-delta.x;
4278 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
4279 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4280 *pixel=gamma*MeshInterpolate(&delta,pixels[1],pixels[0],
4281 pixels[3]);
4282 }
4283 }
4284 else
4285 {
4286 /*
4287 Diagonal 1-2 NE-SW.
4288 */
4289 if (delta.x <= (1.0-delta.y))
4290 {
4291 /*
4292 Top-left triangle (pixel: 0, diagonal: 1-2).
4293 */
4294 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
4295 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4296 *pixel=gamma*MeshInterpolate(&delta,pixels[0],pixels[1],
4297 pixels[2]);
4298 }
4299 else
4300 {
4301 /*
4302 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4303 */
4304 delta.x=1.0-delta.x;
4305 delta.y=1.0-delta.y;
4306 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
4307 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4308 *pixel=gamma*MeshInterpolate(&delta,pixels[3],pixels[2],
4309 pixels[1]);
4310 }
4311 }
cristya085a432011-07-30 01:39:32 +00004312 break;
4313 }
cristy884f6002011-07-31 00:51:45 +00004314 case SplineInterpolatePixel:
4315 {
4316 MagickRealType
4317 dx,
4318 dy;
4319
4320 PointInfo
4321 delta;
4322
4323 ssize_t
4324 j,
4325 n;
4326
4327 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4328 exception);
4329 if (p == (const Quantum *) NULL)
4330 {
4331 status=MagickFalse;
4332 break;
4333 }
cristy222b19c2011-08-04 01:35:11 +00004334 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004335 for (i=0; i < 16; i++)
4336 {
4337 alpha[i]=1.0;
4338 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4339 }
4340 else
4341 for (i=0; i < 16; i++)
4342 {
4343 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4344 GetPixelChannels(image));
4345 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4346 }
4347 delta.x=x-x_offset;
4348 delta.y=y-y_offset;
4349 n=0;
4350 for (i=(-1); i < 3L; i++)
4351 {
4352 dy=CubicWeightingFunction((MagickRealType) i-delta.y);
4353 for (j=(-1); j < 3L; j++)
4354 {
4355 dx=CubicWeightingFunction(delta.x-(MagickRealType) j);
4356 gamma=1.0/(fabs((double) alpha[n]) <= MagickEpsilon ? 1.0 : alpha[n]);
4357 *pixel+=gamma*dx*dy*pixels[n];
4358 n++;
4359 }
4360 }
4361 break;
4362 }
cristya085a432011-07-30 01:39:32 +00004363 }
4364 return(status);
4365}
4366
4367/*
4368%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4369% %
4370% %
4371% %
cristy5c4e2582011-09-11 19:21:03 +00004372% I n t e r p o l a t e P i x e l C h a n n e l s %
4373% %
4374% %
4375% %
4376%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4377%
4378% InterpolatePixelChannels() applies a pixel interpolation method between a
4379% floating point coordinate and the pixels surrounding that coordinate. No
4380% pixel area resampling, or scaling of the result is performed.
4381%
4382% The format of the InterpolatePixelChannels method is:
4383%
4384% MagickBooleanType InterpolatePixelChannels(const Image *source,
4385% const CacheView *source_view,const Image *destination,
4386% const PixelInterpolateMethod method,const double x,const double y,
4387% Quantum *pixel,ExceptionInfo *exception)
4388%
4389% A description of each parameter follows:
4390%
4391% o source: the source.
4392%
4393% o source_view: the source view.
4394%
4395% o destination: the destination image.
4396%
4397% o method: the pixel color interpolation method.
4398%
4399% o x,y: A double representing the current (x,y) position of the pixel.
4400%
4401% o pixel: return the interpolated pixel here.
4402%
4403% o exception: return any errors or warnings in this structure.
4404%
4405*/
4406MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
4407 const CacheView *source_view,const Image *destination,
4408 const PixelInterpolateMethod method,const double x,const double y,
4409 Quantum *pixel,ExceptionInfo *exception)
4410{
4411 MagickBooleanType
4412 status;
4413
4414 MagickRealType
4415 alpha[16],
4416 gamma,
4417 pixels[16];
4418
4419 PixelChannel
4420 channel;
4421
4422 PixelTrait
4423 destination_traits,
4424 traits;
4425
4426 register const Quantum
4427 *p;
4428
4429 register ssize_t
4430 i;
4431
4432 ssize_t
4433 x_offset,
4434 y_offset;
4435
4436 assert(source != (Image *) NULL);
4437 assert(source != (Image *) NULL);
4438 assert(source->signature == MagickSignature);
4439 assert(source_view != (CacheView *) NULL);
4440 status=MagickTrue;
4441 x_offset=(ssize_t) floor(x);
4442 y_offset=(ssize_t) floor(y);
4443 switch (method == UndefinedInterpolatePixel ? source->interpolate : method)
4444 {
4445 case AverageInterpolatePixel:
4446 {
4447 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4448 exception);
4449 if (p == (const Quantum *) NULL)
4450 {
4451 status=MagickFalse;
4452 break;
4453 }
4454 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4455 {
4456 double
4457 sum;
4458
4459 register ssize_t
4460 j;
4461
cristye2a912b2011-12-05 20:02:07 +00004462 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004463 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004464 destination_traits=GetPixelChannelMapTraits(destination,channel);
4465 if ((traits == UndefinedPixelTrait) ||
4466 (destination_traits == UndefinedPixelTrait))
4467 continue;
4468 for (j=0; j < 16; j++)
4469 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
cristy4a7ae692011-12-14 12:24:11 +00004470 sum=0.0;
cristy5c4e2582011-09-11 19:21:03 +00004471 if ((traits & BlendPixelTrait) == 0)
4472 {
4473 for (j=0; j < 16; j++)
cristy4a7ae692011-12-14 12:24:11 +00004474 sum+=0.0625*pixels[j];
4475 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004476 continue;
4477 }
cristy5c4e2582011-09-11 19:21:03 +00004478 for (j=0; j < 16; j++)
4479 {
4480 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4481 GetPixelChannels(source));
4482 pixels[j]*=alpha[j];
4483 gamma=1.0/(fabs((double) alpha[j]) <= MagickEpsilon ? 1.0 : alpha[j]);
4484 sum+=gamma*0.0625*pixels[j];
4485 }
cristy4a7ae692011-12-14 12:24:11 +00004486 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004487 }
4488 break;
4489 }
4490 case BicubicInterpolatePixel:
4491 {
4492 MagickRealType
4493 u[4],
4494 v[4];
4495
4496 PointInfo
4497 delta;
4498
4499 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4500 exception);
4501 if (p == (const Quantum *) NULL)
4502 {
4503 status=MagickFalse;
4504 break;
4505 }
4506 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4507 {
4508 register ssize_t
4509 j;
4510
cristye2a912b2011-12-05 20:02:07 +00004511 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004512 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004513 destination_traits=GetPixelChannelMapTraits(destination,channel);
4514 if ((traits == UndefinedPixelTrait) ||
4515 (destination_traits == UndefinedPixelTrait))
4516 continue;
4517 if ((traits & BlendPixelTrait) == 0)
4518 for (j=0; j < 16; j++)
4519 {
4520 alpha[j]=1.0;
4521 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
4522 }
4523 else
4524 for (j=0; j < 16; j++)
4525 {
4526 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4527 GetPixelChannels(source));
4528 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
4529 }
4530 delta.x=x-x_offset;
4531 delta.y=y-y_offset;
4532 for (j=0; j < 4; j++)
4533 {
4534 u[0]=(pixels[4*j+3]-pixels[4*j+2])-(pixels[4*j+0]-pixels[4*j+1]);
4535 u[1]=(pixels[4*j+0]-pixels[4*j+1])-u[0];
4536 u[2]=pixels[4*j+2]-pixels[4*j+0];
4537 u[3]=pixels[4*j+1];
4538 v[j]=(delta.x*delta.x*delta.x*u[0])+(delta.x*delta.x*u[1])+(delta.x*
4539 u[2])+u[3];
4540 }
4541 u[0]=(v[3]-v[2])-(v[0]-v[1]);
4542 u[1]=(v[0]-v[1])-u[0];
4543 u[2]=v[2]-v[0];
4544 u[3]=v[1];
cristy4a7ae692011-12-14 12:24:11 +00004545 SetPixelChannel(destination,channel,ClampToQuantum((delta.y*delta.y*
4546 delta.y*u[0])+(delta.y*delta.y*u[1])+(delta.y*u[2])+u[3]),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004547 }
4548 break;
4549 }
4550 case BilinearInterpolatePixel:
4551 default:
4552 {
4553 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4554 if (p == (const Quantum *) NULL)
4555 {
4556 status=MagickFalse;
4557 break;
4558 }
4559 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4560 {
4561 PointInfo
4562 delta,
4563 epsilon;
4564
cristye2a912b2011-12-05 20:02:07 +00004565 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004566 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004567 destination_traits=GetPixelChannelMapTraits(destination,channel);
4568 if ((traits == UndefinedPixelTrait) ||
4569 (destination_traits == UndefinedPixelTrait))
4570 continue;
4571 delta.x=x-x_offset;
4572 delta.y=y-y_offset;
4573 epsilon.x=1.0-delta.x;
4574 epsilon.y=1.0-delta.y;
cristy28474bf2011-09-11 23:32:52 +00004575 pixels[0]=(MagickRealType) p[i];
4576 pixels[1]=(MagickRealType) p[GetPixelChannels(source)+i];
cristy5c4e2582011-09-11 19:21:03 +00004577 pixels[2]=(MagickRealType) p[2*GetPixelChannels(source)+i];
4578 pixels[3]=(MagickRealType) p[3*GetPixelChannels(source)+i];
4579 if ((traits & BlendPixelTrait) == 0)
4580 {
4581 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
4582 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004583 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
4584 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*
4585 pixels[2]+delta.x*pixels[3]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004586 continue;
4587 }
cristy28474bf2011-09-11 23:32:52 +00004588 alpha[0]=QuantumScale*GetPixelAlpha(source,p);
4589 alpha[1]=QuantumScale*GetPixelAlpha(source,p+GetPixelChannels(source));
cristy5c4e2582011-09-11 19:21:03 +00004590 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
4591 GetPixelChannels(source));
4592 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
4593 GetPixelChannels(source));
4594 pixels[0]*=alpha[0];
4595 pixels[1]*=alpha[1];
4596 pixels[2]*=alpha[2];
4597 pixels[3]*=alpha[3];
4598 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4599 (epsilon.x*alpha[2]+delta.x*alpha[3])));
4600 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004601 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
4602 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*pixels[2]+
4603 delta.x*pixels[3]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004604 }
4605 break;
4606 }
4607 case FilterInterpolatePixel:
4608 {
4609 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4610 {
4611 CacheView
4612 *filter_view;
4613
4614 Image
4615 *excerpt_source,
4616 *filter_source;
4617
4618 RectangleInfo
4619 geometry;
4620
cristye2a912b2011-12-05 20:02:07 +00004621 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004622 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004623 destination_traits=GetPixelChannelMapTraits(destination,channel);
4624 if ((traits == UndefinedPixelTrait) ||
4625 (destination_traits == UndefinedPixelTrait))
4626 continue;
4627 geometry.width=4L;
4628 geometry.height=4L;
4629 geometry.x=x_offset-1;
4630 geometry.y=y_offset-1;
4631 excerpt_source=ExcerptImage(source,&geometry,exception);
4632 if (excerpt_source == (Image *) NULL)
4633 {
4634 status=MagickFalse;
4635 continue;
4636 }
cristyaa2c16c2012-03-25 22:21:35 +00004637 filter_source=ResizeImage(excerpt_source,1,1,source->filter,exception);
cristy5c4e2582011-09-11 19:21:03 +00004638 excerpt_source=DestroyImage(excerpt_source);
4639 if (filter_source == (Image *) NULL)
4640 continue;
cristydb070952012-04-20 14:33:00 +00004641 filter_view=AcquireVirtualCacheView(filter_source,exception);
cristy5c4e2582011-09-11 19:21:03 +00004642 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4643 if (p == (const Quantum *) NULL)
4644 status=MagickFalse;
4645 else
cristy1861c902011-12-14 02:30:00 +00004646 {
cristy4a7ae692011-12-14 12:24:11 +00004647 SetPixelChannel(destination,channel,p[i],pixel);
cristy1861c902011-12-14 02:30:00 +00004648 }
cristy5c4e2582011-09-11 19:21:03 +00004649 filter_view=DestroyCacheView(filter_view);
4650 filter_source=DestroyImage(filter_source);
4651 }
4652 break;
4653 }
4654 case IntegerInterpolatePixel:
4655 {
4656 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
4657 if (p == (const Quantum *) NULL)
4658 {
4659 status=MagickFalse;
4660 break;
4661 }
4662 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4663 {
cristye2a912b2011-12-05 20:02:07 +00004664 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004665 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004666 destination_traits=GetPixelChannelMapTraits(destination,channel);
4667 if ((traits == UndefinedPixelTrait) ||
4668 (destination_traits == UndefinedPixelTrait))
4669 continue;
cristy4a7ae692011-12-14 12:24:11 +00004670 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004671 }
4672 break;
4673 }
4674 case NearestNeighborInterpolatePixel:
4675 {
4676 p=GetCacheViewVirtualPixels(source_view,NearestNeighbor(x),
4677 NearestNeighbor(y),1,1,exception);
4678 if (p == (const Quantum *) NULL)
4679 {
4680 status=MagickFalse;
4681 break;
4682 }
4683 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4684 {
cristye2a912b2011-12-05 20:02:07 +00004685 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004686 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004687 destination_traits=GetPixelChannelMapTraits(destination,channel);
4688 if ((traits == UndefinedPixelTrait) ||
4689 (destination_traits == UndefinedPixelTrait))
4690 continue;
cristy4a7ae692011-12-14 12:24:11 +00004691 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004692 }
4693 break;
4694 }
4695 case MeshInterpolatePixel:
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 }
4703 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4704 {
4705 PointInfo
4706 delta,
4707 luminance;
4708
cristye2a912b2011-12-05 20:02:07 +00004709 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004710 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004711 destination_traits=GetPixelChannelMapTraits(destination,channel);
4712 if ((traits == UndefinedPixelTrait) ||
4713 (destination_traits == UndefinedPixelTrait))
4714 continue;
cristy1861c902011-12-14 02:30:00 +00004715 pixels[0]=(MagickRealType) p[i];
4716 pixels[1]=(MagickRealType) p[GetPixelChannels(source)+i];
4717 pixels[2]=(MagickRealType) p[2*GetPixelChannels(source)+i];
4718 pixels[3]=(MagickRealType) p[3*GetPixelChannels(source)+i];
4719 if ((traits & BlendPixelTrait) == 0)
4720 {
4721 alpha[0]=1.0;
4722 alpha[1]=1.0;
4723 alpha[2]=1.0;
4724 alpha[3]=1.0;
4725 }
4726 else
4727 {
4728 alpha[0]=QuantumScale*GetPixelAlpha(source,p);
4729 alpha[1]=QuantumScale*GetPixelAlpha(source,p+
4730 GetPixelChannels(source));
4731 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
4732 GetPixelChannels(source));
4733 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
4734 GetPixelChannels(source));
4735 }
4736 delta.x=x-x_offset;
4737 delta.y=y-y_offset;
4738 luminance.x=GetPixelLuminance(source,p)-(double)
4739 GetPixelLuminance(source,p+3*GetPixelChannels(source));
4740 luminance.y=GetPixelLuminance(source,p+GetPixelChannels(source))-
4741 (double) GetPixelLuminance(source,p+2*GetPixelChannels(source));
4742 if (fabs(luminance.x) < fabs(luminance.y))
4743 {
4744 /*
4745 Diagonal 0-3 NW-SE.
4746 */
4747 if (delta.x <= delta.y)
4748 {
4749 /*
4750 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4751 */
4752 delta.y=1.0-delta.y;
4753 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
4754 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004755 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4756 MeshInterpolate(&delta,pixels[2],pixels[3],pixels[0])),pixel);
cristy1861c902011-12-14 02:30:00 +00004757 }
4758 else
4759 {
4760 /*
4761 Top-right triangle (pixel: 1, diagonal: 0-3).
4762 */
4763 delta.x=1.0-delta.x;
4764 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
4765 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004766 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4767 MeshInterpolate(&delta,pixels[1],pixels[0],pixels[3])),pixel);
cristy1861c902011-12-14 02:30:00 +00004768 }
4769 }
4770 else
4771 {
4772 /*
4773 Diagonal 1-2 NE-SW.
4774 */
4775 if (delta.x <= (1.0-delta.y))
4776 {
4777 /*
4778 Top-left triangle (pixel: 0, diagonal: 1-2).
4779 */
4780 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
4781 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004782 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4783 MeshInterpolate(&delta,pixels[0],pixels[1],pixels[2])),pixel);
cristy1861c902011-12-14 02:30:00 +00004784 }
4785 else
4786 {
4787 /*
4788 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4789 */
4790 delta.x=1.0-delta.x;
4791 delta.y=1.0-delta.y;
4792 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
4793 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004794 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4795 MeshInterpolate(&delta,pixels[3],pixels[2],pixels[1])),pixel);
cristy1861c902011-12-14 02:30:00 +00004796 }
4797 }
cristy5c4e2582011-09-11 19:21:03 +00004798 }
4799 break;
4800 }
4801 case SplineInterpolatePixel:
4802 {
4803 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4804 exception);
4805 if (p == (const Quantum *) NULL)
4806 {
4807 status=MagickFalse;
4808 break;
4809 }
4810 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4811 {
4812 double
4813 sum;
4814
4815 MagickRealType
4816 dx,
4817 dy;
4818
4819 PointInfo
4820 delta;
4821
4822 register ssize_t
4823 j;
4824
4825 ssize_t
4826 k,
4827 n;
4828
cristye2a912b2011-12-05 20:02:07 +00004829 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004830 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004831 destination_traits=GetPixelChannelMapTraits(destination,channel);
4832 if ((traits == UndefinedPixelTrait) ||
4833 (destination_traits == UndefinedPixelTrait))
4834 continue;
4835 if ((traits & BlendPixelTrait) == 0)
4836 for (j=0; j < 16; j++)
4837 {
4838 alpha[j]=1.0;
4839 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
4840 }
4841 else
4842 for (j=0; j < 16; j++)
4843 {
4844 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4845 GetPixelChannels(source));
4846 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
4847 }
4848 delta.x=x-x_offset;
4849 delta.y=y-y_offset;
4850 sum=0.0;
4851 n=0;
4852 for (j=(-1); j < 3L; j++)
4853 {
4854 dy=CubicWeightingFunction((MagickRealType) j-delta.y);
4855 for (k=(-1); k < 3L; k++)
4856 {
4857 dx=CubicWeightingFunction(delta.x-(MagickRealType) k);
4858 gamma=1.0/(fabs((double) alpha[n]) <= MagickEpsilon ? 1.0 :
4859 alpha[n]);
4860 sum+=gamma*dx*dy*pixels[n];
4861 n++;
4862 }
4863 }
cristy4a7ae692011-12-14 12:24:11 +00004864 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004865 }
4866 break;
4867 }
4868 }
4869 return(status);
4870}
4871
4872/*
4873%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4874% %
4875% %
4876% %
cristy9075cdb2011-07-30 01:06:23 +00004877% 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 +00004878% %
4879% %
4880% %
4881%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4882%
cristy884f6002011-07-31 00:51:45 +00004883% InterpolatePixelInfo() applies a pixel interpolation method between a
4884% floating point coordinate and the pixels surrounding that coordinate. No
4885% pixel area resampling, or scaling of the result is performed.
cristy4c08aed2011-07-01 19:47:50 +00004886%
4887% The format of the InterpolatePixelInfo method is:
4888%
4889% MagickBooleanType InterpolatePixelInfo(const Image *image,
cristy5c4e2582011-09-11 19:21:03 +00004890% const CacheView *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00004891% const double x,const double y,PixelInfo *pixel,
4892% ExceptionInfo *exception)
4893%
4894% A description of each parameter follows:
4895%
4896% o image: the image.
4897%
4898% o image_view: the image view.
4899%
4900% o method: the pixel color interpolation method.
4901%
4902% o x,y: A double representing the current (x,y) position of the pixel.
4903%
4904% o pixel: return the interpolated pixel here.
4905%
4906% o exception: return any errors or warnings in this structure.
4907%
4908*/
4909
4910static inline void AlphaBlendPixelInfo(const Image *image,
4911 const Quantum *pixel,PixelInfo *pixel_info,MagickRealType *alpha)
4912{
4913 if (image->matte == MagickFalse)
4914 {
4915 *alpha=1.0;
4916 pixel_info->red=(MagickRealType) GetPixelRed(image,pixel);
4917 pixel_info->green=(MagickRealType) GetPixelGreen(image,pixel);
4918 pixel_info->blue=(MagickRealType) GetPixelBlue(image,pixel);
4919 pixel_info->black=0.0;
4920 if (image->colorspace == CMYKColorspace)
4921 pixel_info->black=(MagickRealType) GetPixelBlack(image,pixel);
4922 pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
4923 return;
4924 }
4925 *alpha=QuantumScale*GetPixelAlpha(image,pixel);
4926 pixel_info->red=(*alpha*GetPixelRed(image,pixel));
4927 pixel_info->green=(*alpha*GetPixelGreen(image,pixel));
4928 pixel_info->blue=(*alpha*GetPixelBlue(image,pixel));
4929 pixel_info->black=0.0;
4930 if (image->colorspace == CMYKColorspace)
4931 pixel_info->black=(*alpha*GetPixelBlack(image,pixel));
4932 pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
4933}
4934
4935static void BicubicInterpolate(const PixelInfo *pixels,const double dx,
4936 PixelInfo *pixel)
4937{
4938 MagickRealType
4939 dx2,
4940 p,
4941 q,
4942 r,
4943 s;
4944
4945 dx2=dx*dx;
4946 p=(pixels[3].red-pixels[2].red)-(pixels[0].red-pixels[1].red);
4947 q=(pixels[0].red-pixels[1].red)-p;
4948 r=pixels[2].red-pixels[0].red;
4949 s=pixels[1].red;
4950 pixel->red=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4951 p=(pixels[3].green-pixels[2].green)-(pixels[0].green-pixels[1].green);
4952 q=(pixels[0].green-pixels[1].green)-p;
4953 r=pixels[2].green-pixels[0].green;
4954 s=pixels[1].green;
4955 pixel->green=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4956 p=(pixels[3].blue-pixels[2].blue)-(pixels[0].blue-pixels[1].blue);
4957 q=(pixels[0].blue-pixels[1].blue)-p;
4958 r=pixels[2].blue-pixels[0].blue;
4959 s=pixels[1].blue;
4960 pixel->blue=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4961 p=(pixels[3].alpha-pixels[2].alpha)-(pixels[0].alpha-pixels[1].alpha);
4962 q=(pixels[0].alpha-pixels[1].alpha)-p;
4963 r=pixels[2].alpha-pixels[0].alpha;
4964 s=pixels[1].alpha;
4965 pixel->alpha=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4966 if (pixel->colorspace == CMYKColorspace)
4967 {
4968 p=(pixels[3].black-pixels[2].black)-(pixels[0].black-pixels[1].black);
4969 q=(pixels[0].black-pixels[1].black)-p;
4970 r=pixels[2].black-pixels[0].black;
4971 s=pixels[1].black;
4972 pixel->black=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4973 }
4974}
4975
cristy4c08aed2011-07-01 19:47:50 +00004976MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
cristy5c4e2582011-09-11 19:21:03 +00004977 const CacheView *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00004978 const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception)
4979{
4980 MagickBooleanType
4981 status;
4982
cristy4c08aed2011-07-01 19:47:50 +00004983 MagickRealType
4984 alpha[16],
4985 gamma;
4986
cristy865d58d2011-07-09 00:44:52 +00004987 PixelInfo
4988 pixels[16];
4989
cristy4c08aed2011-07-01 19:47:50 +00004990 register const Quantum
4991 *p;
4992
4993 register ssize_t
4994 i;
4995
4996 ssize_t
4997 x_offset,
4998 y_offset;
4999
5000 assert(image != (Image *) NULL);
5001 assert(image->signature == MagickSignature);
5002 assert(image_view != (CacheView *) NULL);
5003 status=MagickTrue;
5004 x_offset=(ssize_t) floor(x);
5005 y_offset=(ssize_t) floor(y);
5006 switch (method == UndefinedInterpolatePixel ? image->interpolate : method)
5007 {
5008 case AverageInterpolatePixel:
5009 {
5010 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5011 exception);
5012 if (p == (const Quantum *) NULL)
5013 {
5014 status=MagickFalse;
5015 break;
5016 }
cristy5ce8df82011-07-07 14:52:23 +00005017 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005018 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005019 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5020 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5021 AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
5022 AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
5023 AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
5024 AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
5025 AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
5026 AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
5027 AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
cristy865d58d2011-07-09 00:44:52 +00005028 10);
cristyed231572011-07-14 02:18:59 +00005029 AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
cristy865d58d2011-07-09 00:44:52 +00005030 11);
cristyed231572011-07-14 02:18:59 +00005031 AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
cristy865d58d2011-07-09 00:44:52 +00005032 12);
cristyed231572011-07-14 02:18:59 +00005033 AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
cristy865d58d2011-07-09 00:44:52 +00005034 13);
cristyed231572011-07-14 02:18:59 +00005035 AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
cristy865d58d2011-07-09 00:44:52 +00005036 14);
cristyed231572011-07-14 02:18:59 +00005037 AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
cristy865d58d2011-07-09 00:44:52 +00005038 15);
cristy4c08aed2011-07-01 19:47:50 +00005039 pixel->red=0.0;
5040 pixel->green=0.0;
5041 pixel->blue=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005042 pixel->black=0.0;
cristy865d58d2011-07-09 00:44:52 +00005043 pixel->alpha=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005044 for (i=0; i < 16L; i++)
5045 {
5046 gamma=1.0/(fabs((double) alpha[i]) <= MagickEpsilon ? 1.0 : alpha[i]);
5047 pixel->red+=gamma*0.0625*pixels[i].red;
5048 pixel->green+=gamma*0.0625*pixels[i].green;
5049 pixel->blue+=gamma*0.0625*pixels[i].blue;
cristy4c08aed2011-07-01 19:47:50 +00005050 if (image->colorspace == CMYKColorspace)
5051 pixel->black+=gamma*0.0625*pixels[i].black;
cristy865d58d2011-07-09 00:44:52 +00005052 pixel->alpha+=0.0625*pixels[i].alpha;
cristy4c08aed2011-07-01 19:47:50 +00005053 }
5054 break;
5055 }
5056 case BicubicInterpolatePixel:
5057 {
5058 PixelInfo
5059 u[4];
5060
5061 PointInfo
5062 delta;
5063
5064 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5065 exception);
5066 if (p == (const Quantum *) NULL)
5067 {
5068 status=MagickFalse;
5069 break;
5070 }
cristy5ce8df82011-07-07 14:52:23 +00005071 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005072 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005073 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5074 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5075 AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
5076 AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
5077 AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
5078 AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
5079 AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
5080 AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
5081 AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
cristy865d58d2011-07-09 00:44:52 +00005082 10);
cristyed231572011-07-14 02:18:59 +00005083 AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
cristy865d58d2011-07-09 00:44:52 +00005084 11);
cristyed231572011-07-14 02:18:59 +00005085 AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
cristy865d58d2011-07-09 00:44:52 +00005086 12);
cristyed231572011-07-14 02:18:59 +00005087 AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
cristy865d58d2011-07-09 00:44:52 +00005088 13);
cristyed231572011-07-14 02:18:59 +00005089 AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
cristy865d58d2011-07-09 00:44:52 +00005090 14);
cristyed231572011-07-14 02:18:59 +00005091 AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
cristy865d58d2011-07-09 00:44:52 +00005092 15);
cristy4c08aed2011-07-01 19:47:50 +00005093 delta.x=x-x_offset;
5094 delta.y=y-y_offset;
5095 for (i=0; i < 4L; i++)
5096 BicubicInterpolate(pixels+4*i,delta.x,u+i);
5097 BicubicInterpolate(u,delta.y,pixel);
5098 break;
5099 }
5100 case BilinearInterpolatePixel:
5101 default:
5102 {
5103 PointInfo
5104 delta,
5105 epsilon;
5106
5107 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5108 if (p == (const Quantum *) NULL)
5109 {
5110 status=MagickFalse;
5111 break;
5112 }
cristy5ce8df82011-07-07 14:52:23 +00005113 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005114 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005115 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5116 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
cristy4c08aed2011-07-01 19:47:50 +00005117 delta.x=x-x_offset;
5118 delta.y=y-y_offset;
5119 epsilon.x=1.0-delta.x;
5120 epsilon.y=1.0-delta.y;
5121 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
5122 (epsilon.x*alpha[2]+delta.x*alpha[3])));
5123 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
5124 pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x*
5125 pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red));
5126 pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x*
5127 pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x*
5128 pixels[3].green));
5129 pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x*
5130 pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x*
5131 pixels[3].blue));
cristy4c08aed2011-07-01 19:47:50 +00005132 if (image->colorspace == CMYKColorspace)
5133 pixel->black=gamma*(epsilon.y*(epsilon.x*pixels[0].black+delta.x*
5134 pixels[1].black)+delta.y*(epsilon.x*pixels[2].black+delta.x*
5135 pixels[3].black));
cristy884f6002011-07-31 00:51:45 +00005136 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
5137 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy865d58d2011-07-09 00:44:52 +00005138 pixel->alpha=(epsilon.y*(epsilon.x*pixels[0].alpha+delta.x*
5139 pixels[1].alpha)+delta.y*(epsilon.x*pixels[2].alpha+delta.x*
5140 pixels[3].alpha));
cristy4c08aed2011-07-01 19:47:50 +00005141 break;
5142 }
5143 case FilterInterpolatePixel:
5144 {
5145 CacheView
5146 *filter_view;
5147
5148 Image
5149 *excerpt_image,
5150 *filter_image;
5151
5152 RectangleInfo
5153 geometry;
5154
5155 geometry.width=4L;
5156 geometry.height=4L;
5157 geometry.x=x_offset-1;
5158 geometry.y=y_offset-1;
5159 excerpt_image=ExcerptImage(image,&geometry,exception);
5160 if (excerpt_image == (Image *) NULL)
5161 {
5162 status=MagickFalse;
5163 break;
5164 }
cristyaa2c16c2012-03-25 22:21:35 +00005165 filter_image=ResizeImage(excerpt_image,1,1,image->filter,exception);
cristy4c08aed2011-07-01 19:47:50 +00005166 excerpt_image=DestroyImage(excerpt_image);
5167 if (filter_image == (Image *) NULL)
5168 break;
cristydb070952012-04-20 14:33:00 +00005169 filter_view=AcquireVirtualCacheView(filter_image,exception);
cristy4c08aed2011-07-01 19:47:50 +00005170 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
5171 if (p != (const Quantum *) NULL)
cristy803640d2011-11-17 02:11:32 +00005172 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005173 filter_view=DestroyCacheView(filter_view);
5174 filter_image=DestroyImage(filter_image);
5175 break;
5176 }
5177 case IntegerInterpolatePixel:
5178 {
5179 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
5180 if (p == (const Quantum *) NULL)
5181 {
5182 status=MagickFalse;
5183 break;
5184 }
cristy803640d2011-11-17 02:11:32 +00005185 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005186 break;
5187 }
5188 case MeshInterpolatePixel:
5189 {
5190 PointInfo
5191 delta,
5192 luminance;
5193
cristy94ea1632011-07-30 20:40:25 +00005194 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
cristy4c08aed2011-07-01 19:47:50 +00005195 if (p == (const Quantum *) NULL)
5196 {
5197 status=MagickFalse;
5198 break;
5199 }
cristy94ea1632011-07-30 20:40:25 +00005200 delta.x=x-x_offset;
5201 delta.y=y-y_offset;
cristy884f6002011-07-31 00:51:45 +00005202 luminance.x=GetPixelLuminance(image,p)-(double)
cristy94ea1632011-07-30 20:40:25 +00005203 GetPixelLuminance(image,p+3*GetPixelChannels(image));
cristy28474bf2011-09-11 23:32:52 +00005204 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
cristy94ea1632011-07-30 20:40:25 +00005205 GetPixelLuminance(image,p+2*GetPixelChannels(image));
cristy5ce8df82011-07-07 14:52:23 +00005206 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005207 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005208 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5209 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
cristy4c08aed2011-07-01 19:47:50 +00005210 if (fabs(luminance.x) < fabs(luminance.y))
5211 {
5212 /*
5213 Diagonal 0-3 NW-SE.
5214 */
5215 if (delta.x <= delta.y)
5216 {
5217 /*
cristy94ea1632011-07-30 20:40:25 +00005218 Bottom-left triangle (pixel: 2, diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005219 */
5220 delta.y=1.0-delta.y;
5221 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
5222 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
5223 pixel->red=gamma*MeshInterpolate(&delta,pixels[2].red,
5224 pixels[3].red,pixels[0].red);
5225 pixel->green=gamma*MeshInterpolate(&delta,pixels[2].green,
5226 pixels[3].green,pixels[0].green);
5227 pixel->blue=gamma*MeshInterpolate(&delta,pixels[2].blue,
5228 pixels[3].blue,pixels[0].blue);
cristy4c08aed2011-07-01 19:47:50 +00005229 if (image->colorspace == CMYKColorspace)
5230 pixel->black=gamma*MeshInterpolate(&delta,pixels[2].black,
5231 pixels[3].black,pixels[0].black);
cristy94ea1632011-07-30 20:40:25 +00005232 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005233 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[2].alpha,
5234 pixels[3].alpha,pixels[0].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005235 }
5236 else
5237 {
5238 /*
cristy94ea1632011-07-30 20:40:25 +00005239 Top-right triangle (pixel:1 , diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005240 */
5241 delta.x=1.0-delta.x;
5242 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
5243 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
5244 pixel->red=gamma*MeshInterpolate(&delta,pixels[1].red,
5245 pixels[0].red,pixels[3].red);
5246 pixel->green=gamma*MeshInterpolate(&delta,pixels[1].green,
5247 pixels[0].green,pixels[3].green);
5248 pixel->blue=gamma*MeshInterpolate(&delta,pixels[1].blue,
5249 pixels[0].blue,pixels[3].blue);
cristy4c08aed2011-07-01 19:47:50 +00005250 if (image->colorspace == CMYKColorspace)
5251 pixel->black=gamma*MeshInterpolate(&delta,pixels[1].black,
5252 pixels[0].black,pixels[3].black);
cristy94ea1632011-07-30 20:40:25 +00005253 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005254 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[1].alpha,
5255 pixels[0].alpha,pixels[3].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005256 }
5257 }
5258 else
5259 {
5260 /*
5261 Diagonal 1-2 NE-SW.
5262 */
5263 if (delta.x <= (1.0-delta.y))
5264 {
5265 /*
cristy94ea1632011-07-30 20:40:25 +00005266 Top-left triangle (pixel: 0, diagonal: 1-2).
cristy4c08aed2011-07-01 19:47:50 +00005267 */
5268 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
5269 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
5270 pixel->red=gamma*MeshInterpolate(&delta,pixels[0].red,
5271 pixels[1].red,pixels[2].red);
5272 pixel->green=gamma*MeshInterpolate(&delta,pixels[0].green,
5273 pixels[1].green,pixels[2].green);
5274 pixel->blue=gamma*MeshInterpolate(&delta,pixels[0].blue,
5275 pixels[1].blue,pixels[2].blue);
cristy4c08aed2011-07-01 19:47:50 +00005276 if (image->colorspace == CMYKColorspace)
5277 pixel->black=gamma*MeshInterpolate(&delta,pixels[0].black,
5278 pixels[1].black,pixels[2].black);
cristy94ea1632011-07-30 20:40:25 +00005279 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005280 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[0].alpha,
5281 pixels[1].alpha,pixels[2].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005282 }
5283 else
5284 {
5285 /*
5286 Bottom-right triangle (pixel: 3, diagonal: 1-2).
5287 */
5288 delta.x=1.0-delta.x;
5289 delta.y=1.0-delta.y;
5290 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
5291 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
5292 pixel->red=gamma*MeshInterpolate(&delta,pixels[3].red,
5293 pixels[2].red,pixels[1].red);
5294 pixel->green=gamma*MeshInterpolate(&delta,pixels[3].green,
5295 pixels[2].green,pixels[1].green);
5296 pixel->blue=gamma*MeshInterpolate(&delta,pixels[3].blue,
5297 pixels[2].blue,pixels[1].blue);
cristy4c08aed2011-07-01 19:47:50 +00005298 if (image->colorspace == CMYKColorspace)
5299 pixel->black=gamma*MeshInterpolate(&delta,pixels[3].black,
5300 pixels[2].black,pixels[1].black);
cristy94ea1632011-07-30 20:40:25 +00005301 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005302 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[3].alpha,
5303 pixels[2].alpha,pixels[1].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005304 }
5305 }
5306 break;
5307 }
5308 case NearestNeighborInterpolatePixel:
5309 {
5310 p=GetCacheViewVirtualPixels(image_view,NearestNeighbor(x),
5311 NearestNeighbor(y),1,1,exception);
5312 if (p == (const Quantum *) NULL)
5313 {
5314 status=MagickFalse;
5315 break;
5316 }
cristy803640d2011-11-17 02:11:32 +00005317 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005318 break;
5319 }
5320 case SplineInterpolatePixel:
5321 {
5322 MagickRealType
5323 dx,
5324 dy;
5325
5326 PointInfo
5327 delta;
5328
5329 ssize_t
5330 j,
5331 n;
5332
5333 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5334 exception);
5335 if (p == (const Quantum *) NULL)
5336 {
5337 status=MagickFalse;
5338 break;
5339 }
cristy5ce8df82011-07-07 14:52:23 +00005340 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005341 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005342 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5343 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5344 AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
5345 AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
5346 AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
5347 AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
5348 AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
5349 AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
5350 AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
cristy865d58d2011-07-09 00:44:52 +00005351 10);
cristyed231572011-07-14 02:18:59 +00005352 AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
cristy865d58d2011-07-09 00:44:52 +00005353 11);
cristyed231572011-07-14 02:18:59 +00005354 AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
cristy865d58d2011-07-09 00:44:52 +00005355 12);
cristyed231572011-07-14 02:18:59 +00005356 AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
cristy865d58d2011-07-09 00:44:52 +00005357 13);
cristyed231572011-07-14 02:18:59 +00005358 AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
cristy865d58d2011-07-09 00:44:52 +00005359 14);
cristyed231572011-07-14 02:18:59 +00005360 AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
cristy865d58d2011-07-09 00:44:52 +00005361 15);
cristy4c08aed2011-07-01 19:47:50 +00005362 pixel->red=0.0;
5363 pixel->green=0.0;
5364 pixel->blue=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005365 pixel->black=0.0;
cristy865d58d2011-07-09 00:44:52 +00005366 pixel->alpha=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005367 delta.x=x-x_offset;
5368 delta.y=y-y_offset;
5369 n=0;
5370 for (i=(-1); i < 3L; i++)
5371 {
5372 dy=CubicWeightingFunction((MagickRealType) i-delta.y);
5373 for (j=(-1); j < 3L; j++)
5374 {
5375 dx=CubicWeightingFunction(delta.x-(MagickRealType) j);
5376 gamma=1.0/(fabs((double) alpha[n]) <= MagickEpsilon ? 1.0 : alpha[n]);
5377 pixel->red+=gamma*dx*dy*pixels[n].red;
5378 pixel->green+=gamma*dx*dy*pixels[n].green;
5379 pixel->blue+=gamma*dx*dy*pixels[n].blue;
5380 if (image->colorspace == CMYKColorspace)
5381 pixel->black+=gamma*dx*dy*pixels[n].black;
5382 pixel->alpha+=dx*dy*pixels[n].alpha;
5383 n++;
5384 }
5385 }
5386 break;
5387 }
5388 }
5389 return(status);
5390}
5391
5392/*
5393%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5394% %
5395% %
5396% %
5397+ I s F u z z y E q u i v a l e n c e P i x e l %
5398% %
5399% %
5400% %
5401%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5402%
5403% IsFuzzyEquivalencePixel() returns MagickTrue if the distance between two
5404% pixels is less than the specified distance in a linear three (or four)u
5405% dimensional color space.
5406%
5407% The format of the IsFuzzyEquivalencePixel method is:
5408%
cristye4a40472011-12-22 02:56:19 +00005409% void IsFuzzyEquivalencePixel(const Image *source,const Quantum *p,
5410% const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005411%
5412% A description of each parameter follows:
5413%
cristye4a40472011-12-22 02:56:19 +00005414% o source: the source image.
cristy4c08aed2011-07-01 19:47:50 +00005415%
5416% o p: Pixel p.
5417%
cristye4a40472011-12-22 02:56:19 +00005418% o destination: the destination image.
5419%
cristy4c08aed2011-07-01 19:47:50 +00005420% o q: Pixel q.
5421%
5422*/
cristye4a40472011-12-22 02:56:19 +00005423MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source,
5424 const Quantum *p,const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005425{
5426 MagickRealType
5427 fuzz,
5428 pixel;
5429
5430 register MagickRealType
5431 distance,
5432 scale;
5433
cristye4a40472011-12-22 02:56:19 +00005434 fuzz=MagickMax(source->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(
5435 destination->fuzz,(MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005436 scale=1.0;
5437 distance=0.0;
cristye4a40472011-12-22 02:56:19 +00005438 if (source->matte != MagickFalse)
cristy4c08aed2011-07-01 19:47:50 +00005439 {
5440 /*
5441 Transparencies are involved - set alpha distance
5442 */
cristy99abff32011-12-24 20:45:16 +00005443 pixel=GetPixelAlpha(source,p)-(MagickRealType)
5444 GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005445 distance=pixel*pixel;
5446 if (distance > fuzz)
5447 return(MagickFalse);
5448 /*
5449 Generate a alpha scaling factor to generate a 4D cone on colorspace
5450 Note that if one color is transparent, distance has no color component.
5451 */
cristye4a40472011-12-22 02:56:19 +00005452 scale=QuantumScale*GetPixelAlpha(source,p);
5453 scale*=QuantumScale*GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005454 if (scale <= MagickEpsilon)
5455 return(MagickTrue);
5456 }
5457 /*
5458 RGB or CMY color cube
5459 */
5460 distance*=3.0; /* rescale appropriately */
5461 fuzz*=3.0;
cristye4a40472011-12-22 02:56:19 +00005462 pixel=GetPixelRed(source,p)-(MagickRealType) GetPixelRed(destination,q);
5463 if ((source->colorspace == HSLColorspace) ||
5464 (source->colorspace == HSBColorspace) ||
5465 (source->colorspace == HWBColorspace))
cristy4c08aed2011-07-01 19:47:50 +00005466 {
5467 /*
5468 Compute an arc distance for hue. It should be a vector angle of
5469 'S'/'W' length with 'L'/'B' forming appropriate cones.
5470 */
5471 if (fabs((double) pixel) > (QuantumRange/2))
5472 pixel-=QuantumRange;
5473 pixel*=2;
5474 }
5475 distance+=scale*pixel*pixel;
5476 if (distance > fuzz)
5477 return(MagickFalse);
cristye4a40472011-12-22 02:56:19 +00005478 pixel=GetPixelGreen(source,p)-(MagickRealType) GetPixelGreen(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005479 distance+=scale*pixel*pixel;
5480 if (distance > fuzz)
5481 return(MagickFalse);
cristye4a40472011-12-22 02:56:19 +00005482 pixel=GetPixelBlue(source,p)-(MagickRealType) GetPixelBlue(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005483 distance+=scale*pixel*pixel;
5484 if (distance > fuzz)
5485 return(MagickFalse);
5486 return(MagickTrue);
5487}
5488
5489/*
5490%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5491% %
5492% %
5493% %
5494+ 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 %
5495% %
5496% %
5497% %
5498%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5499%
5500% IsFuzzyEquivalencePixelInfo() returns true if the distance between two
5501% colors is less than the specified distance in a linear three (or four)
5502% dimensional color space.
5503%
cristy5f95f4f2011-10-23 01:01:01 +00005504% This implements the equivalent of:
5505% fuzz < sqrt(color_distance^2 * u.a*v.a + alpha_distance^2)
cristy4c08aed2011-07-01 19:47:50 +00005506%
5507% Which produces a multi-dimensional cone for that colorspace along the
5508% transparency vector.
5509%
cristy5f95f4f2011-10-23 01:01:01 +00005510% For example for an RGB:
cristy4c08aed2011-07-01 19:47:50 +00005511% color_distance^2 = ( (u.r-v.r)^2 + (u.g-v.g)^2 + (u.b-v.b)^2 ) / 3
5512%
5513% See http://www.imagemagick.org/Usage/bugs/fuzz_distance/
5514%
5515% Hue colorspace distances need more work. Hue is not a distance, it is an
5516% angle!
5517%
5518% A check that q is in the same color space as p should be made and the
5519% appropriate mapping made. -- Anthony Thyssen 8 December 2010
5520%
5521% The format of the IsFuzzyEquivalencePixelInfo method is:
5522%
5523% MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5524% const PixelInfo *q)
5525%
5526% A description of each parameter follows:
5527%
5528% o p: Pixel p.
5529%
5530% o q: Pixel q.
5531%
5532*/
5533MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5534 const PixelInfo *q)
5535{
5536 MagickRealType
5537 fuzz,
5538 pixel;
5539
5540 register MagickRealType
5541 scale,
5542 distance;
5543
5544 if ((p->fuzz == 0.0) && (q->fuzz == 0.0))
5545 return(IsPixelInfoEquivalent(p,q));
5546 if (p->fuzz == 0.0)
cristy5f95f4f2011-10-23 01:01:01 +00005547 fuzz=MagickMax(q->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(q->fuzz,
5548 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005549 else if (q->fuzz == 0.0)
cristy5f95f4f2011-10-23 01:01:01 +00005550 fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(p->fuzz,
5551 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005552 else
cristy5f95f4f2011-10-23 01:01:01 +00005553 fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(q->fuzz,
5554 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005555 scale=1.0;
5556 distance=0.0;
5557 if ((p->matte != MagickFalse) || (q->matte != MagickFalse))
5558 {
5559 /*
5560 Transparencies are involved - set alpha distance.
5561 */
5562 pixel=(p->matte != MagickFalse ? p->alpha : OpaqueAlpha)-
5563 (q->matte != MagickFalse ? q->alpha : OpaqueAlpha);
5564 distance=pixel*pixel;
5565 if (distance > fuzz)
5566 return(MagickFalse);
5567 /*
5568 Generate a alpha scaling factor to generate a 4D cone on colorspace.
cristy5f95f4f2011-10-23 01:01:01 +00005569 If one color is transparent, distance has no color component.
cristy4c08aed2011-07-01 19:47:50 +00005570 */
5571 if (p->matte != MagickFalse)
5572 scale=(QuantumScale*p->alpha);
5573 if (q->matte != MagickFalse)
5574 scale*=(QuantumScale*q->alpha);
5575 if (scale <= MagickEpsilon )
5576 return(MagickTrue);
5577 }
5578 /*
5579 CMYK create a CMY cube with a multi-dimensional cone toward black.
5580 */
5581 if (p->colorspace == CMYKColorspace)
5582 {
5583 pixel=p->black-q->black;
5584 distance+=pixel*pixel*scale;
5585 if (distance > fuzz)
5586 return(MagickFalse);
5587 scale*=(MagickRealType) (QuantumScale*(QuantumRange-p->black));
5588 scale*=(MagickRealType) (QuantumScale*(QuantumRange-q->black));
5589 }
5590 /*
5591 RGB or CMY color cube.
5592 */
5593 distance*=3.0; /* rescale appropriately */
5594 fuzz*=3.0;
5595 pixel=p->red-q->red;
5596 if ((p->colorspace == HSLColorspace) || (p->colorspace == HSBColorspace) ||
5597 (p->colorspace == HWBColorspace))
5598 {
cristy5f95f4f2011-10-23 01:01:01 +00005599 /*
5600 This calculates a arc distance for hue-- it should be a vector angle
5601 of 'S'/'W' length with 'L'/'B' forming appropriate cones. In other
5602 words this is a hack - Anthony.
cristy4c08aed2011-07-01 19:47:50 +00005603 */
5604 if (fabs((double) pixel) > (QuantumRange/2))
5605 pixel-=QuantumRange;
5606 pixel*=2;
5607 }
5608 distance+=pixel*pixel*scale;
5609 if (distance > fuzz)
5610 return(MagickFalse);
5611 pixel=p->green-q->green;
5612 distance+=pixel*pixel*scale;
5613 if (distance > fuzz)
5614 return(MagickFalse);
5615 pixel=p->blue-q->blue;
5616 distance+=pixel*pixel*scale;
5617 if (distance > fuzz)
5618 return(MagickFalse);
5619 return(MagickTrue);
5620}
5621
5622/*
5623%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5624% %
5625% %
5626% %
cristye2a912b2011-12-05 20:02:07 +00005627% 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 +00005628% %
5629% %
5630% %
5631%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5632%
cristye2a912b2011-12-05 20:02:07 +00005633% SetPixelChannelMapMask() sets the pixel channel map from the specified
5634% channel mask.
cristy2b9582a2011-07-04 17:38:56 +00005635%
cristye2a912b2011-12-05 20:02:07 +00005636% The format of the SetPixelChannelMapMask method is:
cristy2b9582a2011-07-04 17:38:56 +00005637%
cristye2a912b2011-12-05 20:02:07 +00005638% void SetPixelChannelMapMask(Image *image,const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005639%
5640% A description of each parameter follows:
5641%
5642% o image: the image.
5643%
cristydfdb19e2012-03-21 22:22:24 +00005644% o channel_mask: the channel mask.
cristy2b9582a2011-07-04 17:38:56 +00005645%
5646*/
cristye2a912b2011-12-05 20:02:07 +00005647MagickExport void SetPixelChannelMapMask(Image *image,
cristy07a67852011-08-26 13:25:03 +00005648 const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005649{
cristy6a917d62011-08-24 17:31:30 +00005650#define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01)
cristydafd2872011-07-24 22:06:13 +00005651
cristy2b9582a2011-07-04 17:38:56 +00005652 register ssize_t
5653 i;
5654
cristy177e41c2012-04-15 15:08:25 +00005655 if (image->debug != MagickFalse)
5656 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%08x]", \
5657 image->filename,channel_mask); \
cristy3c309812011-11-08 02:40:43 +00005658 image->channel_mask=channel_mask;
cristydafd2872011-07-24 22:06:13 +00005659 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
cristye2a912b2011-12-05 20:02:07 +00005660 {
5661 PixelChannel
5662 channel;
5663
5664 channel=GetPixelChannelMapChannel(image,i);
5665 SetPixelChannelMapTraits(image,channel,
5666 GetChannelBit(channel_mask,channel) == 0 ? CopyPixelTrait :
cristy0bbd87c2011-12-13 19:34:45 +00005667 image->matte == MagickFalse || (channel == AlphaPixelChannel) ?
5668 UpdatePixelTrait : (PixelTrait) (UpdatePixelTrait | BlendPixelTrait));
cristye2a912b2011-12-05 20:02:07 +00005669 }
cristy1685e722011-09-06 00:04:19 +00005670 if (image->storage_class == PseudoClass)
5671 SetPixelChannelMapTraits(image,IndexPixelChannel,CopyPixelTrait);
cristy183a5c72012-01-30 01:40:35 +00005672 if (image->mask != MagickFalse)
cristy10a6c612012-01-29 21:41:05 +00005673 SetPixelChannelMapTraits(image,MaskPixelChannel,CopyPixelTrait);
cristy6dcb9b82011-10-23 23:21:25 +00005674 if (image->debug != MagickFalse)
5675 LogPixelChannels(image);
cristy2b9582a2011-07-04 17:38:56 +00005676}
5677
5678/*
5679%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5680% %
5681% %
5682% %
cristybd5a96c2011-08-21 00:04:26 +00005683% S e t P i x e l C h a n n e l M a s k %
cristy2b9582a2011-07-04 17:38:56 +00005684% %
5685% %
5686% %
5687%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5688%
cristy5f95f4f2011-10-23 01:01:01 +00005689% SetPixelChannelMask() sets the pixel channel mask from the specified channel
5690% mask.
cristy2b9582a2011-07-04 17:38:56 +00005691%
cristybd5a96c2011-08-21 00:04:26 +00005692% The format of the SetPixelChannelMask method is:
cristy2b9582a2011-07-04 17:38:56 +00005693%
cristybd5a96c2011-08-21 00:04:26 +00005694% ChannelType SetPixelChannelMask(Image *image,
5695% const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005696%
5697% A description of each parameter follows:
5698%
5699% o image: the image.
5700%
cristybd5a96c2011-08-21 00:04:26 +00005701% o channel_mask: the channel mask.
5702%
cristy2b9582a2011-07-04 17:38:56 +00005703*/
cristybd5a96c2011-08-21 00:04:26 +00005704MagickExport ChannelType SetPixelChannelMask(Image *image,
5705 const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005706{
cristybd5a96c2011-08-21 00:04:26 +00005707 ChannelType
5708 mask;
cristy222b19c2011-08-04 01:35:11 +00005709
cristybd5a96c2011-08-21 00:04:26 +00005710 mask=image->channel_mask;
5711 image->channel_mask=channel_mask;
cristye2a912b2011-12-05 20:02:07 +00005712 SetPixelChannelMapMask(image,channel_mask);
cristybd5a96c2011-08-21 00:04:26 +00005713 return(mask);
cristy2b9582a2011-07-04 17:38:56 +00005714}
cristy322d07d2012-03-18 21:17:23 +00005715
5716/*
5717%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5718% %
5719% %
5720% %
5721% S e t P i x e l M e t a C h a n n e l s %
5722% %
5723% %
5724% %
5725%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5726%
5727% SetPixelMetaChannels() sets the image meta channels.
5728%
5729% The format of the SetPixelMetaChannels method is:
5730%
5731% MagickBooleanType SetPixelMetaChannels(Image *image,
5732% const size_t number_meta_channels,ExceptionInfo *exception)
5733%
5734% A description of each parameter follows:
5735%
5736% o image: the image.
5737%
5738% o number_meta_channels: the number of meta channels.
5739%
5740% o exception: return any errors or warnings in this structure.
5741%
5742*/
5743MagickExport MagickBooleanType SetPixelMetaChannels(Image *image,
5744 const size_t number_meta_channels,ExceptionInfo *exception)
5745{
5746 image->number_meta_channels=number_meta_channels;
5747 return(SyncImagePixelCache(image,exception));
5748}