blob: 996cd1b7fc574aaa2ee77bb6c65de257c762acc5 [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"
cristy380a11c2012-06-02 15:15:22 +000062#include "MagickCore/pixel-private.h"
cristy4c08aed2011-07-01 19:47:50 +000063#include "MagickCore/quantum.h"
64#include "MagickCore/quantum-private.h"
65#include "MagickCore/resource_.h"
66#include "MagickCore/semaphore.h"
67#include "MagickCore/statistic.h"
68#include "MagickCore/stream.h"
69#include "MagickCore/string_.h"
70#include "MagickCore/transform.h"
71#include "MagickCore/utility.h"
72
cristy146a62b2011-10-23 23:40:46 +000073#define LogPixelChannels(image) \
74{ \
75 register ssize_t \
76 i; \
77 \
78 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%.20g]", \
79 image->filename,(double) image->number_channels); \
80 for (i=0; i < (ssize_t) image->number_channels; i++) \
81 { \
82 char \
83 traits[MaxTextExtent]; \
84 \
85 const char \
cristy46795722011-12-10 23:56:57 +000086 *name; \
87 \
88 PixelChannel \
89 channel; \
cristy146a62b2011-10-23 23:40:46 +000090 \
cristye2a912b2011-12-05 20:02:07 +000091 switch (GetPixelChannelMapChannel(image,i)) \
cristy146a62b2011-10-23 23:40:46 +000092 { \
93 case RedPixelChannel: \
94 { \
cristy46795722011-12-10 23:56:57 +000095 name="red"; \
cristy146a62b2011-10-23 23:40:46 +000096 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +000097 name="cyan"; \
cristy146a62b2011-10-23 23:40:46 +000098 if (image->colorspace == GRAYColorspace) \
cristy46795722011-12-10 23:56:57 +000099 name="gray"; \
cristy146a62b2011-10-23 23:40:46 +0000100 break; \
101 } \
102 case GreenPixelChannel: \
103 { \
cristy46795722011-12-10 23:56:57 +0000104 name="green"; \
cristy146a62b2011-10-23 23:40:46 +0000105 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +0000106 name="magenta"; \
cristy146a62b2011-10-23 23:40:46 +0000107 break; \
108 } \
109 case BluePixelChannel: \
110 { \
cristy46795722011-12-10 23:56:57 +0000111 name="blue"; \
cristy146a62b2011-10-23 23:40:46 +0000112 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +0000113 name="yellow"; \
cristy146a62b2011-10-23 23:40:46 +0000114 break; \
115 } \
116 case BlackPixelChannel: \
117 { \
cristy46795722011-12-10 23:56:57 +0000118 name="black"; \
cristy146a62b2011-10-23 23:40:46 +0000119 if (image->storage_class == PseudoClass) \
cristy46795722011-12-10 23:56:57 +0000120 name="index"; \
cristy146a62b2011-10-23 23:40:46 +0000121 break; \
122 } \
cristye2a912b2011-12-05 20:02:07 +0000123 case IndexPixelChannel: \
124 { \
cristy46795722011-12-10 23:56:57 +0000125 name="index"; \
cristye2a912b2011-12-05 20:02:07 +0000126 break; \
127 } \
cristy146a62b2011-10-23 23:40:46 +0000128 case AlphaPixelChannel: \
129 { \
cristy46795722011-12-10 23:56:57 +0000130 name="alpha"; \
cristy146a62b2011-10-23 23:40:46 +0000131 break; \
132 } \
133 case MaskPixelChannel: \
134 { \
cristy46795722011-12-10 23:56:57 +0000135 name="mask"; \
cristy146a62b2011-10-23 23:40:46 +0000136 break; \
137 } \
cristye2a912b2011-12-05 20:02:07 +0000138 case MetaPixelChannel: \
cristy146a62b2011-10-23 23:40:46 +0000139 { \
cristy46795722011-12-10 23:56:57 +0000140 name="meta"; \
cristye2a912b2011-12-05 20:02:07 +0000141 break; \
cristy146a62b2011-10-23 23:40:46 +0000142 } \
cristye2a912b2011-12-05 20:02:07 +0000143 default: \
cristy46795722011-12-10 23:56:57 +0000144 name="undefined"; \
cristy146a62b2011-10-23 23:40:46 +0000145 } \
cristy46795722011-12-10 23:56:57 +0000146 channel=GetPixelChannelMapChannel(image,i); \
cristy146a62b2011-10-23 23:40:46 +0000147 *traits='\0'; \
cristy46795722011-12-10 23:56:57 +0000148 if ((GetPixelChannelMapTraits(image,channel) & UpdatePixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000149 (void) ConcatenateMagickString(traits,"update,",MaxTextExtent); \
cristy46795722011-12-10 23:56:57 +0000150 if ((GetPixelChannelMapTraits(image,channel) & BlendPixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000151 (void) ConcatenateMagickString(traits,"blend,",MaxTextExtent); \
cristy46795722011-12-10 23:56:57 +0000152 if ((GetPixelChannelMapTraits(image,channel) & CopyPixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000153 (void) ConcatenateMagickString(traits,"copy,",MaxTextExtent); \
154 if (*traits == '\0') \
155 (void) ConcatenateMagickString(traits,"undefined,",MaxTextExtent); \
156 traits[strlen(traits)-1]='\0'; \
157 (void) LogMagickEvent(PixelEvent,GetMagickModule()," %.20g: %s (%s)", \
cristy46795722011-12-10 23:56:57 +0000158 (double) i,name,traits); \
cristy146a62b2011-10-23 23:40:46 +0000159 } \
160}
161
162/*
cristy4c08aed2011-07-01 19:47:50 +0000163%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164% %
165% %
166% %
cristyed231572011-07-14 02:18:59 +0000167+ A c q u i r e P i x e l C h a n n e l M a p %
cristy4c08aed2011-07-01 19:47:50 +0000168% %
169% %
170% %
171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172%
cristyed231572011-07-14 02:18:59 +0000173% AcquirePixelChannelMap() acquires a pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000174%
cristyed231572011-07-14 02:18:59 +0000175% The format of the AcquirePixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000176%
cristybd5a96c2011-08-21 00:04:26 +0000177% PixelChannelMap *AcquirePixelChannelMap(void)
cristy4c08aed2011-07-01 19:47:50 +0000178%
179*/
cristybd5a96c2011-08-21 00:04:26 +0000180MagickExport PixelChannelMap *AcquirePixelChannelMap(void)
cristy4c08aed2011-07-01 19:47:50 +0000181{
cristyed231572011-07-14 02:18:59 +0000182 PixelChannelMap
cristybd5a96c2011-08-21 00:04:26 +0000183 *channel_map;
cristy4c08aed2011-07-01 19:47:50 +0000184
185 register ssize_t
186 i;
187
cristybd5a96c2011-08-21 00:04:26 +0000188 channel_map=(PixelChannelMap *) AcquireQuantumMemory(MaxPixelChannels,
189 sizeof(*channel_map));
190 if (channel_map == (PixelChannelMap *) NULL)
cristy4c08aed2011-07-01 19:47:50 +0000191 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristybd5a96c2011-08-21 00:04:26 +0000192 (void) ResetMagickMemory(channel_map,0,MaxPixelChannels*sizeof(*channel_map));
193 for (i=0; i < MaxPixelChannels; i++)
194 channel_map[i].channel=(PixelChannel) i;
cristyed231572011-07-14 02:18:59 +0000195 return(channel_map);
cristy4c08aed2011-07-01 19:47:50 +0000196}
197
198/*
199%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
200% %
201% %
202% %
cristyed231572011-07-14 02:18:59 +0000203+ C l o n e P i x e l C h a n n e l M a p %
cristy4c08aed2011-07-01 19:47:50 +0000204% %
205% %
206% %
207%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
208%
cristyed231572011-07-14 02:18:59 +0000209% ClonePixelChannelMap() clones a pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000210%
cristyed231572011-07-14 02:18:59 +0000211% The format of the ClonePixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000212%
cristybd5a96c2011-08-21 00:04:26 +0000213% PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000214%
215% A description of each parameter follows:
216%
cristyed231572011-07-14 02:18:59 +0000217% o channel_map: the pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000218%
219*/
cristybd5a96c2011-08-21 00:04:26 +0000220MagickExport PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000221{
cristyed231572011-07-14 02:18:59 +0000222 PixelChannelMap
cristybd5a96c2011-08-21 00:04:26 +0000223 *clone_map;
cristy4c08aed2011-07-01 19:47:50 +0000224
cristybd5a96c2011-08-21 00:04:26 +0000225 assert(channel_map != (PixelChannelMap *) NULL);
cristyed231572011-07-14 02:18:59 +0000226 clone_map=AcquirePixelChannelMap();
cristybd5a96c2011-08-21 00:04:26 +0000227 if (clone_map == (PixelChannelMap *) NULL)
228 return((PixelChannelMap *) NULL);
229 (void) CopyMagickMemory(clone_map,channel_map,MaxPixelChannels*
230 sizeof(*channel_map));
cristy4c08aed2011-07-01 19:47:50 +0000231 return(clone_map);
232}
233
234/*
235%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
236% %
237% %
238% %
239+ C l o n e P i x e l I n f o %
240% %
241% %
242% %
243%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244%
245% ClonePixelInfo() makes a duplicate of the given pixel info structure, or if
246% pixel info is NULL, a new one.
247%
248% The format of the ClonePixelInfo method is:
249%
250% PixelInfo *ClonePixelInfo(const PixelInfo *pixel_info)
251%
252% A description of each parameter follows:
253%
254% o pixel_info: the pixel info.
255%
256*/
257MagickExport PixelInfo *ClonePixelInfo(const PixelInfo *pixel)
258{
259 PixelInfo
260 *pixel_info;
261
cristya64b85d2011-09-14 01:02:31 +0000262 pixel_info=(PixelInfo *) AcquireQuantumMemory(1,sizeof(*pixel_info));
cristy4c08aed2011-07-01 19:47:50 +0000263 if (pixel_info == (PixelInfo *) NULL)
264 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
265 *pixel_info=(*pixel);
266 return(pixel_info);
267}
268
269/*
270%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271% %
272% %
273% %
cristyed231572011-07-14 02:18:59 +0000274+ 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 +0000275% %
276% %
277% %
278%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279%
cristyed231572011-07-14 02:18:59 +0000280% DestroyPixelChannelMap() deallocates memory associated with the pixel
281% channel map.
cristy4c08aed2011-07-01 19:47:50 +0000282%
cristyed231572011-07-14 02:18:59 +0000283% The format of the DestroyPixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000284%
cristybd5a96c2011-08-21 00:04:26 +0000285% PixelChannelMap *DestroyPixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000286%
287% A description of each parameter follows:
288%
cristyed231572011-07-14 02:18:59 +0000289% o channel_map: the pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000290%
291*/
cristybd5a96c2011-08-21 00:04:26 +0000292MagickExport PixelChannelMap *DestroyPixelChannelMap(
293 PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000294{
cristybd5a96c2011-08-21 00:04:26 +0000295 assert(channel_map != (PixelChannelMap *) NULL);
296 channel_map=(PixelChannelMap *) RelinquishMagickMemory(channel_map);
297 return((PixelChannelMap *) RelinquishMagickMemory(channel_map));
cristy4c08aed2011-07-01 19:47:50 +0000298}
299
300/*
301%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
302% %
303% %
304% %
305% E x p o r t I m a g e P i x e l s %
306% %
307% %
308% %
309%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
310%
311% ExportImagePixels() extracts pixel data from an image and returns it to you.
312% The method returns MagickTrue on success otherwise MagickFalse if an error is
cristyb5a45a32012-01-10 13:31:13 +0000313% encountered. The data is returned as char, short int, Quantum, unsigned int,
cristycafe0412012-01-10 13:29:58 +0000314% unsigned long long, float, or double in the order specified by map.
cristy4c08aed2011-07-01 19:47:50 +0000315%
316% Suppose you want to extract the first scanline of a 640x480 image as
317% character data in red-green-blue order:
318%
319% ExportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels,exception);
320%
321% The format of the ExportImagePixels method is:
322%
cristycafe0412012-01-10 13:29:58 +0000323% MagickBooleanType ExportImagePixels(const Image *image,const ssize_t x,
324% const ssize_t y,const size_t width,const size_t height,
325% const char *map,const StorageType type,void *pixels,
cristy46f4be22012-01-07 00:26:39 +0000326% ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +0000327%
328% A description of each parameter follows:
329%
330% o image: the image.
331%
cristycafe0412012-01-10 13:29:58 +0000332% o x,y,width,height: These values define the perimeter
cristy4c08aed2011-07-01 19:47:50 +0000333% of a region of pixels you want to extract.
334%
335% o map: This string reflects the expected ordering of the pixel array.
336% It can be any combination or order of R = red, G = green, B = blue,
337% A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
338% Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
339% P = pad.
340%
341% o type: Define the data type of the pixels. Float and double types are
342% normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
cristy6c9e1682012-01-07 21:37:44 +0000343% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
cristyff6834e2012-01-10 03:00:25 +0000344% LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
cristy6c9e1682012-01-07 21:37:44 +0000345% QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
cristy4c08aed2011-07-01 19:47:50 +0000346%
347% o pixels: This array of values contain the pixel components as defined by
348% map and type. You must preallocate this array where the expected
349% length varies depending on the values of width, height, map, and type.
350%
351% o exception: return any errors or warnings in this structure.
352%
353*/
cristye5370942012-01-06 03:49:31 +0000354
cristycafe0412012-01-10 13:29:58 +0000355static void ExportCharPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000356 const char *restrict map,const QuantumType *quantum_map,void *pixels,
357 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000358{
359 register const Quantum
360 *restrict p;
361
362 register ssize_t
363 x;
364
365 register unsigned char
cristy3fe11452012-01-09 01:27:42 +0000366 *restrict q;
cristye5370942012-01-06 03:49:31 +0000367
cristy14d71292012-05-20 16:48:13 +0000368 size_t
369 length;
370
cristye5370942012-01-06 03:49:31 +0000371 ssize_t
372 y;
373
cristy46f4be22012-01-07 00:26:39 +0000374 q=(unsigned char *) pixels;
cristye5370942012-01-06 03:49:31 +0000375 if (LocaleCompare(map,"BGR") == 0)
376 {
cristycafe0412012-01-10 13:29:58 +0000377 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000378 {
cristycafe0412012-01-10 13:29:58 +0000379 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000380 if (p == (const Quantum *) NULL)
381 break;
cristycafe0412012-01-10 13:29:58 +0000382 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000383 {
384 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
385 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
386 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
387 p+=GetPixelChannels(image);
388 }
389 }
390 return;
391 }
392 if (LocaleCompare(map,"BGRA") == 0)
393 {
cristycafe0412012-01-10 13:29:58 +0000394 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000395 {
cristycafe0412012-01-10 13:29:58 +0000396 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000397 if (p == (const Quantum *) NULL)
398 break;
cristycafe0412012-01-10 13:29:58 +0000399 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000400 {
401 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
402 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
403 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
404 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
405 p+=GetPixelChannels(image);
406 }
407 }
408 return;
409 }
410 if (LocaleCompare(map,"BGRP") == 0)
411 {
cristycafe0412012-01-10 13:29:58 +0000412 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000413 {
cristycafe0412012-01-10 13:29:58 +0000414 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000415 if (p == (const Quantum *) NULL)
416 break;
cristycafe0412012-01-10 13:29:58 +0000417 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000418 {
419 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
420 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
421 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
422 *q++=ScaleQuantumToChar((Quantum) 0);
423 p+=GetPixelChannels(image);
424 }
425 }
426 return;
427 }
428 if (LocaleCompare(map,"I") == 0)
429 {
cristycafe0412012-01-10 13:29:58 +0000430 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000431 {
cristycafe0412012-01-10 13:29:58 +0000432 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000433 if (p == (const Quantum *) NULL)
434 break;
cristycafe0412012-01-10 13:29:58 +0000435 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000436 {
437 *q++=ScaleQuantumToChar(GetPixelIntensity(image,p));
438 p+=GetPixelChannels(image);
439 }
440 }
441 return;
442 }
443 if (LocaleCompare(map,"RGB") == 0)
444 {
cristycafe0412012-01-10 13:29:58 +0000445 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000446 {
cristycafe0412012-01-10 13:29:58 +0000447 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000448 if (p == (const Quantum *) NULL)
449 break;
cristycafe0412012-01-10 13:29:58 +0000450 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000451 {
452 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
453 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
454 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
455 p+=GetPixelChannels(image);
456 }
457 }
458 return;
459 }
460 if (LocaleCompare(map,"RGBA") == 0)
461 {
cristycafe0412012-01-10 13:29:58 +0000462 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000463 {
cristycafe0412012-01-10 13:29:58 +0000464 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000465 if (p == (const Quantum *) NULL)
466 break;
cristycafe0412012-01-10 13:29:58 +0000467 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000468 {
469 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
470 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
471 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
472 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
473 p+=GetPixelChannels(image);
474 }
475 }
476 return;
477 }
478 if (LocaleCompare(map,"RGBP") == 0)
479 {
cristycafe0412012-01-10 13:29:58 +0000480 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000481 {
cristycafe0412012-01-10 13:29:58 +0000482 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000483 if (p == (const Quantum *) NULL)
484 break;
cristycafe0412012-01-10 13:29:58 +0000485 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000486 {
487 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
488 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
489 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
490 *q++=ScaleQuantumToChar((Quantum) 0);
491 p+=GetPixelChannels(image);
492 }
493 }
494 return;
495 }
cristy14d71292012-05-20 16:48:13 +0000496 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +0000497 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000498 {
cristycafe0412012-01-10 13:29:58 +0000499 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000500 if (p == (const Quantum *) NULL)
501 break;
cristycafe0412012-01-10 13:29:58 +0000502 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000503 {
504 register ssize_t
505 i;
506
cristy14d71292012-05-20 16:48:13 +0000507 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +0000508 {
509 *q=0;
510 switch (quantum_map[i])
511 {
512 case RedQuantum:
513 case CyanQuantum:
514 {
515 *q=ScaleQuantumToChar(GetPixelRed(image,p));
516 break;
517 }
518 case GreenQuantum:
519 case MagentaQuantum:
520 {
521 *q=ScaleQuantumToChar(GetPixelGreen(image,p));
522 break;
523 }
524 case BlueQuantum:
525 case YellowQuantum:
526 {
527 *q=ScaleQuantumToChar(GetPixelBlue(image,p));
528 break;
529 }
530 case AlphaQuantum:
531 {
532 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
533 break;
534 }
535 case OpacityQuantum:
536 {
537 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
538 break;
539 }
540 case BlackQuantum:
541 {
542 if (image->colorspace == CMYKColorspace)
543 *q=ScaleQuantumToChar(GetPixelBlack(image,p));
544 break;
545 }
546 case IndexQuantum:
547 {
548 *q=ScaleQuantumToChar(GetPixelIntensity(image,p));
549 break;
550 }
551 default:
552 break;
553 }
554 q++;
555 }
556 p+=GetPixelChannels(image);
557 }
558 }
559}
560
cristycafe0412012-01-10 13:29:58 +0000561static void ExportDoublePixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000562 const char *restrict map,const QuantumType *quantum_map,void *pixels,
563 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000564{
565 register const Quantum
566 *restrict p;
567
568 register double
cristy3fe11452012-01-09 01:27:42 +0000569 *restrict q;
cristye5370942012-01-06 03:49:31 +0000570
571 register ssize_t
572 x;
573
cristy14d71292012-05-20 16:48:13 +0000574 size_t
575 length;
576
cristye5370942012-01-06 03:49:31 +0000577 ssize_t
578 y;
579
580 q=(double *) pixels;
581 if (LocaleCompare(map,"BGR") == 0)
582 {
cristycafe0412012-01-10 13:29:58 +0000583 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000584 {
cristycafe0412012-01-10 13:29:58 +0000585 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000586 if (p == (const Quantum *) NULL)
587 break;
cristycafe0412012-01-10 13:29:58 +0000588 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000589 {
590 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
591 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
592 *q++=(double) (QuantumScale*GetPixelRed(image,p));
593 p+=GetPixelChannels(image);
594 }
595 }
596 return;
597 }
598 if (LocaleCompare(map,"BGRA") == 0)
599 {
cristycafe0412012-01-10 13:29:58 +0000600 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000601 {
cristycafe0412012-01-10 13:29:58 +0000602 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000603 if (p == (const Quantum *) NULL)
604 break;
cristycafe0412012-01-10 13:29:58 +0000605 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000606 {
607 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
608 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
609 *q++=(double) (QuantumScale*GetPixelRed(image,p));
610 *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
611 p+=GetPixelChannels(image);
612 }
613 }
614 return;
615 }
616 if (LocaleCompare(map,"BGRP") == 0)
617 {
cristycafe0412012-01-10 13:29:58 +0000618 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000619 {
cristycafe0412012-01-10 13:29:58 +0000620 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000621 if (p == (const Quantum *) NULL)
622 break;
cristycafe0412012-01-10 13:29:58 +0000623 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000624 {
625 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
626 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
627 *q++=(double) (QuantumScale*GetPixelRed(image,p));
628 *q++=0.0;
629 p+=GetPixelChannels(image);
630 }
631 }
632 return;
633 }
634 if (LocaleCompare(map,"I") == 0)
635 {
cristycafe0412012-01-10 13:29:58 +0000636 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000637 {
cristycafe0412012-01-10 13:29:58 +0000638 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000639 if (p == (const Quantum *) NULL)
640 break;
cristycafe0412012-01-10 13:29:58 +0000641 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000642 {
643 *q++=(double) (QuantumScale*GetPixelIntensity(image,p));
644 p+=GetPixelChannels(image);
645 }
646 }
647 return;
648 }
649 if (LocaleCompare(map,"RGB") == 0)
650 {
cristycafe0412012-01-10 13:29:58 +0000651 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000652 {
cristycafe0412012-01-10 13:29:58 +0000653 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000654 if (p == (const Quantum *) NULL)
655 break;
cristycafe0412012-01-10 13:29:58 +0000656 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000657 {
658 *q++=(double) (QuantumScale*GetPixelRed(image,p));
659 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
660 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
661 p+=GetPixelChannels(image);
662 }
663 }
664 return;
665 }
666 if (LocaleCompare(map,"RGBA") == 0)
667 {
cristycafe0412012-01-10 13:29:58 +0000668 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000669 {
cristycafe0412012-01-10 13:29:58 +0000670 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000671 if (p == (const Quantum *) NULL)
672 break;
cristycafe0412012-01-10 13:29:58 +0000673 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000674 {
675 *q++=(double) (QuantumScale*GetPixelRed(image,p));
676 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
677 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
678 *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
679 p+=GetPixelChannels(image);
680 }
681 }
682 return;
683 }
684 if (LocaleCompare(map,"RGBP") == 0)
685 {
cristycafe0412012-01-10 13:29:58 +0000686 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000687 {
cristycafe0412012-01-10 13:29:58 +0000688 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000689 if (p == (const Quantum *) NULL)
690 break;
cristycafe0412012-01-10 13:29:58 +0000691 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000692 {
693 *q++=(double) (QuantumScale*GetPixelRed(image,p));
694 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
695 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
696 *q++=0.0;
697 p+=GetPixelChannels(image);
698 }
699 }
700 return;
701 }
cristy14d71292012-05-20 16:48:13 +0000702 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +0000703 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000704 {
cristycafe0412012-01-10 13:29:58 +0000705 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000706 if (p == (const Quantum *) NULL)
707 break;
cristycafe0412012-01-10 13:29:58 +0000708 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000709 {
710 register ssize_t
711 i;
712
cristy14d71292012-05-20 16:48:13 +0000713 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +0000714 {
715 *q=0;
716 switch (quantum_map[i])
717 {
718 case RedQuantum:
719 case CyanQuantum:
720 {
721 *q=(double) (QuantumScale*GetPixelRed(image,p));
722 break;
723 }
724 case GreenQuantum:
725 case MagentaQuantum:
726 {
727 *q=(double) (QuantumScale*GetPixelGreen(image,p));
728 break;
729 }
730 case BlueQuantum:
731 case YellowQuantum:
732 {
733 *q=(double) (QuantumScale*GetPixelBlue(image,p));
734 break;
735 }
736 case AlphaQuantum:
737 {
738 *q=(double) (QuantumScale*GetPixelAlpha(image,p));
739 break;
740 }
741 case OpacityQuantum:
742 {
743 *q=(double) (QuantumScale*GetPixelAlpha(image,p));
744 break;
745 }
746 case BlackQuantum:
747 {
748 if (image->colorspace == CMYKColorspace)
749 *q=(double) (QuantumScale*
750 GetPixelBlack(image,p));
751 break;
752 }
753 case IndexQuantum:
754 {
755 *q=(double) (QuantumScale*GetPixelIntensity(image,p));
756 break;
757 }
758 default:
759 *q=0;
760 }
761 q++;
762 }
763 p+=GetPixelChannels(image);
764 }
765 }
766}
767
cristycafe0412012-01-10 13:29:58 +0000768static void ExportFloatPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000769 const char *restrict map,const QuantumType *quantum_map,void *pixels,
770 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000771{
772 register const Quantum
773 *restrict p;
774
775 register float
cristy3fe11452012-01-09 01:27:42 +0000776 *restrict q;
cristye5370942012-01-06 03:49:31 +0000777
778 register ssize_t
779 x;
780
cristy14d71292012-05-20 16:48:13 +0000781 size_t
782 length;
783
cristye5370942012-01-06 03:49:31 +0000784 ssize_t
785 y;
786
787 q=(float *) pixels;
788 if (LocaleCompare(map,"BGR") == 0)
789 {
cristycafe0412012-01-10 13:29:58 +0000790 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000791 {
cristycafe0412012-01-10 13:29:58 +0000792 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000793 if (p == (const Quantum *) NULL)
794 break;
cristycafe0412012-01-10 13:29:58 +0000795 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000796 {
797 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
798 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
799 *q++=(float) (QuantumScale*GetPixelRed(image,p));
800 p+=GetPixelChannels(image);
801 }
802 }
803 return;
804 }
805 if (LocaleCompare(map,"BGRA") == 0)
806 {
cristycafe0412012-01-10 13:29:58 +0000807 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000808 {
cristycafe0412012-01-10 13:29:58 +0000809 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000810 if (p == (const Quantum *) NULL)
811 break;
cristycafe0412012-01-10 13:29:58 +0000812 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000813 {
814 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
815 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
816 *q++=(float) (QuantumScale*GetPixelRed(image,p));
817 *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
818 p+=GetPixelChannels(image);
819 }
820 }
821 return;
822 }
823 if (LocaleCompare(map,"BGRP") == 0)
824 {
cristycafe0412012-01-10 13:29:58 +0000825 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000826 {
cristycafe0412012-01-10 13:29:58 +0000827 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000828 if (p == (const Quantum *) NULL)
829 break;
cristycafe0412012-01-10 13:29:58 +0000830 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000831 {
832 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
833 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
834 *q++=(float) (QuantumScale*GetPixelRed(image,p));
835 *q++=0.0;
836 p+=GetPixelChannels(image);
837 }
838 }
839 return;
840 }
841 if (LocaleCompare(map,"I") == 0)
842 {
cristycafe0412012-01-10 13:29:58 +0000843 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000844 {
cristycafe0412012-01-10 13:29:58 +0000845 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000846 if (p == (const Quantum *) NULL)
847 break;
cristycafe0412012-01-10 13:29:58 +0000848 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000849 {
850 *q++=(float) (QuantumScale*GetPixelIntensity(image,p));
851 p+=GetPixelChannels(image);
852 }
853 }
854 return;
855 }
856 if (LocaleCompare(map,"RGB") == 0)
857 {
cristycafe0412012-01-10 13:29:58 +0000858 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000859 {
cristycafe0412012-01-10 13:29:58 +0000860 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000861 if (p == (const Quantum *) NULL)
862 break;
cristycafe0412012-01-10 13:29:58 +0000863 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000864 {
865 *q++=(float) (QuantumScale*GetPixelRed(image,p));
866 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
867 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
868 p+=GetPixelChannels(image);
869 }
870 }
871 return;
872 }
873 if (LocaleCompare(map,"RGBA") == 0)
874 {
cristycafe0412012-01-10 13:29:58 +0000875 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000876 {
cristycafe0412012-01-10 13:29:58 +0000877 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000878 if (p == (const Quantum *) NULL)
879 break;
cristycafe0412012-01-10 13:29:58 +0000880 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000881 {
882 *q++=(float) (QuantumScale*GetPixelRed(image,p));
883 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
884 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
885 *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
886 p+=GetPixelChannels(image);
887 }
888 }
889 return;
890 }
891 if (LocaleCompare(map,"RGBP") == 0)
892 {
cristycafe0412012-01-10 13:29:58 +0000893 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000894 {
cristycafe0412012-01-10 13:29:58 +0000895 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000896 if (p == (const Quantum *) NULL)
897 break;
cristycafe0412012-01-10 13:29:58 +0000898 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000899 {
900 *q++=(float) (QuantumScale*GetPixelRed(image,p));
901 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
902 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
903 *q++=0.0;
904 p+=GetPixelChannels(image);
905 }
906 }
907 return;
908 }
cristy14d71292012-05-20 16:48:13 +0000909 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +0000910 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000911 {
cristycafe0412012-01-10 13:29:58 +0000912 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000913 if (p == (const Quantum *) NULL)
914 break;
cristycafe0412012-01-10 13:29:58 +0000915 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000916 {
917 register ssize_t
918 i;
919
cristy14d71292012-05-20 16:48:13 +0000920 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +0000921 {
922 *q=0;
923 switch (quantum_map[i])
924 {
925 case RedQuantum:
926 case CyanQuantum:
927 {
928 *q=(float) (QuantumScale*GetPixelRed(image,p));
929 break;
930 }
931 case GreenQuantum:
932 case MagentaQuantum:
933 {
934 *q=(float) (QuantumScale*GetPixelGreen(image,p));
935 break;
936 }
937 case BlueQuantum:
938 case YellowQuantum:
939 {
940 *q=(float) (QuantumScale*GetPixelBlue(image,p));
941 break;
942 }
943 case AlphaQuantum:
944 {
945 *q=(float) (QuantumScale*((Quantum) (GetPixelAlpha(image,p))));
946 break;
947 }
948 case OpacityQuantum:
949 {
950 *q=(float) (QuantumScale*GetPixelAlpha(image,p));
951 break;
952 }
953 case BlackQuantum:
954 {
955 if (image->colorspace == CMYKColorspace)
956 *q=(float) (QuantumScale* GetPixelBlack(image,p));
957 break;
958 }
959 case IndexQuantum:
960 {
961 *q=(float) (QuantumScale*GetPixelIntensity(image,p));
962 break;
963 }
964 default:
965 *q=0;
966 }
967 q++;
968 }
969 p+=GetPixelChannels(image);
970 }
971 }
972}
973
cristycafe0412012-01-10 13:29:58 +0000974static void ExportLongPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000975 const char *restrict map,const QuantumType *quantum_map,void *pixels,
976 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000977{
978 register const Quantum
979 *restrict p;
980
981 register ssize_t
982 x;
983
984 register unsigned int
cristy3fe11452012-01-09 01:27:42 +0000985 *restrict q;
cristye5370942012-01-06 03:49:31 +0000986
cristy14d71292012-05-20 16:48:13 +0000987 size_t
988 length;
989
cristye5370942012-01-06 03:49:31 +0000990 ssize_t
991 y;
992
993 q=(unsigned int *) pixels;
994 if (LocaleCompare(map,"BGR") == 0)
995 {
cristycafe0412012-01-10 13:29:58 +0000996 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000997 {
cristycafe0412012-01-10 13:29:58 +0000998 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000999 if (p == (const Quantum *) NULL)
1000 break;
cristycafe0412012-01-10 13:29:58 +00001001 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001002 {
cristy6c9e1682012-01-07 21:37:44 +00001003 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1004 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1005 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001006 p+=GetPixelChannels(image);
1007 }
1008 }
1009 return;
1010 }
1011 if (LocaleCompare(map,"BGRA") == 0)
1012 {
cristycafe0412012-01-10 13:29:58 +00001013 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001014 {
cristycafe0412012-01-10 13:29:58 +00001015 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001016 if (p == (const Quantum *) NULL)
1017 break;
cristycafe0412012-01-10 13:29:58 +00001018 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001019 {
cristy6c9e1682012-01-07 21:37:44 +00001020 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1021 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1022 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1023 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001024 p+=GetPixelChannels(image);
1025 }
1026 }
1027 return;
1028 }
1029 if (LocaleCompare(map,"BGRP") == 0)
1030 {
cristycafe0412012-01-10 13:29:58 +00001031 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001032 {
cristycafe0412012-01-10 13:29:58 +00001033 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001034 if (p == (const Quantum *) NULL)
1035 break;
cristycafe0412012-01-10 13:29:58 +00001036 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001037 {
cristy6c9e1682012-01-07 21:37:44 +00001038 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1039 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1040 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1041 *q++=0;
cristye5370942012-01-06 03:49:31 +00001042 p+=GetPixelChannels(image);
1043 }
1044 }
1045 return;
1046 }
1047 if (LocaleCompare(map,"I") == 0)
1048 {
cristycafe0412012-01-10 13:29:58 +00001049 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001050 {
cristycafe0412012-01-10 13:29:58 +00001051 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001052 if (p == (const Quantum *) NULL)
1053 break;
cristycafe0412012-01-10 13:29:58 +00001054 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001055 {
cristy6c9e1682012-01-07 21:37:44 +00001056 *q++=ScaleQuantumToLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001057 p+=GetPixelChannels(image);
1058 }
1059 }
1060 return;
1061 }
1062 if (LocaleCompare(map,"RGB") == 0)
1063 {
cristycafe0412012-01-10 13:29:58 +00001064 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001065 {
cristycafe0412012-01-10 13:29:58 +00001066 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001067 if (p == (const Quantum *) NULL)
1068 break;
cristycafe0412012-01-10 13:29:58 +00001069 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001070 {
cristy6c9e1682012-01-07 21:37:44 +00001071 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1072 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1073 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001074 p+=GetPixelChannels(image);
1075 }
1076 }
1077 return;
1078 }
1079 if (LocaleCompare(map,"RGBA") == 0)
1080 {
cristycafe0412012-01-10 13:29:58 +00001081 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001082 {
cristycafe0412012-01-10 13:29:58 +00001083 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001084 if (p == (const Quantum *) NULL)
1085 break;
cristycafe0412012-01-10 13:29:58 +00001086 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001087 {
cristy6c9e1682012-01-07 21:37:44 +00001088 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1089 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1090 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1091 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001092 p+=GetPixelChannels(image);
1093 }
1094 }
1095 return;
1096 }
1097 if (LocaleCompare(map,"RGBP") == 0)
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 {
cristy6c9e1682012-01-07 21:37:44 +00001106 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1107 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1108 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1109 *q++=0;
cristye5370942012-01-06 03:49:31 +00001110 p+=GetPixelChannels(image);
1111 }
1112 }
1113 return;
1114 }
cristy14d71292012-05-20 16:48:13 +00001115 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00001116 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001117 {
cristycafe0412012-01-10 13:29:58 +00001118 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001119 if (p == (const Quantum *) NULL)
1120 break;
cristycafe0412012-01-10 13:29:58 +00001121 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001122 {
1123 register ssize_t
1124 i;
1125
cristy14d71292012-05-20 16:48:13 +00001126 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00001127 {
1128 *q=0;
1129 switch (quantum_map[i])
1130 {
1131 case RedQuantum:
1132 case CyanQuantum:
1133 {
cristy6c9e1682012-01-07 21:37:44 +00001134 *q=ScaleQuantumToLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001135 break;
1136 }
1137 case GreenQuantum:
1138 case MagentaQuantum:
1139 {
cristy6c9e1682012-01-07 21:37:44 +00001140 *q=ScaleQuantumToLong(GetPixelGreen(image,p));
cristye5370942012-01-06 03:49:31 +00001141 break;
1142 }
1143 case BlueQuantum:
1144 case YellowQuantum:
1145 {
cristy6c9e1682012-01-07 21:37:44 +00001146 *q=ScaleQuantumToLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001147 break;
1148 }
1149 case AlphaQuantum:
1150 {
cristy6c9e1682012-01-07 21:37:44 +00001151 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001152 break;
1153 }
1154 case OpacityQuantum:
1155 {
cristy6c9e1682012-01-07 21:37:44 +00001156 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001157 break;
1158 }
1159 case BlackQuantum:
1160 {
1161 if (image->colorspace == CMYKColorspace)
cristy6c9e1682012-01-07 21:37:44 +00001162 *q=ScaleQuantumToLong(GetPixelBlack(image,p));
cristye5370942012-01-06 03:49:31 +00001163 break;
1164 }
1165 case IndexQuantum:
1166 {
cristy6c9e1682012-01-07 21:37:44 +00001167 *q=ScaleQuantumToLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001168 break;
1169 }
1170 default:
cristy6c9e1682012-01-07 21:37:44 +00001171 break;
cristye5370942012-01-06 03:49:31 +00001172 }
1173 q++;
1174 }
1175 p+=GetPixelChannels(image);
1176 }
1177 }
1178}
1179
cristycafe0412012-01-10 13:29:58 +00001180static void ExportLongLongPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00001181 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1182 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001183{
1184 register const Quantum
1185 *restrict p;
1186
1187 register ssize_t
1188 x;
1189
cristyb13e12a2012-01-06 21:48:27 +00001190 register MagickSizeType
cristy3fe11452012-01-09 01:27:42 +00001191 *restrict q;
cristye5370942012-01-06 03:49:31 +00001192
cristy14d71292012-05-20 16:48:13 +00001193 size_t
1194 length;
1195
cristye5370942012-01-06 03:49:31 +00001196 ssize_t
1197 y;
1198
cristyb13e12a2012-01-06 21:48:27 +00001199 q=(MagickSizeType *) pixels;
cristye5370942012-01-06 03:49:31 +00001200 if (LocaleCompare(map,"BGR") == 0)
1201 {
cristycafe0412012-01-10 13:29:58 +00001202 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001203 {
cristycafe0412012-01-10 13:29:58 +00001204 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001205 if (p == (const Quantum *) NULL)
1206 break;
cristycafe0412012-01-10 13:29:58 +00001207 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001208 {
cristyb13e12a2012-01-06 21:48:27 +00001209 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1210 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1211 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001212 p+=GetPixelChannels(image);
1213 }
1214 }
1215 return;
1216 }
1217 if (LocaleCompare(map,"BGRA") == 0)
1218 {
cristycafe0412012-01-10 13:29:58 +00001219 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001220 {
cristycafe0412012-01-10 13:29:58 +00001221 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001222 if (p == (const Quantum *) NULL)
1223 break;
cristycafe0412012-01-10 13:29:58 +00001224 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001225 {
cristyb13e12a2012-01-06 21:48:27 +00001226 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1227 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1228 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1229 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001230 p+=GetPixelChannels(image);
1231 }
1232 }
1233 return;
1234 }
1235 if (LocaleCompare(map,"BGRP") == 0)
1236 {
cristycafe0412012-01-10 13:29:58 +00001237 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001238 {
cristycafe0412012-01-10 13:29:58 +00001239 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001240 if (p == (const Quantum *) NULL)
1241 break;
cristycafe0412012-01-10 13:29:58 +00001242 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001243 {
cristyb13e12a2012-01-06 21:48:27 +00001244 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1245 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1246 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001247 *q++=0;
1248 p+=GetPixelChannels(image);
1249 }
1250 }
1251 return;
1252 }
1253 if (LocaleCompare(map,"I") == 0)
1254 {
cristycafe0412012-01-10 13:29:58 +00001255 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001256 {
cristycafe0412012-01-10 13:29:58 +00001257 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001258 if (p == (const Quantum *) NULL)
1259 break;
cristycafe0412012-01-10 13:29:58 +00001260 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001261 {
cristyb13e12a2012-01-06 21:48:27 +00001262 *q++=ScaleQuantumToLongLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001263 p+=GetPixelChannels(image);
1264 }
1265 }
1266 return;
1267 }
1268 if (LocaleCompare(map,"RGB") == 0)
1269 {
cristycafe0412012-01-10 13:29:58 +00001270 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001271 {
cristycafe0412012-01-10 13:29:58 +00001272 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001273 if (p == (const Quantum *) NULL)
1274 break;
cristycafe0412012-01-10 13:29:58 +00001275 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001276 {
cristyb13e12a2012-01-06 21:48:27 +00001277 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1278 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1279 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001280 p+=GetPixelChannels(image);
1281 }
1282 }
1283 return;
1284 }
1285 if (LocaleCompare(map,"RGBA") == 0)
1286 {
cristycafe0412012-01-10 13:29:58 +00001287 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001288 {
cristycafe0412012-01-10 13:29:58 +00001289 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001290 if (p == (const Quantum *) NULL)
1291 break;
cristycafe0412012-01-10 13:29:58 +00001292 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001293 {
cristyb13e12a2012-01-06 21:48:27 +00001294 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1295 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1296 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1297 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001298 p+=GetPixelChannels(image);
1299 }
1300 }
1301 return;
1302 }
1303 if (LocaleCompare(map,"RGBP") == 0)
1304 {
cristycafe0412012-01-10 13:29:58 +00001305 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001306 {
cristycafe0412012-01-10 13:29:58 +00001307 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001308 if (p == (const Quantum *) NULL)
1309 break;
cristycafe0412012-01-10 13:29:58 +00001310 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001311 {
cristyb13e12a2012-01-06 21:48:27 +00001312 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1313 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1314 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001315 *q++=0;
1316 p+=GetPixelChannels(image);
1317 }
1318 }
1319 return;
1320 }
cristy14d71292012-05-20 16:48:13 +00001321 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00001322 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001323 {
cristycafe0412012-01-10 13:29:58 +00001324 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001325 if (p == (const Quantum *) NULL)
1326 break;
cristycafe0412012-01-10 13:29:58 +00001327 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001328 {
1329 register ssize_t
1330 i;
1331
cristy14d71292012-05-20 16:48:13 +00001332 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00001333 {
1334 *q=0;
1335 switch (quantum_map[i])
1336 {
1337 case RedQuantum:
1338 case CyanQuantum:
1339 {
cristyb13e12a2012-01-06 21:48:27 +00001340 *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001341 break;
1342 }
1343 case GreenQuantum:
1344 case MagentaQuantum:
1345 {
cristyb13e12a2012-01-06 21:48:27 +00001346 *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
cristye5370942012-01-06 03:49:31 +00001347 break;
1348 }
1349 case BlueQuantum:
1350 case YellowQuantum:
1351 {
cristyb13e12a2012-01-06 21:48:27 +00001352 *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001353 break;
1354 }
1355 case AlphaQuantum:
1356 {
cristyb13e12a2012-01-06 21:48:27 +00001357 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001358 break;
1359 }
1360 case OpacityQuantum:
1361 {
cristyb13e12a2012-01-06 21:48:27 +00001362 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001363 break;
1364 }
1365 case BlackQuantum:
1366 {
1367 if (image->colorspace == CMYKColorspace)
cristyb13e12a2012-01-06 21:48:27 +00001368 *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
cristye5370942012-01-06 03:49:31 +00001369 break;
1370 }
1371 case IndexQuantum:
1372 {
cristyb13e12a2012-01-06 21:48:27 +00001373 *q=ScaleQuantumToLongLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001374 break;
1375 }
1376 default:
1377 break;
1378 }
1379 q++;
1380 }
1381 p+=GetPixelChannels(image);
1382 }
1383 }
1384}
1385
cristycafe0412012-01-10 13:29:58 +00001386static void ExportQuantumPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00001387 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1388 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001389{
1390 register const Quantum
1391 *restrict p;
1392
1393 register Quantum
cristy3fe11452012-01-09 01:27:42 +00001394 *restrict q;
cristye5370942012-01-06 03:49:31 +00001395
1396 register ssize_t
1397 x;
1398
cristy14d71292012-05-20 16:48:13 +00001399 size_t
1400 length;
1401
cristye5370942012-01-06 03:49:31 +00001402 ssize_t
1403 y;
1404
1405 q=(Quantum *) pixels;
1406 if (LocaleCompare(map,"BGR") == 0)
1407 {
cristycafe0412012-01-10 13:29:58 +00001408 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001409 {
cristycafe0412012-01-10 13:29:58 +00001410 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001411 if (p == (const Quantum *) NULL)
1412 break;
cristycafe0412012-01-10 13:29:58 +00001413 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001414 {
1415 *q++=GetPixelBlue(image,p);
1416 *q++=GetPixelGreen(image,p);
1417 *q++=GetPixelRed(image,p);
1418 p+=GetPixelChannels(image);
1419 }
1420 }
1421 return;
1422 }
1423 if (LocaleCompare(map,"BGRA") == 0)
1424 {
cristycafe0412012-01-10 13:29:58 +00001425 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001426 {
cristycafe0412012-01-10 13:29:58 +00001427 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001428 if (p == (const Quantum *) NULL)
1429 break;
cristycafe0412012-01-10 13:29:58 +00001430 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001431 {
1432 *q++=GetPixelBlue(image,p);
1433 *q++=GetPixelGreen(image,p);
1434 *q++=GetPixelRed(image,p);
1435 *q++=(Quantum) (GetPixelAlpha(image,p));
1436 p+=GetPixelChannels(image);
1437 }
1438 }
1439 return;
1440 }
1441 if (LocaleCompare(map,"BGRP") == 0)
1442 {
cristycafe0412012-01-10 13:29:58 +00001443 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001444 {
cristycafe0412012-01-10 13:29:58 +00001445 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001446 if (p == (const Quantum *) NULL)
1447 break;
cristycafe0412012-01-10 13:29:58 +00001448 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001449 {
1450 *q++=GetPixelBlue(image,p);
1451 *q++=GetPixelGreen(image,p);
1452 *q++=GetPixelRed(image,p);
1453 *q++=(Quantum) 0;
1454 p+=GetPixelChannels(image);
1455 }
1456 }
1457 return;
1458 }
1459 if (LocaleCompare(map,"I") == 0)
1460 {
cristycafe0412012-01-10 13:29:58 +00001461 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001462 {
cristycafe0412012-01-10 13:29:58 +00001463 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001464 if (p == (const Quantum *) NULL)
1465 break;
cristycafe0412012-01-10 13:29:58 +00001466 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001467 {
1468 *q++=GetPixelIntensity(image,p);
1469 p+=GetPixelChannels(image);
1470 }
1471 }
1472 return;
1473 }
1474 if (LocaleCompare(map,"RGB") == 0)
1475 {
cristycafe0412012-01-10 13:29:58 +00001476 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001477 {
cristycafe0412012-01-10 13:29:58 +00001478 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001479 if (p == (const Quantum *) NULL)
1480 break;
cristycafe0412012-01-10 13:29:58 +00001481 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001482 {
1483 *q++=GetPixelRed(image,p);
1484 *q++=GetPixelGreen(image,p);
1485 *q++=GetPixelBlue(image,p);
1486 p+=GetPixelChannels(image);
1487 }
1488 }
1489 return;
1490 }
1491 if (LocaleCompare(map,"RGBA") == 0)
1492 {
cristycafe0412012-01-10 13:29:58 +00001493 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001494 {
cristycafe0412012-01-10 13:29:58 +00001495 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001496 if (p == (const Quantum *) NULL)
1497 break;
cristycafe0412012-01-10 13:29:58 +00001498 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001499 {
1500 *q++=GetPixelRed(image,p);
1501 *q++=GetPixelGreen(image,p);
1502 *q++=GetPixelBlue(image,p);
1503 *q++=(Quantum) (GetPixelAlpha(image,p));
1504 p+=GetPixelChannels(image);
1505 }
1506 }
1507 return;
1508 }
1509 if (LocaleCompare(map,"RGBP") == 0)
1510 {
cristycafe0412012-01-10 13:29:58 +00001511 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001512 {
cristycafe0412012-01-10 13:29:58 +00001513 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001514 if (p == (const Quantum *) NULL)
1515 break;
cristycafe0412012-01-10 13:29:58 +00001516 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001517 {
1518 *q++=GetPixelRed(image,p);
1519 *q++=GetPixelGreen(image,p);
1520 *q++=GetPixelBlue(image,p);
1521 *q++=(Quantum) 0;
1522 p+=GetPixelChannels(image);
1523 }
1524 }
1525 return;
1526 }
cristy14d71292012-05-20 16:48:13 +00001527 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00001528 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001529 {
cristycafe0412012-01-10 13:29:58 +00001530 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001531 if (p == (const Quantum *) NULL)
1532 break;
cristycafe0412012-01-10 13:29:58 +00001533 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001534 {
1535 register ssize_t
1536 i;
1537
cristy14d71292012-05-20 16:48:13 +00001538 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00001539 {
1540 *q=(Quantum) 0;
1541 switch (quantum_map[i])
1542 {
1543 case RedQuantum:
1544 case CyanQuantum:
1545 {
1546 *q=GetPixelRed(image,p);
1547 break;
1548 }
1549 case GreenQuantum:
1550 case MagentaQuantum:
1551 {
1552 *q=GetPixelGreen(image,p);
1553 break;
1554 }
1555 case BlueQuantum:
1556 case YellowQuantum:
1557 {
1558 *q=GetPixelBlue(image,p);
1559 break;
1560 }
1561 case AlphaQuantum:
1562 {
1563 *q=GetPixelAlpha(image,p);
1564 break;
1565 }
1566 case OpacityQuantum:
1567 {
1568 *q=GetPixelAlpha(image,p);
1569 break;
1570 }
1571 case BlackQuantum:
1572 {
1573 if (image->colorspace == CMYKColorspace)
1574 *q=GetPixelBlack(image,p);
1575 break;
1576 }
1577 case IndexQuantum:
1578 {
1579 *q=(GetPixelIntensity(image,p));
1580 break;
1581 }
1582 default:
1583 {
1584 *q=(Quantum) 0;
1585 break;
1586 }
1587 }
1588 q++;
1589 }
1590 p+=GetPixelChannels(image);
1591 }
1592 }
1593}
1594
cristycafe0412012-01-10 13:29:58 +00001595static void ExportShortPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00001596 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1597 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001598{
1599 register const Quantum
1600 *restrict p;
1601
1602 register ssize_t
1603 x;
1604
cristye5370942012-01-06 03:49:31 +00001605 register unsigned short
cristy3fe11452012-01-09 01:27:42 +00001606 *restrict q;
cristye5370942012-01-06 03:49:31 +00001607
cristy14d71292012-05-20 16:48:13 +00001608 size_t
1609 length;
1610
1611 ssize_t
1612 y;
1613
cristye5370942012-01-06 03:49:31 +00001614 q=(unsigned short *) pixels;
1615 if (LocaleCompare(map,"BGR") == 0)
1616 {
cristycafe0412012-01-10 13:29:58 +00001617 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001618 {
cristycafe0412012-01-10 13:29:58 +00001619 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001620 if (p == (const Quantum *) NULL)
1621 break;
cristycafe0412012-01-10 13:29:58 +00001622 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001623 {
1624 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1625 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1626 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1627 p+=GetPixelChannels(image);
1628 }
1629 }
1630 return;
1631 }
1632 if (LocaleCompare(map,"BGRA") == 0)
1633 {
cristycafe0412012-01-10 13:29:58 +00001634 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001635 {
cristycafe0412012-01-10 13:29:58 +00001636 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001637 if (p == (const Quantum *) NULL)
1638 break;
cristycafe0412012-01-10 13:29:58 +00001639 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001640 {
1641 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1642 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1643 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1644 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1645 p+=GetPixelChannels(image);
1646 }
1647 }
1648 return;
1649 }
1650 if (LocaleCompare(map,"BGRP") == 0)
1651 {
cristycafe0412012-01-10 13:29:58 +00001652 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001653 {
cristycafe0412012-01-10 13:29:58 +00001654 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001655 if (p == (const Quantum *) NULL)
1656 break;
cristycafe0412012-01-10 13:29:58 +00001657 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001658 {
1659 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1660 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1661 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1662 *q++=0;
1663 p+=GetPixelChannels(image);
1664 }
1665 }
1666 return;
1667 }
1668 if (LocaleCompare(map,"I") == 0)
1669 {
cristycafe0412012-01-10 13:29:58 +00001670 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001671 {
cristycafe0412012-01-10 13:29:58 +00001672 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001673 if (p == (const Quantum *) NULL)
1674 break;
cristycafe0412012-01-10 13:29:58 +00001675 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001676 {
1677 *q++=ScaleQuantumToShort(GetPixelIntensity(image,p));
1678 p+=GetPixelChannels(image);
1679 }
1680 }
1681 return;
1682 }
1683 if (LocaleCompare(map,"RGB") == 0)
1684 {
cristycafe0412012-01-10 13:29:58 +00001685 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001686 {
cristycafe0412012-01-10 13:29:58 +00001687 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001688 if (p == (const Quantum *) NULL)
1689 break;
cristycafe0412012-01-10 13:29:58 +00001690 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001691 {
1692 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1693 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1694 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1695 p+=GetPixelChannels(image);
1696 }
1697 }
1698 return;
1699 }
1700 if (LocaleCompare(map,"RGBA") == 0)
1701 {
cristycafe0412012-01-10 13:29:58 +00001702 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001703 {
cristycafe0412012-01-10 13:29:58 +00001704 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001705 if (p == (const Quantum *) NULL)
1706 break;
cristycafe0412012-01-10 13:29:58 +00001707 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001708 {
1709 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1710 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1711 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1712 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1713 p+=GetPixelChannels(image);
1714 }
1715 }
1716 return;
1717 }
1718 if (LocaleCompare(map,"RGBP") == 0)
1719 {
cristycafe0412012-01-10 13:29:58 +00001720 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001721 {
cristycafe0412012-01-10 13:29:58 +00001722 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001723 if (p == (const Quantum *) NULL)
1724 break;
cristycafe0412012-01-10 13:29:58 +00001725 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001726 {
1727 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1728 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1729 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1730 *q++=0;
1731 p+=GetPixelChannels(image);
1732 }
1733 }
1734 return;
1735 }
cristy14d71292012-05-20 16:48:13 +00001736 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00001737 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001738 {
cristycafe0412012-01-10 13:29:58 +00001739 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001740 if (p == (const Quantum *) NULL)
1741 break;
cristycafe0412012-01-10 13:29:58 +00001742 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001743 {
1744 register ssize_t
1745 i;
1746
cristy14d71292012-05-20 16:48:13 +00001747 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00001748 {
1749 *q=0;
1750 switch (quantum_map[i])
1751 {
1752 case RedQuantum:
1753 case CyanQuantum:
1754 {
1755 *q=ScaleQuantumToShort(GetPixelRed(image,p));
1756 break;
1757 }
1758 case GreenQuantum:
1759 case MagentaQuantum:
1760 {
1761 *q=ScaleQuantumToShort(GetPixelGreen(image,p));
1762 break;
1763 }
1764 case BlueQuantum:
1765 case YellowQuantum:
1766 {
1767 *q=ScaleQuantumToShort(GetPixelBlue(image,p));
1768 break;
1769 }
1770 case AlphaQuantum:
1771 {
1772 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1773 break;
1774 }
1775 case OpacityQuantum:
1776 {
1777 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1778 break;
1779 }
1780 case BlackQuantum:
1781 {
1782 if (image->colorspace == CMYKColorspace)
1783 *q=ScaleQuantumToShort(GetPixelBlack(image,p));
1784 break;
1785 }
1786 case IndexQuantum:
1787 {
1788 *q=ScaleQuantumToShort(GetPixelIntensity(image,p));
1789 break;
1790 }
1791 default:
1792 break;
1793 }
1794 q++;
1795 }
1796 p+=GetPixelChannels(image);
1797 }
1798 }
1799}
1800
cristy4c08aed2011-07-01 19:47:50 +00001801MagickExport MagickBooleanType ExportImagePixels(const Image *image,
cristycafe0412012-01-10 13:29:58 +00001802 const ssize_t x,const ssize_t y,const size_t width,const size_t height,
1803 const char *map,const StorageType type,void *pixels,ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00001804{
1805 QuantumType
1806 *quantum_map;
1807
cristycafe0412012-01-10 13:29:58 +00001808 RectangleInfo
1809 roi;
1810
cristy4c08aed2011-07-01 19:47:50 +00001811 register ssize_t
cristye5370942012-01-06 03:49:31 +00001812 i;
cristy4c08aed2011-07-01 19:47:50 +00001813
cristy14d71292012-05-20 16:48:13 +00001814 size_t
1815 length;
1816
cristy4c08aed2011-07-01 19:47:50 +00001817 assert(image != (Image *) NULL);
1818 assert(image->signature == MagickSignature);
1819 if (image->debug != MagickFalse)
1820 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristy14d71292012-05-20 16:48:13 +00001821 length=strlen(map);
1822 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
cristy4c08aed2011-07-01 19:47:50 +00001823 if (quantum_map == (QuantumType *) NULL)
1824 {
1825 (void) ThrowMagickException(exception,GetMagickModule(),
anthonye5b39652012-04-21 05:37:29 +00001826 ResourceLimitError,"MemoryAllocationFailed","'%s'",image->filename);
cristy4c08aed2011-07-01 19:47:50 +00001827 return(MagickFalse);
1828 }
cristy14d71292012-05-20 16:48:13 +00001829 for (i=0; i < (ssize_t) length; i++)
cristy4c08aed2011-07-01 19:47:50 +00001830 {
1831 switch (map[i])
1832 {
1833 case 'A':
1834 case 'a':
1835 {
1836 quantum_map[i]=AlphaQuantum;
1837 break;
1838 }
1839 case 'B':
1840 case 'b':
1841 {
1842 quantum_map[i]=BlueQuantum;
1843 break;
1844 }
1845 case 'C':
1846 case 'c':
1847 {
1848 quantum_map[i]=CyanQuantum;
1849 if (image->colorspace == CMYKColorspace)
1850 break;
1851 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1852 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
anthonye5b39652012-04-21 05:37:29 +00001853 "ColorSeparatedImageRequired","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001854 return(MagickFalse);
1855 }
1856 case 'g':
1857 case 'G':
1858 {
1859 quantum_map[i]=GreenQuantum;
1860 break;
1861 }
1862 case 'I':
1863 case 'i':
1864 {
1865 quantum_map[i]=IndexQuantum;
1866 break;
1867 }
1868 case 'K':
1869 case 'k':
1870 {
1871 quantum_map[i]=BlackQuantum;
1872 if (image->colorspace == CMYKColorspace)
1873 break;
1874 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1875 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
anthonye5b39652012-04-21 05:37:29 +00001876 "ColorSeparatedImageRequired","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001877 return(MagickFalse);
1878 }
1879 case 'M':
1880 case 'm':
1881 {
1882 quantum_map[i]=MagentaQuantum;
1883 if (image->colorspace == CMYKColorspace)
1884 break;
1885 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1886 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
anthonye5b39652012-04-21 05:37:29 +00001887 "ColorSeparatedImageRequired","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001888 return(MagickFalse);
1889 }
1890 case 'o':
1891 case 'O':
1892 {
1893 quantum_map[i]=OpacityQuantum;
1894 break;
1895 }
1896 case 'P':
1897 case 'p':
1898 {
1899 quantum_map[i]=UndefinedQuantum;
1900 break;
1901 }
1902 case 'R':
1903 case 'r':
1904 {
1905 quantum_map[i]=RedQuantum;
1906 break;
1907 }
1908 case 'Y':
1909 case 'y':
1910 {
1911 quantum_map[i]=YellowQuantum;
1912 if (image->colorspace == CMYKColorspace)
1913 break;
1914 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1915 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
anthonye5b39652012-04-21 05:37:29 +00001916 "ColorSeparatedImageRequired","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001917 return(MagickFalse);
1918 }
1919 default:
1920 {
1921 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1922 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthonye5b39652012-04-21 05:37:29 +00001923 "UnrecognizedPixelMap","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001924 return(MagickFalse);
1925 }
1926 }
1927 }
cristycafe0412012-01-10 13:29:58 +00001928 roi.width=width;
1929 roi.height=height;
1930 roi.x=x;
1931 roi.y=y;
cristy4c08aed2011-07-01 19:47:50 +00001932 switch (type)
1933 {
1934 case CharPixel:
1935 {
cristycafe0412012-01-10 13:29:58 +00001936 ExportCharPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001937 break;
1938 }
1939 case DoublePixel:
1940 {
cristycafe0412012-01-10 13:29:58 +00001941 ExportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001942 break;
1943 }
1944 case FloatPixel:
1945 {
cristycafe0412012-01-10 13:29:58 +00001946 ExportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001947 break;
1948 }
cristy4c08aed2011-07-01 19:47:50 +00001949 case LongPixel:
1950 {
cristycafe0412012-01-10 13:29:58 +00001951 ExportLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001952 break;
1953 }
cristy6c9e1682012-01-07 21:37:44 +00001954 case LongLongPixel:
1955 {
cristycafe0412012-01-10 13:29:58 +00001956 ExportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy6c9e1682012-01-07 21:37:44 +00001957 break;
1958 }
cristy4c08aed2011-07-01 19:47:50 +00001959 case QuantumPixel:
1960 {
cristycafe0412012-01-10 13:29:58 +00001961 ExportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001962 break;
1963 }
1964 case ShortPixel:
1965 {
cristycafe0412012-01-10 13:29:58 +00001966 ExportShortPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001967 break;
1968 }
1969 default:
1970 {
1971 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1972 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthonye5b39652012-04-21 05:37:29 +00001973 "UnrecognizedPixelMap","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001974 break;
1975 }
1976 }
1977 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1978 return(MagickTrue);
1979}
1980
1981/*
1982%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1983% %
1984% %
1985% %
cristyaa8634f2011-10-01 13:25:12 +00001986% G e t P i x e l I n f o %
cristy4c08aed2011-07-01 19:47:50 +00001987% %
1988% %
1989% %
1990%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1991%
1992% GetPixelInfo() initializes the PixelInfo structure.
1993%
1994% The format of the GetPixelInfo method is:
1995%
1996% GetPixelInfo(const Image *image,PixelInfo *pixel)
1997%
1998% A description of each parameter follows:
1999%
2000% o image: the image.
2001%
cristy101ab702011-10-13 13:06:32 +00002002% o pixel: Specifies a pointer to a PixelInfo structure.
cristy4c08aed2011-07-01 19:47:50 +00002003%
2004*/
cristyaa8634f2011-10-01 13:25:12 +00002005MagickExport void GetPixelInfo(const Image *image,PixelInfo *pixel)
cristy4c08aed2011-07-01 19:47:50 +00002006{
2007 pixel->storage_class=DirectClass;
cristy7020ae62012-04-18 12:58:34 +00002008 pixel->colorspace=sRGBColorspace;
cristy4c08aed2011-07-01 19:47:50 +00002009 pixel->matte=MagickFalse;
2010 pixel->fuzz=0.0;
2011 pixel->depth=MAGICKCORE_QUANTUM_DEPTH;
2012 pixel->red=0.0;
2013 pixel->green=0.0;
2014 pixel->blue=0.0;
2015 pixel->black=0.0;
2016 pixel->alpha=(MagickRealType) OpaqueAlpha;
2017 pixel->index=0.0;
2018 if (image == (const Image *) NULL)
2019 return;
2020 pixel->storage_class=image->storage_class;
2021 pixel->colorspace=image->colorspace;
2022 pixel->matte=image->matte;
2023 pixel->depth=image->depth;
2024 pixel->fuzz=image->fuzz;
2025}
2026
2027/*
2028%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2029% %
2030% %
2031% %
2032% I m p o r t I m a g e P i x e l s %
2033% %
2034% %
2035% %
2036%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2037%
2038% ImportImagePixels() accepts pixel data and stores in the image at the
2039% location you specify. The method returns MagickTrue on success otherwise
2040% MagickFalse if an error is encountered. The pixel data can be either char,
cristyb5a45a32012-01-10 13:31:13 +00002041% Quantum, short int, unsigned int, unsigned long long, float, or double in
2042% the order specified by map.
cristy4c08aed2011-07-01 19:47:50 +00002043%
2044% Suppose your want to upload the first scanline of a 640x480 image from
2045% character data in red-green-blue order:
2046%
2047% ImportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels);
2048%
2049% The format of the ImportImagePixels method is:
2050%
cristycafe0412012-01-10 13:29:58 +00002051% MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
2052% const ssize_t y,const size_t width,const size_t height,
2053% const char *map,const StorageType type,const void *pixels,
2054% ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00002055%
2056% A description of each parameter follows:
2057%
2058% o image: the image.
2059%
cristycafe0412012-01-10 13:29:58 +00002060% o x,y,width,height: These values define the perimeter
cristy4c08aed2011-07-01 19:47:50 +00002061% of a region of pixels you want to define.
2062%
2063% o map: This string reflects the expected ordering of the pixel array.
2064% It can be any combination or order of R = red, G = green, B = blue,
2065% A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
2066% Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
2067% P = pad.
2068%
2069% o type: Define the data type of the pixels. Float and double types are
2070% normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
cristy6c9e1682012-01-07 21:37:44 +00002071% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
cristyff6834e2012-01-10 03:00:25 +00002072% LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
cristy6c9e1682012-01-07 21:37:44 +00002073% QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
cristy4c08aed2011-07-01 19:47:50 +00002074%
2075% o pixels: This array of values contain the pixel components as defined by
2076% map and type. You must preallocate this array where the expected
2077% length varies depending on the values of width, height, map, and type.
2078%
cristy018f07f2011-09-04 21:15:19 +00002079% o exception: return any errors or warnings in this structure.
2080%
cristy4c08aed2011-07-01 19:47:50 +00002081*/
cristye5370942012-01-06 03:49:31 +00002082
cristycafe0412012-01-10 13:29:58 +00002083static void ImportCharPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002084 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2085 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002086{
2087 register const unsigned char
2088 *restrict p;
2089
2090 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002091 *restrict q;
cristye5370942012-01-06 03:49:31 +00002092
2093 register ssize_t
2094 x;
2095
cristy14d71292012-05-20 16:48:13 +00002096 size_t
2097 length;
2098
cristye5370942012-01-06 03:49:31 +00002099 ssize_t
2100 y;
2101
2102 p=(const unsigned char *) pixels;
2103 if (LocaleCompare(map,"BGR") == 0)
2104 {
cristycafe0412012-01-10 13:29:58 +00002105 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002106 {
cristycafe0412012-01-10 13:29:58 +00002107 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002108 if (q == (Quantum *) NULL)
2109 break;
cristycafe0412012-01-10 13:29:58 +00002110 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002111 {
2112 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2113 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2114 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2115 q+=GetPixelChannels(image);
2116 }
2117 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2118 break;
2119 }
2120 return;
2121 }
2122 if (LocaleCompare(map,"BGRA") == 0)
2123 {
cristycafe0412012-01-10 13:29:58 +00002124 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002125 {
cristycafe0412012-01-10 13:29:58 +00002126 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002127 if (q == (Quantum *) NULL)
2128 break;
cristycafe0412012-01-10 13:29:58 +00002129 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002130 {
2131 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2132 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2133 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2134 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2135 q+=GetPixelChannels(image);
2136 }
2137 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2138 break;
2139 }
2140 return;
2141 }
2142 if (LocaleCompare(map,"BGRO") == 0)
2143 {
cristycafe0412012-01-10 13:29:58 +00002144 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002145 {
cristycafe0412012-01-10 13:29:58 +00002146 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002147 if (q == (Quantum *) NULL)
2148 break;
cristycafe0412012-01-10 13:29:58 +00002149 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002150 {
2151 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2152 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2153 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2154 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2155 q+=GetPixelChannels(image);
2156 }
2157 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2158 break;
2159 }
2160 return;
2161 }
2162 if (LocaleCompare(map,"BGRP") == 0)
2163 {
cristycafe0412012-01-10 13:29:58 +00002164 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002165 {
cristycafe0412012-01-10 13:29:58 +00002166 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002167 if (q == (Quantum *) NULL)
2168 break;
cristycafe0412012-01-10 13:29:58 +00002169 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002170 {
2171 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2172 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2173 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2174 p++;
2175 q+=GetPixelChannels(image);
2176 }
2177 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2178 break;
2179 }
2180 return;
2181 }
2182 if (LocaleCompare(map,"I") == 0)
2183 {
cristycafe0412012-01-10 13:29:58 +00002184 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002185 {
cristycafe0412012-01-10 13:29:58 +00002186 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002187 if (q == (Quantum *) NULL)
2188 break;
cristycafe0412012-01-10 13:29:58 +00002189 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002190 {
2191 SetPixelGray(image,ScaleCharToQuantum(*p++),q);
2192 q+=GetPixelChannels(image);
2193 }
2194 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2195 break;
2196 }
2197 return;
2198 }
2199 if (LocaleCompare(map,"RGB") == 0)
2200 {
cristycafe0412012-01-10 13:29:58 +00002201 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002202 {
cristycafe0412012-01-10 13:29:58 +00002203 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002204 if (q == (Quantum *) NULL)
2205 break;
cristycafe0412012-01-10 13:29:58 +00002206 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002207 {
2208 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2209 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2210 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2211 q+=GetPixelChannels(image);
2212 }
2213 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2214 break;
2215 }
2216 return;
2217 }
2218 if (LocaleCompare(map,"RGBA") == 0)
2219 {
cristycafe0412012-01-10 13:29:58 +00002220 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002221 {
cristycafe0412012-01-10 13:29:58 +00002222 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002223 if (q == (Quantum *) NULL)
2224 break;
cristycafe0412012-01-10 13:29:58 +00002225 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002226 {
2227 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2228 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2229 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2230 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2231 q+=GetPixelChannels(image);
2232 }
2233 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2234 break;
2235 }
2236 return;
2237 }
2238 if (LocaleCompare(map,"RGBO") == 0)
2239 {
cristycafe0412012-01-10 13:29:58 +00002240 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002241 {
cristycafe0412012-01-10 13:29:58 +00002242 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002243 if (q == (Quantum *) NULL)
2244 break;
cristycafe0412012-01-10 13:29:58 +00002245 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002246 {
2247 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2248 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2249 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2250 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2251 q+=GetPixelChannels(image);
2252 }
2253 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2254 break;
2255 }
2256 return;
2257 }
2258 if (LocaleCompare(map,"RGBP") == 0)
2259 {
cristycafe0412012-01-10 13:29:58 +00002260 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002261 {
cristycafe0412012-01-10 13:29:58 +00002262 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002263 if (q == (Quantum *) NULL)
2264 break;
cristycafe0412012-01-10 13:29:58 +00002265 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002266 {
2267 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2268 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2269 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2270 p++;
2271 q+=GetPixelChannels(image);
2272 }
2273 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2274 break;
2275 }
2276 return;
2277 }
cristy14d71292012-05-20 16:48:13 +00002278 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00002279 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002280 {
cristycafe0412012-01-10 13:29:58 +00002281 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002282 if (q == (Quantum *) NULL)
2283 break;
cristycafe0412012-01-10 13:29:58 +00002284 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002285 {
2286 register ssize_t
2287 i;
2288
cristy14d71292012-05-20 16:48:13 +00002289 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00002290 {
2291 switch (quantum_map[i])
2292 {
2293 case RedQuantum:
2294 case CyanQuantum:
2295 {
2296 SetPixelRed(image,ScaleCharToQuantum(*p),q);
2297 break;
2298 }
2299 case GreenQuantum:
2300 case MagentaQuantum:
2301 {
2302 SetPixelGreen(image,ScaleCharToQuantum(*p),q);
2303 break;
2304 }
2305 case BlueQuantum:
2306 case YellowQuantum:
2307 {
2308 SetPixelBlue(image,ScaleCharToQuantum(*p),q);
2309 break;
2310 }
2311 case AlphaQuantum:
2312 {
2313 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2314 break;
2315 }
2316 case OpacityQuantum:
2317 {
2318 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2319 break;
2320 }
2321 case BlackQuantum:
2322 {
2323 SetPixelBlack(image,ScaleCharToQuantum(*p),q);
2324 break;
2325 }
2326 case IndexQuantum:
2327 {
2328 SetPixelGray(image,ScaleCharToQuantum(*p),q);
2329 break;
2330 }
2331 default:
2332 break;
2333 }
2334 p++;
2335 }
2336 q+=GetPixelChannels(image);
2337 }
2338 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2339 break;
2340 }
2341}
2342
cristycafe0412012-01-10 13:29:58 +00002343static void ImportDoublePixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002344 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2345 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002346{
2347 register const double
2348 *restrict p;
2349
2350 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002351 *restrict q;
cristye5370942012-01-06 03:49:31 +00002352
2353 register ssize_t
2354 x;
2355
cristy14d71292012-05-20 16:48:13 +00002356 size_t
2357 length;
2358
cristye5370942012-01-06 03:49:31 +00002359 ssize_t
2360 y;
2361
2362 p=(const double *) pixels;
2363 if (LocaleCompare(map,"BGR") == 0)
2364 {
cristycafe0412012-01-10 13:29:58 +00002365 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002366 {
cristycafe0412012-01-10 13:29:58 +00002367 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002368 if (q == (Quantum *) NULL)
2369 break;
cristycafe0412012-01-10 13:29:58 +00002370 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002371 {
2372 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2373 (*p)),q);
2374 p++;
2375 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2376 (*p)),q);
2377 p++;
2378 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2379 (*p)),q);
2380 p++;
2381 q+=GetPixelChannels(image);
2382 }
2383 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2384 break;
2385 }
2386 return;
2387 }
2388 if (LocaleCompare(map,"BGRA") == 0)
2389 {
cristycafe0412012-01-10 13:29:58 +00002390 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002391 {
cristycafe0412012-01-10 13:29:58 +00002392 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002393 if (q == (Quantum *) NULL)
2394 break;
cristycafe0412012-01-10 13:29:58 +00002395 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002396 {
2397 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2398 (*p)),q);
2399 p++;
2400 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2401 (*p)),q);
2402 p++;
2403 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2404 (*p)),q);
2405 p++;
2406 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2407 (*p)),q);
2408 p++;
2409 q+=GetPixelChannels(image);
2410 }
2411 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2412 break;
2413 }
2414 return;
2415 }
2416 if (LocaleCompare(map,"BGRP") == 0)
2417 {
cristycafe0412012-01-10 13:29:58 +00002418 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002419 {
cristycafe0412012-01-10 13:29:58 +00002420 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002421 if (q == (Quantum *) NULL)
2422 break;
cristycafe0412012-01-10 13:29:58 +00002423 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002424 {
2425 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2426 (*p)),q);
2427 p++;
2428 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2429 (*p)),q);
2430 p++;
2431 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2432 (*p)),q);
2433 p++;
2434 p++;
2435 q+=GetPixelChannels(image);
2436 }
2437 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2438 break;
2439 }
2440 return;
2441 }
2442 if (LocaleCompare(map,"I") == 0)
2443 {
cristycafe0412012-01-10 13:29:58 +00002444 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002445 {
cristycafe0412012-01-10 13:29:58 +00002446 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002447 if (q == (Quantum *) NULL)
2448 break;
cristycafe0412012-01-10 13:29:58 +00002449 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002450 {
2451 SetPixelGray(image,ClampToQuantum((MagickRealType) QuantumRange*
2452 (*p)),q);
2453 p++;
2454 q+=GetPixelChannels(image);
2455 }
2456 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2457 break;
2458 }
2459 return;
2460 }
2461 if (LocaleCompare(map,"RGB") == 0)
2462 {
cristycafe0412012-01-10 13:29:58 +00002463 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002464 {
cristycafe0412012-01-10 13:29:58 +00002465 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002466 if (q == (Quantum *) NULL)
2467 break;
cristycafe0412012-01-10 13:29:58 +00002468 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002469 {
2470 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2471 (*p)),q);
2472 p++;
2473 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2474 (*p)),q);
2475 p++;
2476 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2477 (*p)),q);
2478 p++;
2479 q+=GetPixelChannels(image);
2480 }
2481 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2482 break;
2483 }
2484 return;
2485 }
2486 if (LocaleCompare(map,"RGBA") == 0)
2487 {
cristycafe0412012-01-10 13:29:58 +00002488 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002489 {
cristycafe0412012-01-10 13:29:58 +00002490 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002491 if (q == (Quantum *) NULL)
2492 break;
cristycafe0412012-01-10 13:29:58 +00002493 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002494 {
2495 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2496 (*p)),q);
2497 p++;
2498 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2499 (*p)),q);
2500 p++;
2501 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2502 (*p)),q);
2503 p++;
2504 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2505 (*p)),q);
2506 p++;
2507 q+=GetPixelChannels(image);
2508 }
2509 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2510 break;
2511 }
2512 return;
2513 }
2514 if (LocaleCompare(map,"RGBP") == 0)
2515 {
cristycafe0412012-01-10 13:29:58 +00002516 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002517 {
cristycafe0412012-01-10 13:29:58 +00002518 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002519 if (q == (Quantum *) NULL)
2520 break;
cristycafe0412012-01-10 13:29:58 +00002521 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002522 {
2523 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2524 (*p)),q);
2525 p++;
2526 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2527 (*p)),q);
2528 p++;
2529 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2530 (*p)),q);
2531 p++;
2532 q+=GetPixelChannels(image);
2533 }
2534 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2535 break;
2536 }
2537 return;
2538 }
cristy14d71292012-05-20 16:48:13 +00002539 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00002540 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002541 {
cristycafe0412012-01-10 13:29:58 +00002542 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002543 if (q == (Quantum *) NULL)
2544 break;
cristycafe0412012-01-10 13:29:58 +00002545 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002546 {
2547 register ssize_t
2548 i;
2549
cristy14d71292012-05-20 16:48:13 +00002550 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00002551 {
2552 switch (quantum_map[i])
2553 {
2554 case RedQuantum:
2555 case CyanQuantum:
2556 {
2557 SetPixelRed(image,ClampToQuantum((MagickRealType)
2558 QuantumRange*(*p)),q);
2559 break;
2560 }
2561 case GreenQuantum:
2562 case MagentaQuantum:
2563 {
2564 SetPixelGreen(image,ClampToQuantum((MagickRealType)
2565 QuantumRange*(*p)),q);
2566 break;
2567 }
2568 case BlueQuantum:
2569 case YellowQuantum:
2570 {
2571 SetPixelBlue(image,ClampToQuantum((MagickRealType)
2572 QuantumRange*(*p)),q);
2573 break;
2574 }
2575 case AlphaQuantum:
2576 {
2577 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2578 QuantumRange*(*p)),q);
2579 break;
2580 }
2581 case OpacityQuantum:
2582 {
2583 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2584 QuantumRange*(*p)),q);
2585 break;
2586 }
2587 case BlackQuantum:
2588 {
2589 SetPixelBlack(image,ClampToQuantum((MagickRealType)
2590 QuantumRange*(*p)),q);
2591 break;
2592 }
2593 case IndexQuantum:
2594 {
2595 SetPixelGray(image,ClampToQuantum((MagickRealType)
2596 QuantumRange*(*p)),q);
2597 break;
2598 }
2599 default:
2600 break;
2601 }
2602 p++;
2603 }
2604 q+=GetPixelChannels(image);
2605 }
2606 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2607 break;
2608 }
2609}
2610
cristycafe0412012-01-10 13:29:58 +00002611static void ImportFloatPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002612 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2613 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002614{
2615 register const float
2616 *restrict p;
2617
2618 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002619 *restrict q;
cristye5370942012-01-06 03:49:31 +00002620
2621 register ssize_t
2622 x;
2623
cristy14d71292012-05-20 16:48:13 +00002624 size_t
2625 length;
2626
cristye5370942012-01-06 03:49:31 +00002627 ssize_t
2628 y;
2629
2630 p=(const float *) pixels;
2631 if (LocaleCompare(map,"BGR") == 0)
2632 {
cristycafe0412012-01-10 13:29:58 +00002633 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002634 {
cristycafe0412012-01-10 13:29:58 +00002635 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002636 if (q == (Quantum *) NULL)
2637 break;
cristycafe0412012-01-10 13:29:58 +00002638 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002639 {
2640 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2641 (*p)),q);
2642 p++;
2643 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2644 (*p)),q);
2645 p++;
2646 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2647 (*p)),q);
2648 p++;
2649 q+=GetPixelChannels(image);
2650 }
2651 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2652 break;
2653 }
2654 return;
2655 }
2656 if (LocaleCompare(map,"BGRA") == 0)
2657 {
cristycafe0412012-01-10 13:29:58 +00002658 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002659 {
cristycafe0412012-01-10 13:29:58 +00002660 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002661 if (q == (Quantum *) NULL)
2662 break;
cristycafe0412012-01-10 13:29:58 +00002663 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002664 {
2665 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2666 (*p)),q);
2667 p++;
2668 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2669 (*p)),q);
2670 p++;
2671 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2672 (*p)),q);
2673 p++;
2674 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2675 (*p)),q);
2676 p++;
2677 q+=GetPixelChannels(image);
2678 }
2679 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2680 break;
2681 }
2682 return;
2683 }
2684 if (LocaleCompare(map,"BGRP") == 0)
2685 {
cristycafe0412012-01-10 13:29:58 +00002686 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002687 {
cristycafe0412012-01-10 13:29:58 +00002688 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002689 if (q == (Quantum *) NULL)
2690 break;
cristycafe0412012-01-10 13:29:58 +00002691 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002692 {
2693 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2694 (*p)),q);
2695 p++;
2696 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2697 (*p)),q);
2698 p++;
2699 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2700 (*p)),q);
2701 p++;
2702 p++;
2703 q+=GetPixelChannels(image);
2704 }
2705 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2706 break;
2707 }
2708 return;
2709 }
2710 if (LocaleCompare(map,"I") == 0)
2711 {
cristycafe0412012-01-10 13:29:58 +00002712 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002713 {
cristycafe0412012-01-10 13:29:58 +00002714 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002715 if (q == (Quantum *) NULL)
2716 break;
cristycafe0412012-01-10 13:29:58 +00002717 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002718 {
2719 SetPixelGray(image,ClampToQuantum((MagickRealType) QuantumRange*
2720 (*p)),q);
2721 p++;
2722 q+=GetPixelChannels(image);
2723 }
2724 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2725 break;
2726 }
2727 return;
2728 }
2729 if (LocaleCompare(map,"RGB") == 0)
2730 {
cristycafe0412012-01-10 13:29:58 +00002731 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002732 {
cristycafe0412012-01-10 13:29:58 +00002733 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002734 if (q == (Quantum *) NULL)
2735 break;
cristycafe0412012-01-10 13:29:58 +00002736 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002737 {
2738 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2739 (*p)),q);
2740 p++;
2741 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2742 (*p)),q);
2743 p++;
2744 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2745 (*p)),q);
2746 p++;
2747 q+=GetPixelChannels(image);
2748 }
2749 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2750 break;
2751 }
2752 return;
2753 }
2754 if (LocaleCompare(map,"RGBA") == 0)
2755 {
cristycafe0412012-01-10 13:29:58 +00002756 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002757 {
cristycafe0412012-01-10 13:29:58 +00002758 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002759 if (q == (Quantum *) NULL)
2760 break;
cristycafe0412012-01-10 13:29:58 +00002761 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002762 {
2763 SetPixelRed(image,ClampToQuantum((MagickRealType)
2764 QuantumRange*(*p)),q);
2765 p++;
2766 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2767 (*p)),q);
2768 p++;
2769 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2770 (*p)),q);
2771 p++;
2772 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2773 (*p)),q);
2774 p++;
2775 q+=GetPixelChannels(image);
2776 }
2777 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2778 break;
2779 }
2780 return;
2781 }
2782 if (LocaleCompare(map,"RGBP") == 0)
2783 {
cristycafe0412012-01-10 13:29:58 +00002784 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002785 {
cristycafe0412012-01-10 13:29:58 +00002786 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002787 if (q == (Quantum *) NULL)
2788 break;
cristycafe0412012-01-10 13:29:58 +00002789 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002790 {
2791 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2792 (*p)),q);
2793 p++;
2794 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2795 (*p)),q);
2796 p++;
2797 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2798 (*p)),q);
2799 p++;
2800 q+=GetPixelChannels(image);
2801 }
2802 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2803 break;
2804 }
2805 return;
2806 }
cristy14d71292012-05-20 16:48:13 +00002807 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00002808 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002809 {
cristycafe0412012-01-10 13:29:58 +00002810 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002811 if (q == (Quantum *) NULL)
2812 break;
cristycafe0412012-01-10 13:29:58 +00002813 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002814 {
2815 register ssize_t
2816 i;
2817
cristy14d71292012-05-20 16:48:13 +00002818 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00002819 {
2820 switch (quantum_map[i])
2821 {
2822 case RedQuantum:
2823 case CyanQuantum:
2824 {
2825 SetPixelRed(image,ClampToQuantum((MagickRealType)
2826 QuantumRange*(*p)),q);
2827 break;
2828 }
2829 case GreenQuantum:
2830 case MagentaQuantum:
2831 {
2832 SetPixelGreen(image,ClampToQuantum((MagickRealType)
2833 QuantumRange*(*p)),q);
2834 break;
2835 }
2836 case BlueQuantum:
2837 case YellowQuantum:
2838 {
2839 SetPixelBlue(image,ClampToQuantum((MagickRealType)
2840 QuantumRange*(*p)),q);
2841 break;
2842 }
2843 case AlphaQuantum:
2844 {
2845 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2846 QuantumRange*(*p)),q);
2847 break;
2848 }
2849 case OpacityQuantum:
2850 {
2851 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2852 QuantumRange*(*p)),q);
2853 break;
2854 }
2855 case BlackQuantum:
2856 {
2857 SetPixelBlack(image,ClampToQuantum((MagickRealType)
2858 QuantumRange*(*p)),q);
2859 break;
2860 }
2861 case IndexQuantum:
2862 {
2863 SetPixelGray(image,ClampToQuantum((MagickRealType)
2864 QuantumRange*(*p)),q);
2865 break;
2866 }
2867 default:
2868 break;
2869 }
2870 p++;
2871 }
2872 q+=GetPixelChannels(image);
2873 }
2874 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2875 break;
2876 }
2877}
2878
cristycafe0412012-01-10 13:29:58 +00002879static void ImportLongPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002880 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2881 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002882{
2883 register const unsigned int
2884 *restrict p;
2885
2886 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002887 *restrict q;
cristye5370942012-01-06 03:49:31 +00002888
2889 register ssize_t
2890 x;
2891
cristy14d71292012-05-20 16:48:13 +00002892 size_t
2893 length;
2894
cristye5370942012-01-06 03:49:31 +00002895 ssize_t
2896 y;
2897
2898 p=(const unsigned int *) pixels;
2899 if (LocaleCompare(map,"BGR") == 0)
2900 {
cristycafe0412012-01-10 13:29:58 +00002901 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002902 {
cristycafe0412012-01-10 13:29:58 +00002903 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002904 if (q == (Quantum *) NULL)
2905 break;
cristycafe0412012-01-10 13:29:58 +00002906 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002907 {
2908 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2909 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2910 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2911 q+=GetPixelChannels(image);
2912 }
2913 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2914 break;
2915 }
2916 return;
2917 }
2918 if (LocaleCompare(map,"BGRA") == 0)
2919 {
cristycafe0412012-01-10 13:29:58 +00002920 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002921 {
cristycafe0412012-01-10 13:29:58 +00002922 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002923 if (q == (Quantum *) NULL)
2924 break;
cristycafe0412012-01-10 13:29:58 +00002925 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002926 {
2927 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2928 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2929 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2930 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
2931 q+=GetPixelChannels(image);
2932 }
2933 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2934 break;
2935 }
2936 return;
2937 }
2938 if (LocaleCompare(map,"BGRP") == 0)
2939 {
cristycafe0412012-01-10 13:29:58 +00002940 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002941 {
cristycafe0412012-01-10 13:29:58 +00002942 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002943 if (q == (Quantum *) NULL)
2944 break;
cristycafe0412012-01-10 13:29:58 +00002945 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002946 {
2947 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2948 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2949 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2950 p++;
2951 q+=GetPixelChannels(image);
2952 }
2953 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2954 break;
2955 }
2956 return;
2957 }
2958 if (LocaleCompare(map,"I") == 0)
2959 {
cristycafe0412012-01-10 13:29:58 +00002960 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002961 {
cristycafe0412012-01-10 13:29:58 +00002962 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002963 if (q == (Quantum *) NULL)
2964 break;
cristycafe0412012-01-10 13:29:58 +00002965 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002966 {
2967 SetPixelGray(image,ScaleLongToQuantum(*p++),q);
2968 q+=GetPixelChannels(image);
2969 }
2970 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2971 break;
2972 }
2973 return;
2974 }
2975 if (LocaleCompare(map,"RGB") == 0)
2976 {
cristycafe0412012-01-10 13:29:58 +00002977 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002978 {
cristycafe0412012-01-10 13:29:58 +00002979 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002980 if (q == (Quantum *) NULL)
2981 break;
cristycafe0412012-01-10 13:29:58 +00002982 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002983 {
2984 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2985 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2986 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2987 q+=GetPixelChannels(image);
2988 }
2989 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2990 break;
2991 }
2992 return;
2993 }
2994 if (LocaleCompare(map,"RGBA") == 0)
2995 {
cristycafe0412012-01-10 13:29:58 +00002996 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002997 {
cristycafe0412012-01-10 13:29:58 +00002998 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002999 if (q == (Quantum *) NULL)
3000 break;
cristycafe0412012-01-10 13:29:58 +00003001 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003002 {
3003 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3004 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3005 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3006 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
3007 q+=GetPixelChannels(image);
3008 }
3009 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3010 break;
3011 }
3012 return;
3013 }
3014 if (LocaleCompare(map,"RGBP") == 0)
3015 {
cristycafe0412012-01-10 13:29:58 +00003016 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003017 {
cristycafe0412012-01-10 13:29:58 +00003018 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003019 if (q == (Quantum *) NULL)
3020 break;
cristycafe0412012-01-10 13:29:58 +00003021 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003022 {
3023 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3024 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3025 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3026 p++;
3027 q+=GetPixelChannels(image);
3028 }
3029 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3030 break;
3031 }
3032 return;
3033 }
cristy14d71292012-05-20 16:48:13 +00003034 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003035 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003036 {
cristycafe0412012-01-10 13:29:58 +00003037 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003038 if (q == (Quantum *) NULL)
3039 break;
cristycafe0412012-01-10 13:29:58 +00003040 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003041 {
3042 register ssize_t
3043 i;
3044
cristy14d71292012-05-20 16:48:13 +00003045 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003046 {
3047 switch (quantum_map[i])
3048 {
3049 case RedQuantum:
3050 case CyanQuantum:
3051 {
3052 SetPixelRed(image,ScaleLongToQuantum(*p),q);
3053 break;
3054 }
3055 case GreenQuantum:
3056 case MagentaQuantum:
3057 {
3058 SetPixelGreen(image,ScaleLongToQuantum(*p),q);
3059 break;
3060 }
3061 case BlueQuantum:
3062 case YellowQuantum:
3063 {
3064 SetPixelBlue(image,ScaleLongToQuantum(*p),q);
3065 break;
3066 }
3067 case AlphaQuantum:
3068 {
3069 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3070 break;
3071 }
3072 case OpacityQuantum:
3073 {
3074 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3075 break;
3076 }
3077 case BlackQuantum:
3078 {
3079 SetPixelBlack(image,ScaleLongToQuantum(*p),q);
3080 break;
3081 }
3082 case IndexQuantum:
3083 {
3084 SetPixelGray(image,ScaleLongToQuantum(*p),q);
3085 break;
3086 }
3087 default:
3088 break;
3089 }
3090 p++;
3091 }
3092 q+=GetPixelChannels(image);
3093 }
3094 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3095 break;
3096 }
3097}
3098
cristycafe0412012-01-10 13:29:58 +00003099static void ImportLongLongPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003100 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3101 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003102{
cristyb13e12a2012-01-06 21:48:27 +00003103 register const MagickSizeType
cristye5370942012-01-06 03:49:31 +00003104 *restrict p;
3105
3106 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003107 *restrict q;
cristye5370942012-01-06 03:49:31 +00003108
3109 register ssize_t
3110 x;
3111
cristy14d71292012-05-20 16:48:13 +00003112 size_t
3113 length;
3114
cristye5370942012-01-06 03:49:31 +00003115 ssize_t
3116 y;
3117
cristyb13e12a2012-01-06 21:48:27 +00003118 p=(const MagickSizeType *) pixels;
cristye5370942012-01-06 03:49:31 +00003119 if (LocaleCompare(map,"BGR") == 0)
3120 {
cristycafe0412012-01-10 13:29:58 +00003121 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003122 {
cristycafe0412012-01-10 13:29:58 +00003123 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003124 if (q == (Quantum *) NULL)
3125 break;
cristycafe0412012-01-10 13:29:58 +00003126 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003127 {
cristyb13e12a2012-01-06 21:48:27 +00003128 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3129 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3130 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003131 q+=GetPixelChannels(image);
3132 }
3133 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3134 break;
3135 }
3136 return;
3137 }
3138 if (LocaleCompare(map,"BGRA") == 0)
3139 {
cristycafe0412012-01-10 13:29:58 +00003140 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003141 {
cristycafe0412012-01-10 13:29:58 +00003142 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003143 if (q == (Quantum *) NULL)
3144 break;
cristycafe0412012-01-10 13:29:58 +00003145 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003146 {
cristyb13e12a2012-01-06 21:48:27 +00003147 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3148 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3149 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3150 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003151 q+=GetPixelChannels(image);
3152 }
3153 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3154 break;
3155 }
3156 return;
3157 }
3158 if (LocaleCompare(map,"BGRP") == 0)
3159 {
cristycafe0412012-01-10 13:29:58 +00003160 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003161 {
cristycafe0412012-01-10 13:29:58 +00003162 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003163 if (q == (Quantum *) NULL)
3164 break;
cristycafe0412012-01-10 13:29:58 +00003165 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003166 {
cristyb13e12a2012-01-06 21:48:27 +00003167 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3168 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3169 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003170 p++;
3171 q+=GetPixelChannels(image);
3172 }
3173 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3174 break;
3175 }
3176 return;
3177 }
3178 if (LocaleCompare(map,"I") == 0)
3179 {
cristycafe0412012-01-10 13:29:58 +00003180 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003181 {
cristycafe0412012-01-10 13:29:58 +00003182 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003183 if (q == (Quantum *) NULL)
3184 break;
cristycafe0412012-01-10 13:29:58 +00003185 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003186 {
cristyb13e12a2012-01-06 21:48:27 +00003187 SetPixelGray(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003188 q+=GetPixelChannels(image);
3189 }
3190 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3191 break;
3192 }
3193 return;
3194 }
3195 if (LocaleCompare(map,"RGB") == 0)
3196 {
cristycafe0412012-01-10 13:29:58 +00003197 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003198 {
cristycafe0412012-01-10 13:29:58 +00003199 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003200 if (q == (Quantum *) NULL)
3201 break;
cristycafe0412012-01-10 13:29:58 +00003202 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003203 {
cristyb13e12a2012-01-06 21:48:27 +00003204 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3205 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3206 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003207 q+=GetPixelChannels(image);
3208 }
3209 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3210 break;
3211 }
3212 return;
3213 }
3214 if (LocaleCompare(map,"RGBA") == 0)
3215 {
cristycafe0412012-01-10 13:29:58 +00003216 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003217 {
cristycafe0412012-01-10 13:29:58 +00003218 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003219 if (q == (Quantum *) NULL)
3220 break;
cristycafe0412012-01-10 13:29:58 +00003221 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003222 {
cristyb13e12a2012-01-06 21:48:27 +00003223 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3224 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3225 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3226 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003227 q+=GetPixelChannels(image);
3228 }
3229 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3230 break;
3231 }
3232 return;
3233 }
3234 if (LocaleCompare(map,"RGBP") == 0)
3235 {
cristycafe0412012-01-10 13:29:58 +00003236 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003237 {
cristycafe0412012-01-10 13:29:58 +00003238 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003239 if (q == (Quantum *) NULL)
3240 break;
cristycafe0412012-01-10 13:29:58 +00003241 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003242 {
cristyb13e12a2012-01-06 21:48:27 +00003243 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3244 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3245 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003246 p++;
3247 q+=GetPixelChannels(image);
3248 }
3249 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3250 break;
3251 }
3252 return;
3253 }
cristy14d71292012-05-20 16:48:13 +00003254 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003255 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003256 {
cristycafe0412012-01-10 13:29:58 +00003257 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003258 if (q == (Quantum *) NULL)
3259 break;
cristycafe0412012-01-10 13:29:58 +00003260 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003261 {
3262 register ssize_t
3263 i;
3264
cristy14d71292012-05-20 16:48:13 +00003265 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003266 {
3267 switch (quantum_map[i])
3268 {
3269 case RedQuantum:
3270 case CyanQuantum:
3271 {
cristyb13e12a2012-01-06 21:48:27 +00003272 SetPixelRed(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003273 break;
3274 }
3275 case GreenQuantum:
3276 case MagentaQuantum:
3277 {
cristyb13e12a2012-01-06 21:48:27 +00003278 SetPixelGreen(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003279 break;
3280 }
3281 case BlueQuantum:
3282 case YellowQuantum:
3283 {
cristyb13e12a2012-01-06 21:48:27 +00003284 SetPixelBlue(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003285 break;
3286 }
3287 case AlphaQuantum:
3288 {
cristyb13e12a2012-01-06 21:48:27 +00003289 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003290 break;
3291 }
3292 case OpacityQuantum:
3293 {
cristyb13e12a2012-01-06 21:48:27 +00003294 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003295 break;
3296 }
3297 case BlackQuantum:
3298 {
cristyb13e12a2012-01-06 21:48:27 +00003299 SetPixelBlack(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003300 break;
3301 }
3302 case IndexQuantum:
3303 {
cristyb13e12a2012-01-06 21:48:27 +00003304 SetPixelGray(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003305 break;
3306 }
3307 default:
3308 break;
3309 }
3310 p++;
3311 }
3312 q+=GetPixelChannels(image);
3313 }
3314 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3315 break;
3316 }
3317}
3318
cristycafe0412012-01-10 13:29:58 +00003319static void ImportQuantumPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003320 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3321 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003322{
3323 register const Quantum
3324 *restrict p;
3325
3326 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003327 *restrict q;
cristye5370942012-01-06 03:49:31 +00003328
3329 register ssize_t
3330 x;
3331
cristy14d71292012-05-20 16:48:13 +00003332 size_t
3333 length;
3334
cristye5370942012-01-06 03:49:31 +00003335 ssize_t
3336 y;
3337
3338 p=(const Quantum *) pixels;
3339 if (LocaleCompare(map,"BGR") == 0)
3340 {
cristycafe0412012-01-10 13:29:58 +00003341 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003342 {
cristycafe0412012-01-10 13:29:58 +00003343 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003344 if (q == (Quantum *) NULL)
3345 break;
cristycafe0412012-01-10 13:29:58 +00003346 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003347 {
3348 SetPixelBlue(image,*p++,q);
3349 SetPixelGreen(image,*p++,q);
3350 SetPixelRed(image,*p++,q);
3351 q+=GetPixelChannels(image);
3352 }
3353 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3354 break;
3355 }
3356 return;
3357 }
3358 if (LocaleCompare(map,"BGRA") == 0)
3359 {
cristycafe0412012-01-10 13:29:58 +00003360 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003361 {
cristycafe0412012-01-10 13:29:58 +00003362 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003363 if (q == (Quantum *) NULL)
3364 break;
cristycafe0412012-01-10 13:29:58 +00003365 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003366 {
3367 SetPixelBlue(image,*p++,q);
3368 SetPixelGreen(image,*p++,q);
3369 SetPixelRed(image,*p++,q);
3370 SetPixelAlpha(image,*p++,q);
3371 q+=GetPixelChannels(image);
3372 }
3373 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3374 break;
3375 }
3376 return;
3377 }
3378 if (LocaleCompare(map,"BGRP") == 0)
3379 {
cristycafe0412012-01-10 13:29:58 +00003380 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003381 {
cristycafe0412012-01-10 13:29:58 +00003382 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003383 if (q == (Quantum *) NULL)
3384 break;
cristycafe0412012-01-10 13:29:58 +00003385 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003386 {
3387 SetPixelBlue(image,*p++,q);
3388 SetPixelGreen(image,*p++,q);
3389 SetPixelRed(image,*p++,q);
3390 p++;
3391 q+=GetPixelChannels(image);
3392 }
3393 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3394 break;
3395 }
3396 return;
3397 }
3398 if (LocaleCompare(map,"I") == 0)
3399 {
cristycafe0412012-01-10 13:29:58 +00003400 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003401 {
cristycafe0412012-01-10 13:29:58 +00003402 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003403 if (q == (Quantum *) NULL)
3404 break;
cristycafe0412012-01-10 13:29:58 +00003405 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003406 {
3407 SetPixelGray(image,*p++,q);
3408 q+=GetPixelChannels(image);
3409 }
3410 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3411 break;
3412 }
3413 return;
3414 }
3415 if (LocaleCompare(map,"RGB") == 0)
3416 {
cristycafe0412012-01-10 13:29:58 +00003417 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003418 {
cristycafe0412012-01-10 13:29:58 +00003419 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003420 if (q == (Quantum *) NULL)
3421 break;
cristycafe0412012-01-10 13:29:58 +00003422 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003423 {
3424 SetPixelRed(image,*p++,q);
3425 SetPixelGreen(image,*p++,q);
3426 SetPixelBlue(image,*p++,q);
3427 q+=GetPixelChannels(image);
3428 }
3429 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3430 break;
3431 }
3432 return;
3433 }
3434 if (LocaleCompare(map,"RGBA") == 0)
3435 {
cristycafe0412012-01-10 13:29:58 +00003436 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003437 {
cristycafe0412012-01-10 13:29:58 +00003438 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003439 if (q == (Quantum *) NULL)
3440 break;
cristycafe0412012-01-10 13:29:58 +00003441 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003442 {
3443 SetPixelRed(image,*p++,q);
3444 SetPixelGreen(image,*p++,q);
3445 SetPixelBlue(image,*p++,q);
3446 SetPixelAlpha(image,*p++,q);
3447 q+=GetPixelChannels(image);
3448 }
3449 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3450 break;
3451 }
3452 return;
3453 }
3454 if (LocaleCompare(map,"RGBP") == 0)
3455 {
cristycafe0412012-01-10 13:29:58 +00003456 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003457 {
cristycafe0412012-01-10 13:29:58 +00003458 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003459 if (q == (Quantum *) NULL)
3460 break;
cristycafe0412012-01-10 13:29:58 +00003461 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003462 {
3463 SetPixelRed(image,*p++,q);
3464 SetPixelGreen(image,*p++,q);
3465 SetPixelBlue(image,*p++,q);
3466 p++;
3467 q+=GetPixelChannels(image);
3468 }
3469 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3470 break;
3471 }
3472 return;
3473 }
cristy14d71292012-05-20 16:48:13 +00003474 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003475 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003476 {
cristycafe0412012-01-10 13:29:58 +00003477 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003478 if (q == (Quantum *) NULL)
3479 break;
cristycafe0412012-01-10 13:29:58 +00003480 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003481 {
3482 register ssize_t
3483 i;
3484
cristy14d71292012-05-20 16:48:13 +00003485 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003486 {
3487 switch (quantum_map[i])
3488 {
3489 case RedQuantum:
3490 case CyanQuantum:
3491 {
3492 SetPixelRed(image,*p,q);
3493 break;
3494 }
3495 case GreenQuantum:
3496 case MagentaQuantum:
3497 {
3498 SetPixelGreen(image,*p,q);
3499 break;
3500 }
3501 case BlueQuantum:
3502 case YellowQuantum:
3503 {
3504 SetPixelBlue(image,*p,q);
3505 break;
3506 }
3507 case AlphaQuantum:
3508 {
3509 SetPixelAlpha(image,*p,q);
3510 break;
3511 }
3512 case OpacityQuantum:
3513 {
3514 SetPixelAlpha(image,*p,q);
3515 break;
3516 }
3517 case BlackQuantum:
3518 {
3519 SetPixelBlack(image,*p,q);
3520 break;
3521 }
3522 case IndexQuantum:
3523 {
3524 SetPixelGray(image,*p,q);
3525 break;
3526 }
3527 default:
3528 break;
3529 }
3530 p++;
3531 }
3532 q+=GetPixelChannels(image);
3533 }
3534 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3535 break;
3536 }
3537}
3538
cristycafe0412012-01-10 13:29:58 +00003539static void ImportShortPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003540 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3541 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003542{
3543 register const unsigned short
3544 *restrict p;
3545
3546 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003547 *restrict q;
cristye5370942012-01-06 03:49:31 +00003548
3549 register ssize_t
3550 x;
3551
cristy14d71292012-05-20 16:48:13 +00003552 size_t
3553 length;
3554
cristye5370942012-01-06 03:49:31 +00003555 ssize_t
3556 y;
3557
3558 p=(const unsigned short *) pixels;
3559 if (LocaleCompare(map,"BGR") == 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 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3569 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3570 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3571 q+=GetPixelChannels(image);
3572 }
3573 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3574 break;
3575 }
3576 return;
3577 }
3578 if (LocaleCompare(map,"BGRA") == 0)
3579 {
cristycafe0412012-01-10 13:29:58 +00003580 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003581 {
cristycafe0412012-01-10 13:29:58 +00003582 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003583 if (q == (Quantum *) NULL)
3584 break;
cristycafe0412012-01-10 13:29:58 +00003585 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003586 {
3587 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3588 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3589 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3590 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3591 q+=GetPixelChannels(image);
3592 }
3593 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3594 break;
3595 }
3596 return;
3597 }
3598 if (LocaleCompare(map,"BGRP") == 0)
3599 {
cristycafe0412012-01-10 13:29:58 +00003600 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003601 {
cristycafe0412012-01-10 13:29:58 +00003602 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003603 if (q == (Quantum *) NULL)
3604 break;
cristycafe0412012-01-10 13:29:58 +00003605 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003606 {
3607 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3608 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3609 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3610 p++;
3611 q+=GetPixelChannels(image);
3612 }
3613 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3614 break;
3615 }
3616 return;
3617 }
3618 if (LocaleCompare(map,"I") == 0)
3619 {
cristycafe0412012-01-10 13:29:58 +00003620 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003621 {
cristycafe0412012-01-10 13:29:58 +00003622 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003623 if (q == (Quantum *) NULL)
3624 break;
cristycafe0412012-01-10 13:29:58 +00003625 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003626 {
3627 SetPixelGray(image,ScaleShortToQuantum(*p++),q);
3628 q+=GetPixelChannels(image);
3629 }
3630 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3631 break;
3632 }
3633 return;
3634 }
3635 if (LocaleCompare(map,"RGB") == 0)
3636 {
cristycafe0412012-01-10 13:29:58 +00003637 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003638 {
cristycafe0412012-01-10 13:29:58 +00003639 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003640 if (q == (Quantum *) NULL)
3641 break;
cristycafe0412012-01-10 13:29:58 +00003642 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003643 {
3644 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3645 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3646 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3647 q+=GetPixelChannels(image);
3648 }
3649 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3650 break;
3651 }
3652 return;
3653 }
3654 if (LocaleCompare(map,"RGBA") == 0)
3655 {
cristycafe0412012-01-10 13:29:58 +00003656 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003657 {
cristycafe0412012-01-10 13:29:58 +00003658 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003659 if (q == (Quantum *) NULL)
3660 break;
cristycafe0412012-01-10 13:29:58 +00003661 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003662 {
3663 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3664 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3665 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3666 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3667 q+=GetPixelChannels(image);
3668 }
3669 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3670 break;
3671 }
3672 return;
3673 }
3674 if (LocaleCompare(map,"RGBP") == 0)
3675 {
cristycafe0412012-01-10 13:29:58 +00003676 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003677 {
cristycafe0412012-01-10 13:29:58 +00003678 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003679 if (q == (Quantum *) NULL)
3680 break;
cristycafe0412012-01-10 13:29:58 +00003681 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003682 {
3683 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3684 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3685 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3686 p++;
3687 q+=GetPixelChannels(image);
3688 }
3689 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3690 break;
3691 }
3692 return;
3693 }
cristy14d71292012-05-20 16:48:13 +00003694 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003695 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003696 {
cristycafe0412012-01-10 13:29:58 +00003697 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003698 if (q == (Quantum *) NULL)
3699 break;
cristycafe0412012-01-10 13:29:58 +00003700 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003701 {
3702 register ssize_t
3703 i;
3704
cristy14d71292012-05-20 16:48:13 +00003705 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003706 {
3707 switch (quantum_map[i])
3708 {
3709 case RedQuantum:
3710 case CyanQuantum:
3711 {
3712 SetPixelRed(image,ScaleShortToQuantum(*p),q);
3713 break;
3714 }
3715 case GreenQuantum:
3716 case MagentaQuantum:
3717 {
3718 SetPixelGreen(image,ScaleShortToQuantum(*p),q);
3719 break;
3720 }
3721 case BlueQuantum:
3722 case YellowQuantum:
3723 {
3724 SetPixelBlue(image,ScaleShortToQuantum(*p),q);
3725 break;
3726 }
3727 case AlphaQuantum:
3728 {
3729 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
3730 break;
3731 }
3732 case OpacityQuantum:
3733 {
3734 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
3735 break;
3736 }
3737 case BlackQuantum:
3738 {
3739 SetPixelBlack(image,ScaleShortToQuantum(*p),q);
3740 break;
3741 }
3742 case IndexQuantum:
3743 {
3744 SetPixelGray(image,ScaleShortToQuantum(*p),q);
3745 break;
3746 }
3747 default:
3748 break;
3749 }
3750 p++;
3751 }
3752 q+=GetPixelChannels(image);
3753 }
3754 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3755 break;
3756 }
3757}
3758
cristycafe0412012-01-10 13:29:58 +00003759MagickExport MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
3760 const ssize_t y,const size_t width,const size_t height,const char *map,
3761 const StorageType type,const void *pixels,ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00003762{
cristy4c08aed2011-07-01 19:47:50 +00003763 QuantumType
3764 *quantum_map;
3765
cristycafe0412012-01-10 13:29:58 +00003766 RectangleInfo
3767 roi;
3768
cristy4c08aed2011-07-01 19:47:50 +00003769 register ssize_t
cristye5370942012-01-06 03:49:31 +00003770 i;
cristy4c08aed2011-07-01 19:47:50 +00003771
cristy14d71292012-05-20 16:48:13 +00003772 size_t
3773 length;
3774
cristy4c08aed2011-07-01 19:47:50 +00003775 /*
3776 Allocate image structure.
3777 */
3778 assert(image != (Image *) NULL);
3779 assert(image->signature == MagickSignature);
3780 if (image->debug != MagickFalse)
3781 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristy14d71292012-05-20 16:48:13 +00003782 length=strlen(map);
3783 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
cristy4c08aed2011-07-01 19:47:50 +00003784 if (quantum_map == (QuantumType *) NULL)
3785 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
3786 image->filename);
cristy14d71292012-05-20 16:48:13 +00003787 for (i=0; i < (ssize_t) length; i++)
cristy4c08aed2011-07-01 19:47:50 +00003788 {
3789 switch (map[i])
3790 {
3791 case 'a':
3792 case 'A':
3793 {
3794 quantum_map[i]=AlphaQuantum;
3795 image->matte=MagickTrue;
3796 break;
3797 }
3798 case 'B':
3799 case 'b':
3800 {
3801 quantum_map[i]=BlueQuantum;
3802 break;
3803 }
3804 case 'C':
3805 case 'c':
3806 {
3807 quantum_map[i]=CyanQuantum;
cristy63240882011-08-05 19:05:27 +00003808 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003809 break;
3810 }
3811 case 'g':
3812 case 'G':
3813 {
3814 quantum_map[i]=GreenQuantum;
3815 break;
3816 }
3817 case 'K':
3818 case 'k':
3819 {
3820 quantum_map[i]=BlackQuantum;
cristy63240882011-08-05 19:05:27 +00003821 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003822 break;
3823 }
3824 case 'I':
3825 case 'i':
3826 {
3827 quantum_map[i]=IndexQuantum;
3828 break;
3829 }
3830 case 'm':
3831 case 'M':
3832 {
3833 quantum_map[i]=MagentaQuantum;
cristy63240882011-08-05 19:05:27 +00003834 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003835 break;
3836 }
3837 case 'O':
3838 case 'o':
3839 {
3840 quantum_map[i]=OpacityQuantum;
3841 image->matte=MagickTrue;
3842 break;
3843 }
3844 case 'P':
3845 case 'p':
3846 {
3847 quantum_map[i]=UndefinedQuantum;
3848 break;
3849 }
3850 case 'R':
3851 case 'r':
3852 {
3853 quantum_map[i]=RedQuantum;
3854 break;
3855 }
3856 case 'Y':
3857 case 'y':
3858 {
3859 quantum_map[i]=YellowQuantum;
cristy63240882011-08-05 19:05:27 +00003860 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003861 break;
3862 }
3863 default:
3864 {
3865 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
cristy63240882011-08-05 19:05:27 +00003866 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthonye5b39652012-04-21 05:37:29 +00003867 "UnrecognizedPixelMap","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00003868 return(MagickFalse);
3869 }
3870 }
3871 }
cristy63240882011-08-05 19:05:27 +00003872 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
cristy4c08aed2011-07-01 19:47:50 +00003873 return(MagickFalse);
3874 /*
cristye5370942012-01-06 03:49:31 +00003875 Transfer the pixels from the pixel data to the image.
cristy4c08aed2011-07-01 19:47:50 +00003876 */
cristycafe0412012-01-10 13:29:58 +00003877 roi.width=width;
3878 roi.height=height;
3879 roi.x=x;
3880 roi.y=y;
cristy4c08aed2011-07-01 19:47:50 +00003881 switch (type)
3882 {
3883 case CharPixel:
3884 {
cristycafe0412012-01-10 13:29:58 +00003885 ImportCharPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003886 break;
3887 }
3888 case DoublePixel:
3889 {
cristycafe0412012-01-10 13:29:58 +00003890 ImportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003891 break;
3892 }
3893 case FloatPixel:
3894 {
cristycafe0412012-01-10 13:29:58 +00003895 ImportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003896 break;
3897 }
cristy4c08aed2011-07-01 19:47:50 +00003898 case LongPixel:
3899 {
cristycafe0412012-01-10 13:29:58 +00003900 ImportLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003901 break;
3902 }
cristy6c9e1682012-01-07 21:37:44 +00003903 case LongLongPixel:
3904 {
cristycafe0412012-01-10 13:29:58 +00003905 ImportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy6c9e1682012-01-07 21:37:44 +00003906 break;
3907 }
cristy4c08aed2011-07-01 19:47:50 +00003908 case QuantumPixel:
3909 {
cristycafe0412012-01-10 13:29:58 +00003910 ImportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003911 break;
3912 }
3913 case ShortPixel:
3914 {
cristycafe0412012-01-10 13:29:58 +00003915 ImportShortPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003916 break;
3917 }
3918 default:
3919 {
3920 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
cristyc82a27b2011-10-21 01:07:16 +00003921 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthonye5b39652012-04-21 05:37:29 +00003922 "UnrecognizedPixelMap","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00003923 break;
3924 }
3925 }
3926 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
3927 return(MagickTrue);
3928}
3929
3930/*
3931%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3932% %
3933% %
3934% %
cristybd5a96c2011-08-21 00:04:26 +00003935+ 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 %
3936% %
3937% %
3938% %
3939%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3940%
3941% InitializePixelChannelMap() defines the standard pixel component map.
3942%
3943% The format of the InitializePixelChannelMap() method is:
3944%
3945% void InitializePixelChannelMap(Image *image)
3946%
3947% A description of each parameter follows:
3948%
3949% o image: the image.
3950%
3951*/
cristye2a912b2011-12-05 20:02:07 +00003952MagickExport void InitializePixelChannelMap(Image *image)
cristy77c30f52011-10-24 18:56:57 +00003953{
cristye2a912b2011-12-05 20:02:07 +00003954 PixelTrait
3955 trait;
3956
cristy77c30f52011-10-24 18:56:57 +00003957 register ssize_t
3958 i;
3959
cristyd26338f2011-12-14 02:39:30 +00003960 ssize_t
cristy77c30f52011-10-24 18:56:57 +00003961 n;
3962
3963 assert(image != (Image *) NULL);
3964 assert(image->signature == MagickSignature);
cristye2a912b2011-12-05 20:02:07 +00003965 (void) ResetMagickMemory(image->channel_map,0,MaxPixelChannels*
3966 sizeof(*image->channel_map));
3967 trait=UpdatePixelTrait;
3968 if (image->matte != MagickFalse)
cristy61f18ad2011-12-08 21:12:37 +00003969 trait=(PixelTrait) (trait | BlendPixelTrait);
cristy77c30f52011-10-24 18:56:57 +00003970 n=0;
cristyc06c5802011-12-31 23:36:16 +00003971 if (image->colorspace == GRAYColorspace)
cristy77c30f52011-10-24 18:56:57 +00003972 {
cristy3c316282011-12-15 15:43:24 +00003973 SetPixelChannelMap(image,BluePixelChannel,trait,n);
cristye2a912b2011-12-05 20:02:07 +00003974 SetPixelChannelMap(image,GreenPixelChannel,trait,n);
cristy3c316282011-12-15 15:43:24 +00003975 SetPixelChannelMap(image,RedPixelChannel,trait,n++);
3976 }
3977 else
3978 {
3979 SetPixelChannelMap(image,RedPixelChannel,trait,n++);
3980 SetPixelChannelMap(image,GreenPixelChannel,trait,n++);
cristye2a912b2011-12-05 20:02:07 +00003981 SetPixelChannelMap(image,BluePixelChannel,trait,n++);
cristy77c30f52011-10-24 18:56:57 +00003982 }
3983 if (image->colorspace == CMYKColorspace)
cristye2a912b2011-12-05 20:02:07 +00003984 SetPixelChannelMap(image,BlackPixelChannel,trait,n++);
cristy77c30f52011-10-24 18:56:57 +00003985 if (image->matte != MagickFalse)
cristye2a912b2011-12-05 20:02:07 +00003986 SetPixelChannelMap(image,AlphaPixelChannel,CopyPixelTrait,n++);
3987 if (image->storage_class == PseudoClass)
3988 SetPixelChannelMap(image,IndexPixelChannel,CopyPixelTrait,n++);
cristy183a5c72012-01-30 01:40:35 +00003989 if (image->mask != MagickFalse)
cristy10a6c612012-01-29 21:41:05 +00003990 SetPixelChannelMap(image,MaskPixelChannel,CopyPixelTrait,n++);
cristye2a912b2011-12-05 20:02:07 +00003991 assert((n+image->number_meta_channels) < MaxPixelChannels);
3992 for (i=0; i < (ssize_t) image->number_meta_channels; i++)
cristy61f18ad2011-12-08 21:12:37 +00003993 SetPixelChannelMap(image,(PixelChannel) (MetaPixelChannel+i),CopyPixelTrait,
cristye2a912b2011-12-05 20:02:07 +00003994 n++);
cristyd26338f2011-12-14 02:39:30 +00003995 image->number_channels=(size_t) n;
cristy77c30f52011-10-24 18:56:57 +00003996 if (image->debug != MagickFalse)
3997 LogPixelChannels(image);
3998 (void) SetPixelChannelMask(image,image->channel_mask);
3999}
cristybd5a96c2011-08-21 00:04:26 +00004000
4001/*
4002%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4003% %
4004% %
4005% %
cristya085a432011-07-30 01:39:32 +00004006% I n t e r p o l a t e P i x e l C h a n n e l %
4007% %
4008% %
4009% %
4010%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4011%
cristy884f6002011-07-31 00:51:45 +00004012% InterpolatePixelChannel() applies a pixel interpolation method between a
4013% floating point coordinate and the pixels surrounding that coordinate. No
4014% pixel area resampling, or scaling of the result is performed.
cristya085a432011-07-30 01:39:32 +00004015%
4016% The format of the InterpolatePixelChannel method is:
4017%
4018% MagickBooleanType InterpolatePixelChannel(const Image *image,
cristy444eda62011-08-10 02:07:46 +00004019% const CacheView *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00004020% const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00004021% double *pixel,ExceptionInfo *exception)
4022%
4023% A description of each parameter follows:
4024%
4025% o image: the image.
4026%
4027% o image_view: the image view.
4028%
4029% o channel: the pixel channel to interpolate.
4030%
4031% o method: the pixel color interpolation method.
4032%
4033% o x,y: A double representing the current (x,y) position of the pixel.
4034%
4035% o pixel: return the interpolated pixel here.
4036%
4037% o exception: return any errors or warnings in this structure.
4038%
4039*/
cristy94ea1632011-07-30 20:40:25 +00004040
cristy884f6002011-07-31 00:51:45 +00004041static inline double MagickMax(const MagickRealType x,const MagickRealType y)
4042{
4043 if (x > y)
4044 return(x);
4045 return(y);
4046}
4047
4048static inline MagickRealType CubicWeightingFunction(const MagickRealType x)
4049{
4050 MagickRealType
4051 alpha,
4052 gamma;
4053
4054 alpha=MagickMax(x+2.0,0.0);
4055 gamma=1.0*alpha*alpha*alpha;
4056 alpha=MagickMax(x+1.0,0.0);
4057 gamma-=4.0*alpha*alpha*alpha;
4058 alpha=MagickMax(x+0.0,0.0);
4059 gamma+=6.0*alpha*alpha*alpha;
4060 alpha=MagickMax(x-1.0,0.0);
4061 gamma-=4.0*alpha*alpha*alpha;
4062 return(gamma/6.0);
4063}
4064
cristy94ea1632011-07-30 20:40:25 +00004065static inline double MeshInterpolate(const PointInfo *delta,const double p,
4066 const double x,const double y)
4067{
4068 return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p);
4069}
4070
cristy884f6002011-07-31 00:51:45 +00004071static inline ssize_t NearestNeighbor(const MagickRealType x)
4072{
4073 if (x >= 0.0)
4074 return((ssize_t) (x+0.5));
4075 return((ssize_t) (x-0.5));
4076}
4077
cristya085a432011-07-30 01:39:32 +00004078MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
4079 const CacheView *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00004080 const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00004081 double *pixel,ExceptionInfo *exception)
4082{
4083 MagickBooleanType
4084 status;
4085
cristy94ea1632011-07-30 20:40:25 +00004086 MagickRealType
4087 alpha[16],
cristy884f6002011-07-31 00:51:45 +00004088 gamma,
4089 pixels[16];
cristy94ea1632011-07-30 20:40:25 +00004090
4091 PixelTrait
4092 traits;
4093
cristy94ea1632011-07-30 20:40:25 +00004094 register const Quantum
4095 *p;
4096
4097 register ssize_t
4098 i;
4099
cristya085a432011-07-30 01:39:32 +00004100 ssize_t
4101 x_offset,
4102 y_offset;
4103
4104 assert(image != (Image *) NULL);
4105 assert(image != (Image *) NULL);
4106 assert(image->signature == MagickSignature);
4107 assert(image_view != (CacheView *) NULL);
4108 status=MagickTrue;
cristy884f6002011-07-31 00:51:45 +00004109 *pixel=0.0;
cristy94ea1632011-07-30 20:40:25 +00004110 traits=GetPixelChannelMapTraits(image,channel);
cristya085a432011-07-30 01:39:32 +00004111 x_offset=(ssize_t) floor(x);
4112 y_offset=(ssize_t) floor(y);
4113 switch (method == UndefinedInterpolatePixel ? image->interpolate : method)
4114 {
cristy884f6002011-07-31 00:51:45 +00004115 case AverageInterpolatePixel:
4116 {
4117 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4118 exception);
4119 if (p == (const Quantum *) NULL)
4120 {
4121 status=MagickFalse;
4122 break;
4123 }
cristy222b19c2011-08-04 01:35:11 +00004124 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004125 for (i=0; i < 16; i++)
4126 {
4127 alpha[i]=1.0;
4128 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4129 }
4130 else
4131 for (i=0; i < 16; i++)
4132 {
4133 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4134 GetPixelChannels(image));
4135 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4136 }
4137 for (i=0; i < 16; i++)
4138 {
cristyc58380a2012-06-03 15:12:30 +00004139 gamma=MagickEpsilonReciprocal(alpha[i]);
cristy884f6002011-07-31 00:51:45 +00004140 *pixel+=gamma*0.0625*pixels[i];
4141 }
4142 break;
4143 }
4144 case BicubicInterpolatePixel:
4145 {
4146 MagickRealType
cristy380a11c2012-06-02 15:15:22 +00004147 beta[4],
4148 cx[4],
4149 cy[4];
cristy884f6002011-07-31 00:51:45 +00004150
4151 PointInfo
4152 delta;
4153
cristy380a11c2012-06-02 15:15:22 +00004154 /*
4155 Refactoring of the Catmull-Rom computation by Nicolas Robidoux with 55
4156 flops = 28* + 10- + 17+. Originally implemented for the VIPS (Virtual
4157 Image Processing System) library.
4158 */
cristy884f6002011-07-31 00:51:45 +00004159 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4160 exception);
4161 if (p == (const Quantum *) NULL)
4162 {
4163 status=MagickFalse;
4164 break;
4165 }
cristy222b19c2011-08-04 01:35:11 +00004166 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004167 for (i=0; i < 16; i++)
4168 {
4169 alpha[i]=1.0;
4170 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4171 }
4172 else
4173 for (i=0; i < 16; i++)
4174 {
4175 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4176 GetPixelChannels(image));
4177 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4178 }
4179 delta.x=x-x_offset;
4180 delta.y=y-y_offset;
cristy380a11c2012-06-02 15:15:22 +00004181 beta[0]=1.0-delta.x;
4182 beta[1]=(-0.5)*delta.x;
4183 beta[2]=beta[0]*beta[1];
4184 cx[0]=beta[0]*beta[2];
4185 cx[3]=delta.x*beta[2];
4186 beta[3]=cx[3]-cx[0];
4187 cx[1]=beta[0]-cx[0]+beta[3];
4188 cx[2]=delta.x-cx[3]-beta[3];
4189 beta[0]=1.0-delta.y;
4190 beta[1]=(-0.5)*delta.y;
4191 beta[2]=beta[0]*beta[1];
4192 cy[0]=beta[0]*beta[2];
4193 cy[3]=delta.y*beta[2];
4194 beta[3]=cy[3]-cy[0];
4195 cy[1]=beta[0]-cy[0]+beta[3];
4196 cy[2]=delta.y-cy[3]-beta[3];
4197 /*
4198 Interpolate pixel.
4199 */
4200 gamma=1.0;
4201 if (channel != AlphaPixelChannel)
cristyc58380a2012-06-03 15:12:30 +00004202 gamma=MagickEpsilonReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
cristy380a11c2012-06-02 15:15:22 +00004203 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+
4204 cx[2]*alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+
4205 cx[1]*alpha[9]+cx[2]*alpha[10]+cx[3]*alpha[11])+cy[3]*(
4206 cx[0]*alpha[12]+cx[1]*alpha[13]+cx[2]*alpha[14]+cx[3]*alpha[15]));
4207 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
4208 cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+
4209 cx[2]*pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+
4210 cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(
4211 cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15]));
cristy884f6002011-07-31 00:51:45 +00004212 break;
4213 }
4214 case BilinearInterpolatePixel:
cristy94ea1632011-07-30 20:40:25 +00004215 default:
cristya085a432011-07-30 01:39:32 +00004216 {
cristy94ea1632011-07-30 20:40:25 +00004217 PointInfo
4218 delta,
cristy884f6002011-07-31 00:51:45 +00004219 epsilon;
4220
4221 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4222 if (p == (const Quantum *) NULL)
4223 {
4224 status=MagickFalse;
4225 break;
4226 }
cristy222b19c2011-08-04 01:35:11 +00004227 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004228 for (i=0; i < 4; i++)
4229 {
4230 alpha[i]=1.0;
4231 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4232 }
4233 else
4234 for (i=0; i < 4; i++)
4235 {
4236 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4237 GetPixelChannels(image));
4238 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4239 }
4240 delta.x=x-x_offset;
4241 delta.y=y-y_offset;
4242 epsilon.x=1.0-delta.x;
4243 epsilon.y=1.0-delta.y;
4244 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4245 (epsilon.x*alpha[2]+delta.x*alpha[3])));
cristyc58380a2012-06-03 15:12:30 +00004246 gamma=MagickEpsilonReciprocal(gamma);
cristy884f6002011-07-31 00:51:45 +00004247 *pixel=gamma*(epsilon.y*(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*
4248 (epsilon.x*pixels[2]+delta.x*pixels[3]));
4249 break;
4250 }
4251 case FilterInterpolatePixel:
4252 {
4253 CacheView
4254 *filter_view;
4255
4256 Image
4257 *excerpt_image,
4258 *filter_image;
4259
4260 RectangleInfo
4261 geometry;
4262
4263 geometry.width=4L;
4264 geometry.height=4L;
4265 geometry.x=x_offset-1;
4266 geometry.y=y_offset-1;
4267 excerpt_image=ExcerptImage(image,&geometry,exception);
4268 if (excerpt_image == (Image *) NULL)
4269 {
4270 status=MagickFalse;
4271 break;
4272 }
cristyaa2c16c2012-03-25 22:21:35 +00004273 filter_image=ResizeImage(excerpt_image,1,1,image->filter,exception);
cristy884f6002011-07-31 00:51:45 +00004274 excerpt_image=DestroyImage(excerpt_image);
4275 if (filter_image == (Image *) NULL)
4276 break;
cristydb070952012-04-20 14:33:00 +00004277 filter_view=AcquireVirtualCacheView(filter_image,exception);
cristy884f6002011-07-31 00:51:45 +00004278 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4279 if (p == (const Quantum *) NULL)
4280 status=MagickFalse;
4281 else
cristy0beccfa2011-09-25 20:47:53 +00004282 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004283 filter_view=DestroyCacheView(filter_view);
4284 filter_image=DestroyImage(filter_image);
4285 break;
4286 }
4287 case IntegerInterpolatePixel:
4288 {
4289 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
4290 if (p == (const Quantum *) NULL)
4291 {
4292 status=MagickFalse;
4293 break;
4294 }
cristy0beccfa2011-09-25 20:47:53 +00004295 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004296 break;
4297 }
4298 case NearestNeighborInterpolatePixel:
4299 {
4300 p=GetCacheViewVirtualPixels(image_view,NearestNeighbor(x),
4301 NearestNeighbor(y),1,1,exception);
4302 if (p == (const Quantum *) NULL)
4303 {
4304 status=MagickFalse;
4305 break;
4306 }
cristy0beccfa2011-09-25 20:47:53 +00004307 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004308 break;
4309 }
4310 case MeshInterpolatePixel:
4311 {
4312 PointInfo
4313 delta,
cristy94ea1632011-07-30 20:40:25 +00004314 luminance;
4315
4316 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4317 if (p == (const Quantum *) NULL)
4318 {
4319 status=MagickFalse;
4320 break;
4321 }
cristy222b19c2011-08-04 01:35:11 +00004322 if ((traits & BlendPixelTrait) == 0)
cristy94ea1632011-07-30 20:40:25 +00004323 for (i=0; i < 4; i++)
4324 {
4325 alpha[i]=1.0;
cristy884f6002011-07-31 00:51:45 +00004326 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
cristy94ea1632011-07-30 20:40:25 +00004327 }
4328 else
4329 for (i=0; i < 4; i++)
4330 {
4331 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4332 GetPixelChannels(image));
4333 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4334 }
cristy884f6002011-07-31 00:51:45 +00004335 delta.x=x-x_offset;
4336 delta.y=y-y_offset;
4337 luminance.x=GetPixelLuminance(image,p)-(double)
4338 GetPixelLuminance(image,p+3*GetPixelChannels(image));
cristy28474bf2011-09-11 23:32:52 +00004339 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
cristy884f6002011-07-31 00:51:45 +00004340 GetPixelLuminance(image,p+2*GetPixelChannels(image));
cristy94ea1632011-07-30 20:40:25 +00004341 if (fabs(luminance.x) < fabs(luminance.y))
4342 {
4343 /*
4344 Diagonal 0-3 NW-SE.
4345 */
4346 if (delta.x <= delta.y)
4347 {
4348 /*
4349 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4350 */
4351 delta.y=1.0-delta.y;
4352 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
cristyc58380a2012-06-03 15:12:30 +00004353 gamma=MagickEpsilonReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004354 *pixel=gamma*MeshInterpolate(&delta,pixels[2],pixels[3],
4355 pixels[0]);
4356 }
4357 else
4358 {
4359 /*
4360 Top-right triangle (pixel: 1, diagonal: 0-3).
4361 */
4362 delta.x=1.0-delta.x;
4363 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
cristyc58380a2012-06-03 15:12:30 +00004364 gamma=MagickEpsilonReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004365 *pixel=gamma*MeshInterpolate(&delta,pixels[1],pixels[0],
4366 pixels[3]);
4367 }
4368 }
4369 else
4370 {
4371 /*
4372 Diagonal 1-2 NE-SW.
4373 */
4374 if (delta.x <= (1.0-delta.y))
4375 {
4376 /*
4377 Top-left triangle (pixel: 0, diagonal: 1-2).
4378 */
4379 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
cristyc58380a2012-06-03 15:12:30 +00004380 gamma=MagickEpsilonReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004381 *pixel=gamma*MeshInterpolate(&delta,pixels[0],pixels[1],
4382 pixels[2]);
4383 }
4384 else
4385 {
4386 /*
4387 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4388 */
4389 delta.x=1.0-delta.x;
4390 delta.y=1.0-delta.y;
4391 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
cristyc58380a2012-06-03 15:12:30 +00004392 gamma=MagickEpsilonReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004393 *pixel=gamma*MeshInterpolate(&delta,pixels[3],pixels[2],
4394 pixels[1]);
4395 }
4396 }
cristya085a432011-07-30 01:39:32 +00004397 break;
4398 }
cristy884f6002011-07-31 00:51:45 +00004399 case SplineInterpolatePixel:
4400 {
4401 MagickRealType
4402 dx,
4403 dy;
4404
4405 PointInfo
4406 delta;
4407
4408 ssize_t
4409 j,
4410 n;
4411
4412 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4413 exception);
4414 if (p == (const Quantum *) NULL)
4415 {
4416 status=MagickFalse;
4417 break;
4418 }
cristy222b19c2011-08-04 01:35:11 +00004419 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004420 for (i=0; i < 16; i++)
4421 {
4422 alpha[i]=1.0;
4423 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4424 }
4425 else
4426 for (i=0; i < 16; i++)
4427 {
4428 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4429 GetPixelChannels(image));
4430 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4431 }
4432 delta.x=x-x_offset;
4433 delta.y=y-y_offset;
4434 n=0;
4435 for (i=(-1); i < 3L; i++)
4436 {
4437 dy=CubicWeightingFunction((MagickRealType) i-delta.y);
4438 for (j=(-1); j < 3L; j++)
4439 {
4440 dx=CubicWeightingFunction(delta.x-(MagickRealType) j);
cristyc58380a2012-06-03 15:12:30 +00004441 gamma=MagickEpsilonReciprocal(alpha[n]);
cristy884f6002011-07-31 00:51:45 +00004442 *pixel+=gamma*dx*dy*pixels[n];
4443 n++;
4444 }
4445 }
4446 break;
4447 }
cristya085a432011-07-30 01:39:32 +00004448 }
4449 return(status);
4450}
4451
4452/*
4453%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4454% %
4455% %
4456% %
cristy5c4e2582011-09-11 19:21:03 +00004457% I n t e r p o l a t e P i x e l C h a n n e l s %
4458% %
4459% %
4460% %
4461%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4462%
4463% InterpolatePixelChannels() applies a pixel interpolation method between a
4464% floating point coordinate and the pixels surrounding that coordinate. No
4465% pixel area resampling, or scaling of the result is performed.
4466%
4467% The format of the InterpolatePixelChannels method is:
4468%
4469% MagickBooleanType InterpolatePixelChannels(const Image *source,
4470% const CacheView *source_view,const Image *destination,
4471% const PixelInterpolateMethod method,const double x,const double y,
4472% Quantum *pixel,ExceptionInfo *exception)
4473%
4474% A description of each parameter follows:
4475%
4476% o source: the source.
4477%
4478% o source_view: the source view.
4479%
4480% o destination: the destination image.
4481%
4482% o method: the pixel color interpolation method.
4483%
4484% o x,y: A double representing the current (x,y) position of the pixel.
4485%
4486% o pixel: return the interpolated pixel here.
4487%
4488% o exception: return any errors or warnings in this structure.
4489%
4490*/
4491MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
4492 const CacheView *source_view,const Image *destination,
4493 const PixelInterpolateMethod method,const double x,const double y,
4494 Quantum *pixel,ExceptionInfo *exception)
4495{
4496 MagickBooleanType
4497 status;
4498
4499 MagickRealType
4500 alpha[16],
4501 gamma,
4502 pixels[16];
4503
4504 PixelChannel
4505 channel;
4506
4507 PixelTrait
4508 destination_traits,
4509 traits;
4510
4511 register const Quantum
4512 *p;
4513
4514 register ssize_t
4515 i;
4516
4517 ssize_t
4518 x_offset,
4519 y_offset;
4520
4521 assert(source != (Image *) NULL);
4522 assert(source != (Image *) NULL);
4523 assert(source->signature == MagickSignature);
4524 assert(source_view != (CacheView *) NULL);
4525 status=MagickTrue;
4526 x_offset=(ssize_t) floor(x);
4527 y_offset=(ssize_t) floor(y);
4528 switch (method == UndefinedInterpolatePixel ? source->interpolate : method)
4529 {
4530 case AverageInterpolatePixel:
4531 {
4532 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4533 exception);
4534 if (p == (const Quantum *) NULL)
4535 {
4536 status=MagickFalse;
4537 break;
4538 }
4539 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4540 {
4541 double
4542 sum;
4543
4544 register ssize_t
4545 j;
4546
cristye2a912b2011-12-05 20:02:07 +00004547 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004548 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004549 destination_traits=GetPixelChannelMapTraits(destination,channel);
4550 if ((traits == UndefinedPixelTrait) ||
4551 (destination_traits == UndefinedPixelTrait))
4552 continue;
4553 for (j=0; j < 16; j++)
4554 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
cristy4a7ae692011-12-14 12:24:11 +00004555 sum=0.0;
cristy5c4e2582011-09-11 19:21:03 +00004556 if ((traits & BlendPixelTrait) == 0)
4557 {
4558 for (j=0; j < 16; j++)
cristy4a7ae692011-12-14 12:24:11 +00004559 sum+=0.0625*pixels[j];
4560 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004561 continue;
4562 }
cristy5c4e2582011-09-11 19:21:03 +00004563 for (j=0; j < 16; j++)
4564 {
4565 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4566 GetPixelChannels(source));
4567 pixels[j]*=alpha[j];
cristyc58380a2012-06-03 15:12:30 +00004568 gamma=MagickEpsilonReciprocal(alpha[j]);
cristy5c4e2582011-09-11 19:21:03 +00004569 sum+=gamma*0.0625*pixels[j];
4570 }
cristy4a7ae692011-12-14 12:24:11 +00004571 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004572 }
4573 break;
4574 }
4575 case BicubicInterpolatePixel:
4576 {
4577 MagickRealType
cristy380a11c2012-06-02 15:15:22 +00004578 beta[4],
4579 cx[4],
4580 cy[4];
cristy5c4e2582011-09-11 19:21:03 +00004581
4582 PointInfo
4583 delta;
4584
cristy380a11c2012-06-02 15:15:22 +00004585 /*
4586 Refactoring of the Catmull-Rom computation by Nicolas Robidoux with 55
4587 flops = 28* + 10- + 17+. Originally implemented for the VIPS (Virtual
4588 Image Processing System) library.
4589 */
cristy5c4e2582011-09-11 19:21:03 +00004590 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4591 exception);
4592 if (p == (const Quantum *) NULL)
4593 {
4594 status=MagickFalse;
4595 break;
4596 }
4597 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4598 {
4599 register ssize_t
4600 j;
4601
cristye2a912b2011-12-05 20:02:07 +00004602 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004603 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004604 destination_traits=GetPixelChannelMapTraits(destination,channel);
4605 if ((traits == UndefinedPixelTrait) ||
4606 (destination_traits == UndefinedPixelTrait))
4607 continue;
4608 if ((traits & BlendPixelTrait) == 0)
4609 for (j=0; j < 16; j++)
4610 {
4611 alpha[j]=1.0;
4612 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
4613 }
4614 else
4615 for (j=0; j < 16; j++)
4616 {
4617 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4618 GetPixelChannels(source));
4619 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
4620 }
4621 delta.x=x-x_offset;
4622 delta.y=y-y_offset;
cristy380a11c2012-06-02 15:15:22 +00004623 beta[0]=1.0-delta.x;
4624 beta[1]=(-0.5)*delta.x;
4625 beta[2]=beta[0]*beta[1];
4626 cx[0]=beta[0]*beta[2];
4627 cx[3]=delta.x*beta[2];
4628 beta[3]=cx[3]-cx[0];
4629 cx[1]=beta[0]-cx[0]+beta[3];
4630 cx[2]=delta.x-cx[3]-beta[3];
4631 beta[0]=1.0-delta.y;
4632 beta[1]=(-0.5)*delta.y;
4633 beta[2]=beta[0]*beta[1];
4634 cy[0]=beta[0]*beta[2];
4635 cy[3]=delta.y*beta[2];
4636 beta[3]=cy[3]-cy[0];
4637 cy[1]=beta[0]-cy[0]+beta[3];
4638 cy[2]=delta.y-cy[3]-beta[3];
4639 /*
4640 Interpolate pixel.
4641 */
4642 gamma=1.0;
4643 if ((traits & BlendPixelTrait) == 0)
cristyc58380a2012-06-03 15:12:30 +00004644 gamma=MagickEpsilonReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
cristy380a11c2012-06-02 15:15:22 +00004645 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+
4646 cx[2]*alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+
4647 cx[1]*alpha[9]+cx[2]*alpha[10]+cx[3]*alpha[11])+cy[3]*(
4648 cx[0]*alpha[12]+cx[1]*alpha[13]+cx[2]*alpha[14]+cx[3]*alpha[15]));
4649 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]*
4650 pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]*
4651 (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+
4652 cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*
4653 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*pixels[14]+
4654 cx[3]*pixels[15]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004655 }
4656 break;
4657 }
4658 case BilinearInterpolatePixel:
4659 default:
4660 {
4661 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4662 if (p == (const Quantum *) NULL)
4663 {
4664 status=MagickFalse;
4665 break;
4666 }
4667 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4668 {
4669 PointInfo
4670 delta,
4671 epsilon;
4672
cristye2a912b2011-12-05 20:02:07 +00004673 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004674 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004675 destination_traits=GetPixelChannelMapTraits(destination,channel);
4676 if ((traits == UndefinedPixelTrait) ||
4677 (destination_traits == UndefinedPixelTrait))
4678 continue;
4679 delta.x=x-x_offset;
4680 delta.y=y-y_offset;
4681 epsilon.x=1.0-delta.x;
4682 epsilon.y=1.0-delta.y;
cristy28474bf2011-09-11 23:32:52 +00004683 pixels[0]=(MagickRealType) p[i];
4684 pixels[1]=(MagickRealType) p[GetPixelChannels(source)+i];
cristy5c4e2582011-09-11 19:21:03 +00004685 pixels[2]=(MagickRealType) p[2*GetPixelChannels(source)+i];
4686 pixels[3]=(MagickRealType) p[3*GetPixelChannels(source)+i];
4687 if ((traits & BlendPixelTrait) == 0)
4688 {
4689 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
cristyc58380a2012-06-03 15:12:30 +00004690 gamma=MagickEpsilonReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00004691 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
4692 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*
4693 pixels[2]+delta.x*pixels[3]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004694 continue;
4695 }
cristy28474bf2011-09-11 23:32:52 +00004696 alpha[0]=QuantumScale*GetPixelAlpha(source,p);
4697 alpha[1]=QuantumScale*GetPixelAlpha(source,p+GetPixelChannels(source));
cristy5c4e2582011-09-11 19:21:03 +00004698 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
4699 GetPixelChannels(source));
4700 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
4701 GetPixelChannels(source));
4702 pixels[0]*=alpha[0];
4703 pixels[1]*=alpha[1];
4704 pixels[2]*=alpha[2];
4705 pixels[3]*=alpha[3];
4706 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4707 (epsilon.x*alpha[2]+delta.x*alpha[3])));
cristyc58380a2012-06-03 15:12:30 +00004708 gamma=MagickEpsilonReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00004709 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
4710 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*pixels[2]+
4711 delta.x*pixels[3]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004712 }
4713 break;
4714 }
4715 case FilterInterpolatePixel:
4716 {
4717 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4718 {
4719 CacheView
4720 *filter_view;
4721
4722 Image
4723 *excerpt_source,
4724 *filter_source;
4725
4726 RectangleInfo
4727 geometry;
4728
cristye2a912b2011-12-05 20:02:07 +00004729 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004730 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004731 destination_traits=GetPixelChannelMapTraits(destination,channel);
4732 if ((traits == UndefinedPixelTrait) ||
4733 (destination_traits == UndefinedPixelTrait))
4734 continue;
4735 geometry.width=4L;
4736 geometry.height=4L;
4737 geometry.x=x_offset-1;
4738 geometry.y=y_offset-1;
4739 excerpt_source=ExcerptImage(source,&geometry,exception);
4740 if (excerpt_source == (Image *) NULL)
4741 {
4742 status=MagickFalse;
4743 continue;
4744 }
cristyaa2c16c2012-03-25 22:21:35 +00004745 filter_source=ResizeImage(excerpt_source,1,1,source->filter,exception);
cristy5c4e2582011-09-11 19:21:03 +00004746 excerpt_source=DestroyImage(excerpt_source);
4747 if (filter_source == (Image *) NULL)
4748 continue;
cristydb070952012-04-20 14:33:00 +00004749 filter_view=AcquireVirtualCacheView(filter_source,exception);
cristy5c4e2582011-09-11 19:21:03 +00004750 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4751 if (p == (const Quantum *) NULL)
4752 status=MagickFalse;
4753 else
cristy1861c902011-12-14 02:30:00 +00004754 {
cristy4a7ae692011-12-14 12:24:11 +00004755 SetPixelChannel(destination,channel,p[i],pixel);
cristy1861c902011-12-14 02:30:00 +00004756 }
cristy5c4e2582011-09-11 19:21:03 +00004757 filter_view=DestroyCacheView(filter_view);
4758 filter_source=DestroyImage(filter_source);
4759 }
4760 break;
4761 }
4762 case IntegerInterpolatePixel:
4763 {
4764 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
4765 if (p == (const Quantum *) NULL)
4766 {
4767 status=MagickFalse;
4768 break;
4769 }
4770 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4771 {
cristye2a912b2011-12-05 20:02:07 +00004772 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004773 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004774 destination_traits=GetPixelChannelMapTraits(destination,channel);
4775 if ((traits == UndefinedPixelTrait) ||
4776 (destination_traits == UndefinedPixelTrait))
4777 continue;
cristy4a7ae692011-12-14 12:24:11 +00004778 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004779 }
4780 break;
4781 }
4782 case NearestNeighborInterpolatePixel:
4783 {
4784 p=GetCacheViewVirtualPixels(source_view,NearestNeighbor(x),
4785 NearestNeighbor(y),1,1,exception);
4786 if (p == (const Quantum *) NULL)
4787 {
4788 status=MagickFalse;
4789 break;
4790 }
4791 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4792 {
cristye2a912b2011-12-05 20:02:07 +00004793 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004794 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004795 destination_traits=GetPixelChannelMapTraits(destination,channel);
4796 if ((traits == UndefinedPixelTrait) ||
4797 (destination_traits == UndefinedPixelTrait))
4798 continue;
cristy4a7ae692011-12-14 12:24:11 +00004799 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004800 }
4801 break;
4802 }
4803 case MeshInterpolatePixel:
4804 {
4805 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4806 if (p == (const Quantum *) NULL)
4807 {
4808 status=MagickFalse;
4809 break;
4810 }
4811 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4812 {
4813 PointInfo
4814 delta,
4815 luminance;
4816
cristye2a912b2011-12-05 20:02:07 +00004817 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004818 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004819 destination_traits=GetPixelChannelMapTraits(destination,channel);
4820 if ((traits == UndefinedPixelTrait) ||
4821 (destination_traits == UndefinedPixelTrait))
4822 continue;
cristy1861c902011-12-14 02:30:00 +00004823 pixels[0]=(MagickRealType) p[i];
4824 pixels[1]=(MagickRealType) p[GetPixelChannels(source)+i];
4825 pixels[2]=(MagickRealType) p[2*GetPixelChannels(source)+i];
4826 pixels[3]=(MagickRealType) p[3*GetPixelChannels(source)+i];
4827 if ((traits & BlendPixelTrait) == 0)
4828 {
4829 alpha[0]=1.0;
4830 alpha[1]=1.0;
4831 alpha[2]=1.0;
4832 alpha[3]=1.0;
4833 }
4834 else
4835 {
4836 alpha[0]=QuantumScale*GetPixelAlpha(source,p);
4837 alpha[1]=QuantumScale*GetPixelAlpha(source,p+
4838 GetPixelChannels(source));
4839 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
4840 GetPixelChannels(source));
4841 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
4842 GetPixelChannels(source));
4843 }
4844 delta.x=x-x_offset;
4845 delta.y=y-y_offset;
4846 luminance.x=GetPixelLuminance(source,p)-(double)
4847 GetPixelLuminance(source,p+3*GetPixelChannels(source));
4848 luminance.y=GetPixelLuminance(source,p+GetPixelChannels(source))-
4849 (double) GetPixelLuminance(source,p+2*GetPixelChannels(source));
4850 if (fabs(luminance.x) < fabs(luminance.y))
4851 {
4852 /*
4853 Diagonal 0-3 NW-SE.
4854 */
4855 if (delta.x <= delta.y)
4856 {
4857 /*
4858 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4859 */
4860 delta.y=1.0-delta.y;
4861 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
cristyc58380a2012-06-03 15:12:30 +00004862 gamma=MagickEpsilonReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00004863 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4864 MeshInterpolate(&delta,pixels[2],pixels[3],pixels[0])),pixel);
cristy1861c902011-12-14 02:30:00 +00004865 }
4866 else
4867 {
4868 /*
4869 Top-right triangle (pixel: 1, diagonal: 0-3).
4870 */
4871 delta.x=1.0-delta.x;
4872 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
cristyc58380a2012-06-03 15:12:30 +00004873 gamma=MagickEpsilonReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00004874 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4875 MeshInterpolate(&delta,pixels[1],pixels[0],pixels[3])),pixel);
cristy1861c902011-12-14 02:30:00 +00004876 }
4877 }
4878 else
4879 {
4880 /*
4881 Diagonal 1-2 NE-SW.
4882 */
4883 if (delta.x <= (1.0-delta.y))
4884 {
4885 /*
4886 Top-left triangle (pixel: 0, diagonal: 1-2).
4887 */
4888 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
cristyc58380a2012-06-03 15:12:30 +00004889 gamma=MagickEpsilonReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00004890 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4891 MeshInterpolate(&delta,pixels[0],pixels[1],pixels[2])),pixel);
cristy1861c902011-12-14 02:30:00 +00004892 }
4893 else
4894 {
4895 /*
4896 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4897 */
4898 delta.x=1.0-delta.x;
4899 delta.y=1.0-delta.y;
4900 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
cristyc58380a2012-06-03 15:12:30 +00004901 gamma=MagickEpsilonReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00004902 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4903 MeshInterpolate(&delta,pixels[3],pixels[2],pixels[1])),pixel);
cristy1861c902011-12-14 02:30:00 +00004904 }
4905 }
cristy5c4e2582011-09-11 19:21:03 +00004906 }
4907 break;
4908 }
4909 case SplineInterpolatePixel:
4910 {
4911 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4912 exception);
4913 if (p == (const Quantum *) NULL)
4914 {
4915 status=MagickFalse;
4916 break;
4917 }
4918 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4919 {
4920 double
4921 sum;
4922
4923 MagickRealType
4924 dx,
4925 dy;
4926
4927 PointInfo
4928 delta;
4929
4930 register ssize_t
4931 j;
4932
4933 ssize_t
4934 k,
4935 n;
4936
cristye2a912b2011-12-05 20:02:07 +00004937 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004938 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004939 destination_traits=GetPixelChannelMapTraits(destination,channel);
4940 if ((traits == UndefinedPixelTrait) ||
4941 (destination_traits == UndefinedPixelTrait))
4942 continue;
4943 if ((traits & BlendPixelTrait) == 0)
4944 for (j=0; j < 16; j++)
4945 {
4946 alpha[j]=1.0;
4947 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
4948 }
4949 else
4950 for (j=0; j < 16; j++)
4951 {
4952 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4953 GetPixelChannels(source));
4954 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
4955 }
4956 delta.x=x-x_offset;
4957 delta.y=y-y_offset;
4958 sum=0.0;
4959 n=0;
4960 for (j=(-1); j < 3L; j++)
4961 {
4962 dy=CubicWeightingFunction((MagickRealType) j-delta.y);
4963 for (k=(-1); k < 3L; k++)
4964 {
4965 dx=CubicWeightingFunction(delta.x-(MagickRealType) k);
cristyc58380a2012-06-03 15:12:30 +00004966 gamma=MagickEpsilonReciprocal(alpha[n]);
cristy5c4e2582011-09-11 19:21:03 +00004967 sum+=gamma*dx*dy*pixels[n];
4968 n++;
4969 }
4970 }
cristy4a7ae692011-12-14 12:24:11 +00004971 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004972 }
4973 break;
4974 }
4975 }
4976 return(status);
4977}
4978
4979/*
4980%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4981% %
4982% %
4983% %
cristy9075cdb2011-07-30 01:06:23 +00004984% 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 +00004985% %
4986% %
4987% %
4988%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4989%
cristy884f6002011-07-31 00:51:45 +00004990% InterpolatePixelInfo() applies a pixel interpolation method between a
4991% floating point coordinate and the pixels surrounding that coordinate. No
4992% pixel area resampling, or scaling of the result is performed.
cristy4c08aed2011-07-01 19:47:50 +00004993%
4994% The format of the InterpolatePixelInfo method is:
4995%
4996% MagickBooleanType InterpolatePixelInfo(const Image *image,
cristy5c4e2582011-09-11 19:21:03 +00004997% const CacheView *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00004998% const double x,const double y,PixelInfo *pixel,
4999% ExceptionInfo *exception)
5000%
5001% A description of each parameter follows:
5002%
5003% o image: the image.
5004%
5005% o image_view: the image view.
5006%
5007% o method: the pixel color interpolation method.
5008%
5009% o x,y: A double representing the current (x,y) position of the pixel.
5010%
5011% o pixel: return the interpolated pixel here.
5012%
5013% o exception: return any errors or warnings in this structure.
5014%
5015*/
5016
5017static inline void AlphaBlendPixelInfo(const Image *image,
5018 const Quantum *pixel,PixelInfo *pixel_info,MagickRealType *alpha)
5019{
5020 if (image->matte == MagickFalse)
5021 {
5022 *alpha=1.0;
5023 pixel_info->red=(MagickRealType) GetPixelRed(image,pixel);
5024 pixel_info->green=(MagickRealType) GetPixelGreen(image,pixel);
5025 pixel_info->blue=(MagickRealType) GetPixelBlue(image,pixel);
5026 pixel_info->black=0.0;
5027 if (image->colorspace == CMYKColorspace)
5028 pixel_info->black=(MagickRealType) GetPixelBlack(image,pixel);
5029 pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
5030 return;
5031 }
5032 *alpha=QuantumScale*GetPixelAlpha(image,pixel);
5033 pixel_info->red=(*alpha*GetPixelRed(image,pixel));
5034 pixel_info->green=(*alpha*GetPixelGreen(image,pixel));
5035 pixel_info->blue=(*alpha*GetPixelBlue(image,pixel));
5036 pixel_info->black=0.0;
5037 if (image->colorspace == CMYKColorspace)
5038 pixel_info->black=(*alpha*GetPixelBlack(image,pixel));
5039 pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
5040}
5041
cristy4c08aed2011-07-01 19:47:50 +00005042MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
cristy5c4e2582011-09-11 19:21:03 +00005043 const CacheView *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00005044 const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception)
5045{
5046 MagickBooleanType
5047 status;
5048
cristy4c08aed2011-07-01 19:47:50 +00005049 MagickRealType
5050 alpha[16],
5051 gamma;
5052
cristy865d58d2011-07-09 00:44:52 +00005053 PixelInfo
5054 pixels[16];
5055
cristy4c08aed2011-07-01 19:47:50 +00005056 register const Quantum
5057 *p;
5058
5059 register ssize_t
5060 i;
5061
5062 ssize_t
5063 x_offset,
5064 y_offset;
5065
5066 assert(image != (Image *) NULL);
5067 assert(image->signature == MagickSignature);
5068 assert(image_view != (CacheView *) NULL);
5069 status=MagickTrue;
5070 x_offset=(ssize_t) floor(x);
5071 y_offset=(ssize_t) floor(y);
5072 switch (method == UndefinedInterpolatePixel ? image->interpolate : method)
5073 {
5074 case AverageInterpolatePixel:
5075 {
5076 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5077 exception);
5078 if (p == (const Quantum *) NULL)
5079 {
5080 status=MagickFalse;
5081 break;
5082 }
cristy5ce8df82011-07-07 14:52:23 +00005083 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005084 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005085 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5086 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5087 AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
5088 AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
5089 AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
5090 AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
5091 AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
5092 AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
5093 AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
cristy865d58d2011-07-09 00:44:52 +00005094 10);
cristyed231572011-07-14 02:18:59 +00005095 AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
cristy865d58d2011-07-09 00:44:52 +00005096 11);
cristyed231572011-07-14 02:18:59 +00005097 AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
cristy865d58d2011-07-09 00:44:52 +00005098 12);
cristyed231572011-07-14 02:18:59 +00005099 AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
cristy865d58d2011-07-09 00:44:52 +00005100 13);
cristyed231572011-07-14 02:18:59 +00005101 AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
cristy865d58d2011-07-09 00:44:52 +00005102 14);
cristyed231572011-07-14 02:18:59 +00005103 AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
cristy865d58d2011-07-09 00:44:52 +00005104 15);
cristy4c08aed2011-07-01 19:47:50 +00005105 pixel->red=0.0;
5106 pixel->green=0.0;
5107 pixel->blue=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005108 pixel->black=0.0;
cristy865d58d2011-07-09 00:44:52 +00005109 pixel->alpha=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005110 for (i=0; i < 16L; i++)
5111 {
cristyc58380a2012-06-03 15:12:30 +00005112 gamma=MagickEpsilonReciprocal(alpha[i]);
cristy4c08aed2011-07-01 19:47:50 +00005113 pixel->red+=gamma*0.0625*pixels[i].red;
5114 pixel->green+=gamma*0.0625*pixels[i].green;
5115 pixel->blue+=gamma*0.0625*pixels[i].blue;
cristy4c08aed2011-07-01 19:47:50 +00005116 if (image->colorspace == CMYKColorspace)
5117 pixel->black+=gamma*0.0625*pixels[i].black;
cristy865d58d2011-07-09 00:44:52 +00005118 pixel->alpha+=0.0625*pixels[i].alpha;
cristy4c08aed2011-07-01 19:47:50 +00005119 }
5120 break;
5121 }
5122 case BicubicInterpolatePixel:
5123 {
cristy380a11c2012-06-02 15:15:22 +00005124 MagickRealType
5125 beta[4],
5126 cx[4],
5127 cy[4];
cristy4c08aed2011-07-01 19:47:50 +00005128
5129 PointInfo
5130 delta;
5131
cristy380a11c2012-06-02 15:15:22 +00005132
5133 /*
5134 Refactoring of the Catmull-Rom computation by Nicolas Robidoux with 55
5135 flops = 28* + 10- + 17+. Originally implemented for the VIPS (Virtual
5136 Image Processing System) library.
5137 */
cristy4c08aed2011-07-01 19:47:50 +00005138 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5139 exception);
5140 if (p == (const Quantum *) NULL)
5141 {
5142 status=MagickFalse;
5143 break;
5144 }
cristy5ce8df82011-07-07 14:52:23 +00005145 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005146 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005147 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5148 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5149 AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
5150 AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
5151 AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
5152 AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
5153 AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
5154 AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
5155 AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
cristy865d58d2011-07-09 00:44:52 +00005156 10);
cristyed231572011-07-14 02:18:59 +00005157 AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
cristy865d58d2011-07-09 00:44:52 +00005158 11);
cristyed231572011-07-14 02:18:59 +00005159 AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
cristy865d58d2011-07-09 00:44:52 +00005160 12);
cristyed231572011-07-14 02:18:59 +00005161 AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
cristy865d58d2011-07-09 00:44:52 +00005162 13);
cristyed231572011-07-14 02:18:59 +00005163 AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
cristy865d58d2011-07-09 00:44:52 +00005164 14);
cristyed231572011-07-14 02:18:59 +00005165 AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
cristy865d58d2011-07-09 00:44:52 +00005166 15);
cristy4c08aed2011-07-01 19:47:50 +00005167 delta.x=x-x_offset;
5168 delta.y=y-y_offset;
cristy380a11c2012-06-02 15:15:22 +00005169 beta[0]=1.0-delta.x;
5170 beta[1]=(-0.5)*delta.x;
5171 beta[2]=beta[0]*beta[1];
5172 cx[0]=beta[0]*beta[2];
5173 cx[3]=delta.x*beta[2];
5174 beta[3]=cx[3]-cx[0];
5175 cx[1]=beta[0]-cx[0]+beta[3];
5176 cx[2]=delta.x-cx[3]-beta[3];
5177 beta[0]=1.0-delta.y;
5178 beta[1]=(-0.5)*delta.y;
5179 beta[2]=beta[0]*beta[1];
5180 cy[0]=beta[0]*beta[2];
5181 cy[3]=delta.y*beta[2];
5182 beta[3]=cy[3]-cy[0];
5183 cy[1]=beta[0]-cy[0]+beta[3];
5184 cy[2]=delta.y-cy[3]-beta[3];
5185 /*
5186 Interpolate pixel.
5187 */
5188 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*
5189 pixels[1].red+cx[2]*pixels[2].red+cx[3]*
5190 pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
5191 pixels[5].red+cx[2]*pixels[6].red+cx[3]*
5192 pixels[7].red)+cy[2]*(cx[0]*pixels[8].red+cx[1]*
5193 pixels[9].red+cx[2]*pixels[10].red+cx[3]*
5194 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*
5195 pixels[13].red+cx[2]*pixels[14].red+cx[3]*pixels[15].red));
5196 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*
5197 pixels[1].green+cx[2]*pixels[2].green+cx[3]*
5198 pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+cx[1]*
5199 pixels[5].green+cx[2]*pixels[6].green+cx[3]*
5200 pixels[7].green)+cy[2]*(cx[0]*pixels[8].green+cx[1]*
5201 pixels[9].green+cx[2]*pixels[10].green+cx[3]*
5202 pixels[11].green)+cy[3]*(cx[0]*pixels[12].green+cx[1]*
5203 pixels[13].green+cx[2]*pixels[14].green+cx[3]*pixels[15].green));
5204 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*
5205 pixels[1].blue+cx[2]*pixels[2].blue+cx[3]*
5206 pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]*
5207 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*
5208 pixels[7].blue)+cy[2]*(cx[0]*pixels[8].blue+cx[1]*
5209 pixels[9].blue+cx[2]*pixels[10].blue+cx[3]*
5210 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*
5211 pixels[13].blue+cx[2]*pixels[14].blue+cx[3]*pixels[15].blue));
5212 if (image->colorspace == CMYKColorspace)
5213 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*
5214 pixels[1].black+cx[2]*pixels[2].black+cx[3]*
5215 pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+cx[1]*
5216 pixels[5].black+cx[2]*pixels[6].black+cx[3]*
5217 pixels[7].black)+cy[2]*(cx[0]*pixels[8].black+cx[1]*
5218 pixels[9].black+cx[2]*pixels[10].black+cx[3]*
5219 pixels[11].black)+cy[3]*(cx[0]*pixels[12].black+cx[1]*
5220 pixels[13].black+cx[2]*pixels[14].black+cx[3]*pixels[15].black));
5221 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*
5222 pixels[1].alpha+cx[2]*pixels[2].alpha+cx[3]*
5223 pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+cx[1]*
5224 pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*
5225 pixels[7].alpha)+cy[2]*(cx[0]*pixels[8].alpha+cx[1]*
5226 pixels[9].alpha+cx[2]*pixels[10].alpha+cx[3]*
5227 pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+cx[1]*
5228 pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha));
cristy4c08aed2011-07-01 19:47:50 +00005229 break;
5230 }
5231 case BilinearInterpolatePixel:
5232 default:
5233 {
5234 PointInfo
5235 delta,
5236 epsilon;
5237
5238 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5239 if (p == (const Quantum *) NULL)
5240 {
5241 status=MagickFalse;
5242 break;
5243 }
cristy5ce8df82011-07-07 14:52:23 +00005244 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005245 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005246 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5247 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
cristy4c08aed2011-07-01 19:47:50 +00005248 delta.x=x-x_offset;
5249 delta.y=y-y_offset;
5250 epsilon.x=1.0-delta.x;
5251 epsilon.y=1.0-delta.y;
5252 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
5253 (epsilon.x*alpha[2]+delta.x*alpha[3])));
cristyc58380a2012-06-03 15:12:30 +00005254 gamma=MagickEpsilonReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005255 pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x*
5256 pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red));
5257 pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x*
5258 pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x*
5259 pixels[3].green));
5260 pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x*
5261 pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x*
5262 pixels[3].blue));
cristy4c08aed2011-07-01 19:47:50 +00005263 if (image->colorspace == CMYKColorspace)
5264 pixel->black=gamma*(epsilon.y*(epsilon.x*pixels[0].black+delta.x*
5265 pixels[1].black)+delta.y*(epsilon.x*pixels[2].black+delta.x*
5266 pixels[3].black));
cristy884f6002011-07-31 00:51:45 +00005267 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
cristyc58380a2012-06-03 15:12:30 +00005268 gamma=MagickEpsilonReciprocal(gamma);
cristy865d58d2011-07-09 00:44:52 +00005269 pixel->alpha=(epsilon.y*(epsilon.x*pixels[0].alpha+delta.x*
5270 pixels[1].alpha)+delta.y*(epsilon.x*pixels[2].alpha+delta.x*
5271 pixels[3].alpha));
cristy4c08aed2011-07-01 19:47:50 +00005272 break;
5273 }
5274 case FilterInterpolatePixel:
5275 {
5276 CacheView
5277 *filter_view;
5278
5279 Image
5280 *excerpt_image,
5281 *filter_image;
5282
5283 RectangleInfo
5284 geometry;
5285
5286 geometry.width=4L;
5287 geometry.height=4L;
5288 geometry.x=x_offset-1;
5289 geometry.y=y_offset-1;
5290 excerpt_image=ExcerptImage(image,&geometry,exception);
5291 if (excerpt_image == (Image *) NULL)
5292 {
5293 status=MagickFalse;
5294 break;
5295 }
cristyaa2c16c2012-03-25 22:21:35 +00005296 filter_image=ResizeImage(excerpt_image,1,1,image->filter,exception);
cristy4c08aed2011-07-01 19:47:50 +00005297 excerpt_image=DestroyImage(excerpt_image);
5298 if (filter_image == (Image *) NULL)
5299 break;
cristydb070952012-04-20 14:33:00 +00005300 filter_view=AcquireVirtualCacheView(filter_image,exception);
cristy4c08aed2011-07-01 19:47:50 +00005301 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
5302 if (p != (const Quantum *) NULL)
cristy803640d2011-11-17 02:11:32 +00005303 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005304 filter_view=DestroyCacheView(filter_view);
5305 filter_image=DestroyImage(filter_image);
5306 break;
5307 }
5308 case IntegerInterpolatePixel:
5309 {
5310 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
5311 if (p == (const Quantum *) NULL)
5312 {
5313 status=MagickFalse;
5314 break;
5315 }
cristy803640d2011-11-17 02:11:32 +00005316 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005317 break;
5318 }
5319 case MeshInterpolatePixel:
5320 {
5321 PointInfo
5322 delta,
5323 luminance;
5324
cristy94ea1632011-07-30 20:40:25 +00005325 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
cristy4c08aed2011-07-01 19:47:50 +00005326 if (p == (const Quantum *) NULL)
5327 {
5328 status=MagickFalse;
5329 break;
5330 }
cristy94ea1632011-07-30 20:40:25 +00005331 delta.x=x-x_offset;
5332 delta.y=y-y_offset;
cristy884f6002011-07-31 00:51:45 +00005333 luminance.x=GetPixelLuminance(image,p)-(double)
cristy94ea1632011-07-30 20:40:25 +00005334 GetPixelLuminance(image,p+3*GetPixelChannels(image));
cristy28474bf2011-09-11 23:32:52 +00005335 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
cristy94ea1632011-07-30 20:40:25 +00005336 GetPixelLuminance(image,p+2*GetPixelChannels(image));
cristy5ce8df82011-07-07 14:52:23 +00005337 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005338 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005339 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5340 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
cristy4c08aed2011-07-01 19:47:50 +00005341 if (fabs(luminance.x) < fabs(luminance.y))
5342 {
5343 /*
5344 Diagonal 0-3 NW-SE.
5345 */
5346 if (delta.x <= delta.y)
5347 {
5348 /*
cristy94ea1632011-07-30 20:40:25 +00005349 Bottom-left triangle (pixel: 2, diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005350 */
5351 delta.y=1.0-delta.y;
5352 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
cristyc58380a2012-06-03 15:12:30 +00005353 gamma=MagickEpsilonReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005354 pixel->red=gamma*MeshInterpolate(&delta,pixels[2].red,
5355 pixels[3].red,pixels[0].red);
5356 pixel->green=gamma*MeshInterpolate(&delta,pixels[2].green,
5357 pixels[3].green,pixels[0].green);
5358 pixel->blue=gamma*MeshInterpolate(&delta,pixels[2].blue,
5359 pixels[3].blue,pixels[0].blue);
cristy4c08aed2011-07-01 19:47:50 +00005360 if (image->colorspace == CMYKColorspace)
5361 pixel->black=gamma*MeshInterpolate(&delta,pixels[2].black,
5362 pixels[3].black,pixels[0].black);
cristy94ea1632011-07-30 20:40:25 +00005363 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005364 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[2].alpha,
5365 pixels[3].alpha,pixels[0].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005366 }
5367 else
5368 {
5369 /*
cristy94ea1632011-07-30 20:40:25 +00005370 Top-right triangle (pixel:1 , diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005371 */
5372 delta.x=1.0-delta.x;
5373 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
cristyc58380a2012-06-03 15:12:30 +00005374 gamma=MagickEpsilonReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005375 pixel->red=gamma*MeshInterpolate(&delta,pixels[1].red,
5376 pixels[0].red,pixels[3].red);
5377 pixel->green=gamma*MeshInterpolate(&delta,pixels[1].green,
5378 pixels[0].green,pixels[3].green);
5379 pixel->blue=gamma*MeshInterpolate(&delta,pixels[1].blue,
5380 pixels[0].blue,pixels[3].blue);
cristy4c08aed2011-07-01 19:47:50 +00005381 if (image->colorspace == CMYKColorspace)
5382 pixel->black=gamma*MeshInterpolate(&delta,pixels[1].black,
5383 pixels[0].black,pixels[3].black);
cristy94ea1632011-07-30 20:40:25 +00005384 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005385 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[1].alpha,
5386 pixels[0].alpha,pixels[3].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005387 }
5388 }
5389 else
5390 {
5391 /*
5392 Diagonal 1-2 NE-SW.
5393 */
5394 if (delta.x <= (1.0-delta.y))
5395 {
5396 /*
cristy94ea1632011-07-30 20:40:25 +00005397 Top-left triangle (pixel: 0, diagonal: 1-2).
cristy4c08aed2011-07-01 19:47:50 +00005398 */
5399 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
cristyc58380a2012-06-03 15:12:30 +00005400 gamma=MagickEpsilonReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005401 pixel->red=gamma*MeshInterpolate(&delta,pixels[0].red,
5402 pixels[1].red,pixels[2].red);
5403 pixel->green=gamma*MeshInterpolate(&delta,pixels[0].green,
5404 pixels[1].green,pixels[2].green);
5405 pixel->blue=gamma*MeshInterpolate(&delta,pixels[0].blue,
5406 pixels[1].blue,pixels[2].blue);
cristy4c08aed2011-07-01 19:47:50 +00005407 if (image->colorspace == CMYKColorspace)
5408 pixel->black=gamma*MeshInterpolate(&delta,pixels[0].black,
5409 pixels[1].black,pixels[2].black);
cristy94ea1632011-07-30 20:40:25 +00005410 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005411 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[0].alpha,
5412 pixels[1].alpha,pixels[2].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005413 }
5414 else
5415 {
5416 /*
5417 Bottom-right triangle (pixel: 3, diagonal: 1-2).
5418 */
5419 delta.x=1.0-delta.x;
5420 delta.y=1.0-delta.y;
5421 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
cristyc58380a2012-06-03 15:12:30 +00005422 gamma=MagickEpsilonReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005423 pixel->red=gamma*MeshInterpolate(&delta,pixels[3].red,
5424 pixels[2].red,pixels[1].red);
5425 pixel->green=gamma*MeshInterpolate(&delta,pixels[3].green,
5426 pixels[2].green,pixels[1].green);
5427 pixel->blue=gamma*MeshInterpolate(&delta,pixels[3].blue,
5428 pixels[2].blue,pixels[1].blue);
cristy4c08aed2011-07-01 19:47:50 +00005429 if (image->colorspace == CMYKColorspace)
5430 pixel->black=gamma*MeshInterpolate(&delta,pixels[3].black,
5431 pixels[2].black,pixels[1].black);
cristy94ea1632011-07-30 20:40:25 +00005432 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005433 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[3].alpha,
5434 pixels[2].alpha,pixels[1].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005435 }
5436 }
5437 break;
5438 }
5439 case NearestNeighborInterpolatePixel:
5440 {
5441 p=GetCacheViewVirtualPixels(image_view,NearestNeighbor(x),
5442 NearestNeighbor(y),1,1,exception);
5443 if (p == (const Quantum *) NULL)
5444 {
5445 status=MagickFalse;
5446 break;
5447 }
cristy803640d2011-11-17 02:11:32 +00005448 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005449 break;
5450 }
5451 case SplineInterpolatePixel:
5452 {
5453 MagickRealType
5454 dx,
5455 dy;
5456
5457 PointInfo
5458 delta;
5459
5460 ssize_t
5461 j,
5462 n;
5463
5464 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5465 exception);
5466 if (p == (const Quantum *) NULL)
5467 {
5468 status=MagickFalse;
5469 break;
5470 }
cristy5ce8df82011-07-07 14:52:23 +00005471 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005472 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005473 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5474 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5475 AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
5476 AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
5477 AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
5478 AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
5479 AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
5480 AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
5481 AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
cristy865d58d2011-07-09 00:44:52 +00005482 10);
cristyed231572011-07-14 02:18:59 +00005483 AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
cristy865d58d2011-07-09 00:44:52 +00005484 11);
cristyed231572011-07-14 02:18:59 +00005485 AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
cristy865d58d2011-07-09 00:44:52 +00005486 12);
cristyed231572011-07-14 02:18:59 +00005487 AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
cristy865d58d2011-07-09 00:44:52 +00005488 13);
cristyed231572011-07-14 02:18:59 +00005489 AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
cristy865d58d2011-07-09 00:44:52 +00005490 14);
cristyed231572011-07-14 02:18:59 +00005491 AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
cristy865d58d2011-07-09 00:44:52 +00005492 15);
cristy4c08aed2011-07-01 19:47:50 +00005493 pixel->red=0.0;
5494 pixel->green=0.0;
5495 pixel->blue=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005496 pixel->black=0.0;
cristy865d58d2011-07-09 00:44:52 +00005497 pixel->alpha=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005498 delta.x=x-x_offset;
5499 delta.y=y-y_offset;
5500 n=0;
5501 for (i=(-1); i < 3L; i++)
5502 {
5503 dy=CubicWeightingFunction((MagickRealType) i-delta.y);
5504 for (j=(-1); j < 3L; j++)
5505 {
5506 dx=CubicWeightingFunction(delta.x-(MagickRealType) j);
cristyc58380a2012-06-03 15:12:30 +00005507 gamma=MagickEpsilonReciprocal(alpha[n]);
cristy4c08aed2011-07-01 19:47:50 +00005508 pixel->red+=gamma*dx*dy*pixels[n].red;
5509 pixel->green+=gamma*dx*dy*pixels[n].green;
5510 pixel->blue+=gamma*dx*dy*pixels[n].blue;
5511 if (image->colorspace == CMYKColorspace)
5512 pixel->black+=gamma*dx*dy*pixels[n].black;
5513 pixel->alpha+=dx*dy*pixels[n].alpha;
5514 n++;
5515 }
5516 }
5517 break;
5518 }
5519 }
5520 return(status);
5521}
5522
5523/*
5524%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5525% %
5526% %
5527% %
5528+ I s F u z z y E q u i v a l e n c e P i x e l %
5529% %
5530% %
5531% %
5532%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5533%
5534% IsFuzzyEquivalencePixel() returns MagickTrue if the distance between two
5535% pixels is less than the specified distance in a linear three (or four)u
5536% dimensional color space.
5537%
5538% The format of the IsFuzzyEquivalencePixel method is:
5539%
cristye4a40472011-12-22 02:56:19 +00005540% void IsFuzzyEquivalencePixel(const Image *source,const Quantum *p,
5541% const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005542%
5543% A description of each parameter follows:
5544%
cristye4a40472011-12-22 02:56:19 +00005545% o source: the source image.
cristy4c08aed2011-07-01 19:47:50 +00005546%
5547% o p: Pixel p.
5548%
cristye4a40472011-12-22 02:56:19 +00005549% o destination: the destination image.
5550%
cristy4c08aed2011-07-01 19:47:50 +00005551% o q: Pixel q.
5552%
5553*/
cristye4a40472011-12-22 02:56:19 +00005554MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source,
5555 const Quantum *p,const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005556{
5557 MagickRealType
5558 fuzz,
5559 pixel;
5560
5561 register MagickRealType
5562 distance,
5563 scale;
5564
cristye4a40472011-12-22 02:56:19 +00005565 fuzz=MagickMax(source->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(
5566 destination->fuzz,(MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005567 scale=1.0;
5568 distance=0.0;
cristye4a40472011-12-22 02:56:19 +00005569 if (source->matte != MagickFalse)
cristy4c08aed2011-07-01 19:47:50 +00005570 {
5571 /*
5572 Transparencies are involved - set alpha distance
5573 */
cristy99abff32011-12-24 20:45:16 +00005574 pixel=GetPixelAlpha(source,p)-(MagickRealType)
5575 GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005576 distance=pixel*pixel;
5577 if (distance > fuzz)
5578 return(MagickFalse);
5579 /*
5580 Generate a alpha scaling factor to generate a 4D cone on colorspace
5581 Note that if one color is transparent, distance has no color component.
5582 */
cristye4a40472011-12-22 02:56:19 +00005583 scale=QuantumScale*GetPixelAlpha(source,p);
5584 scale*=QuantumScale*GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005585 if (scale <= MagickEpsilon)
5586 return(MagickTrue);
5587 }
5588 /*
5589 RGB or CMY color cube
5590 */
5591 distance*=3.0; /* rescale appropriately */
5592 fuzz*=3.0;
cristye4a40472011-12-22 02:56:19 +00005593 pixel=GetPixelRed(source,p)-(MagickRealType) GetPixelRed(destination,q);
5594 if ((source->colorspace == HSLColorspace) ||
5595 (source->colorspace == HSBColorspace) ||
5596 (source->colorspace == HWBColorspace))
cristy4c08aed2011-07-01 19:47:50 +00005597 {
5598 /*
5599 Compute an arc distance for hue. It should be a vector angle of
5600 'S'/'W' length with 'L'/'B' forming appropriate cones.
5601 */
5602 if (fabs((double) pixel) > (QuantumRange/2))
5603 pixel-=QuantumRange;
5604 pixel*=2;
5605 }
5606 distance+=scale*pixel*pixel;
5607 if (distance > fuzz)
5608 return(MagickFalse);
cristye4a40472011-12-22 02:56:19 +00005609 pixel=GetPixelGreen(source,p)-(MagickRealType) GetPixelGreen(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005610 distance+=scale*pixel*pixel;
5611 if (distance > fuzz)
5612 return(MagickFalse);
cristye4a40472011-12-22 02:56:19 +00005613 pixel=GetPixelBlue(source,p)-(MagickRealType) GetPixelBlue(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005614 distance+=scale*pixel*pixel;
5615 if (distance > fuzz)
5616 return(MagickFalse);
5617 return(MagickTrue);
5618}
5619
5620/*
5621%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5622% %
5623% %
5624% %
5625+ 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 %
5626% %
5627% %
5628% %
5629%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5630%
5631% IsFuzzyEquivalencePixelInfo() returns true if the distance between two
5632% colors is less than the specified distance in a linear three (or four)
5633% dimensional color space.
5634%
cristy5f95f4f2011-10-23 01:01:01 +00005635% This implements the equivalent of:
5636% fuzz < sqrt(color_distance^2 * u.a*v.a + alpha_distance^2)
cristy4c08aed2011-07-01 19:47:50 +00005637%
5638% Which produces a multi-dimensional cone for that colorspace along the
5639% transparency vector.
5640%
cristy5f95f4f2011-10-23 01:01:01 +00005641% For example for an RGB:
cristy4c08aed2011-07-01 19:47:50 +00005642% color_distance^2 = ( (u.r-v.r)^2 + (u.g-v.g)^2 + (u.b-v.b)^2 ) / 3
5643%
5644% See http://www.imagemagick.org/Usage/bugs/fuzz_distance/
5645%
5646% Hue colorspace distances need more work. Hue is not a distance, it is an
5647% angle!
5648%
5649% A check that q is in the same color space as p should be made and the
5650% appropriate mapping made. -- Anthony Thyssen 8 December 2010
5651%
5652% The format of the IsFuzzyEquivalencePixelInfo method is:
5653%
5654% MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5655% const PixelInfo *q)
5656%
5657% A description of each parameter follows:
5658%
5659% o p: Pixel p.
5660%
5661% o q: Pixel q.
5662%
5663*/
5664MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5665 const PixelInfo *q)
5666{
5667 MagickRealType
5668 fuzz,
5669 pixel;
5670
5671 register MagickRealType
5672 scale,
5673 distance;
5674
5675 if ((p->fuzz == 0.0) && (q->fuzz == 0.0))
5676 return(IsPixelInfoEquivalent(p,q));
5677 if (p->fuzz == 0.0)
cristy5f95f4f2011-10-23 01:01:01 +00005678 fuzz=MagickMax(q->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(q->fuzz,
5679 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005680 else if (q->fuzz == 0.0)
cristy5f95f4f2011-10-23 01:01:01 +00005681 fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(p->fuzz,
5682 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005683 else
cristy5f95f4f2011-10-23 01:01:01 +00005684 fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(q->fuzz,
5685 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005686 scale=1.0;
5687 distance=0.0;
5688 if ((p->matte != MagickFalse) || (q->matte != MagickFalse))
5689 {
5690 /*
5691 Transparencies are involved - set alpha distance.
5692 */
5693 pixel=(p->matte != MagickFalse ? p->alpha : OpaqueAlpha)-
5694 (q->matte != MagickFalse ? q->alpha : OpaqueAlpha);
5695 distance=pixel*pixel;
5696 if (distance > fuzz)
5697 return(MagickFalse);
5698 /*
5699 Generate a alpha scaling factor to generate a 4D cone on colorspace.
cristy5f95f4f2011-10-23 01:01:01 +00005700 If one color is transparent, distance has no color component.
cristy4c08aed2011-07-01 19:47:50 +00005701 */
5702 if (p->matte != MagickFalse)
5703 scale=(QuantumScale*p->alpha);
5704 if (q->matte != MagickFalse)
5705 scale*=(QuantumScale*q->alpha);
5706 if (scale <= MagickEpsilon )
5707 return(MagickTrue);
5708 }
5709 /*
5710 CMYK create a CMY cube with a multi-dimensional cone toward black.
5711 */
5712 if (p->colorspace == CMYKColorspace)
5713 {
5714 pixel=p->black-q->black;
5715 distance+=pixel*pixel*scale;
5716 if (distance > fuzz)
5717 return(MagickFalse);
5718 scale*=(MagickRealType) (QuantumScale*(QuantumRange-p->black));
5719 scale*=(MagickRealType) (QuantumScale*(QuantumRange-q->black));
5720 }
5721 /*
5722 RGB or CMY color cube.
5723 */
5724 distance*=3.0; /* rescale appropriately */
5725 fuzz*=3.0;
5726 pixel=p->red-q->red;
5727 if ((p->colorspace == HSLColorspace) || (p->colorspace == HSBColorspace) ||
5728 (p->colorspace == HWBColorspace))
5729 {
cristy5f95f4f2011-10-23 01:01:01 +00005730 /*
5731 This calculates a arc distance for hue-- it should be a vector angle
5732 of 'S'/'W' length with 'L'/'B' forming appropriate cones. In other
5733 words this is a hack - Anthony.
cristy4c08aed2011-07-01 19:47:50 +00005734 */
5735 if (fabs((double) pixel) > (QuantumRange/2))
5736 pixel-=QuantumRange;
5737 pixel*=2;
5738 }
5739 distance+=pixel*pixel*scale;
5740 if (distance > fuzz)
5741 return(MagickFalse);
5742 pixel=p->green-q->green;
5743 distance+=pixel*pixel*scale;
5744 if (distance > fuzz)
5745 return(MagickFalse);
5746 pixel=p->blue-q->blue;
5747 distance+=pixel*pixel*scale;
5748 if (distance > fuzz)
5749 return(MagickFalse);
5750 return(MagickTrue);
5751}
5752
5753/*
5754%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5755% %
5756% %
5757% %
cristye2a912b2011-12-05 20:02:07 +00005758% 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 +00005759% %
5760% %
5761% %
5762%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5763%
cristye2a912b2011-12-05 20:02:07 +00005764% SetPixelChannelMapMask() sets the pixel channel map from the specified
5765% channel mask.
cristy2b9582a2011-07-04 17:38:56 +00005766%
cristye2a912b2011-12-05 20:02:07 +00005767% The format of the SetPixelChannelMapMask method is:
cristy2b9582a2011-07-04 17:38:56 +00005768%
cristye2a912b2011-12-05 20:02:07 +00005769% void SetPixelChannelMapMask(Image *image,const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005770%
5771% A description of each parameter follows:
5772%
5773% o image: the image.
5774%
cristydfdb19e2012-03-21 22:22:24 +00005775% o channel_mask: the channel mask.
cristy2b9582a2011-07-04 17:38:56 +00005776%
5777*/
cristye2a912b2011-12-05 20:02:07 +00005778MagickExport void SetPixelChannelMapMask(Image *image,
cristy07a67852011-08-26 13:25:03 +00005779 const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005780{
cristy6a917d62011-08-24 17:31:30 +00005781#define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01)
cristydafd2872011-07-24 22:06:13 +00005782
cristy2b9582a2011-07-04 17:38:56 +00005783 register ssize_t
5784 i;
5785
cristy177e41c2012-04-15 15:08:25 +00005786 if (image->debug != MagickFalse)
5787 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%08x]", \
5788 image->filename,channel_mask); \
cristy3c309812011-11-08 02:40:43 +00005789 image->channel_mask=channel_mask;
cristydafd2872011-07-24 22:06:13 +00005790 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
cristye2a912b2011-12-05 20:02:07 +00005791 {
5792 PixelChannel
5793 channel;
5794
5795 channel=GetPixelChannelMapChannel(image,i);
5796 SetPixelChannelMapTraits(image,channel,
5797 GetChannelBit(channel_mask,channel) == 0 ? CopyPixelTrait :
cristy0bbd87c2011-12-13 19:34:45 +00005798 image->matte == MagickFalse || (channel == AlphaPixelChannel) ?
5799 UpdatePixelTrait : (PixelTrait) (UpdatePixelTrait | BlendPixelTrait));
cristye2a912b2011-12-05 20:02:07 +00005800 }
cristy1685e722011-09-06 00:04:19 +00005801 if (image->storage_class == PseudoClass)
5802 SetPixelChannelMapTraits(image,IndexPixelChannel,CopyPixelTrait);
cristy183a5c72012-01-30 01:40:35 +00005803 if (image->mask != MagickFalse)
cristy10a6c612012-01-29 21:41:05 +00005804 SetPixelChannelMapTraits(image,MaskPixelChannel,CopyPixelTrait);
cristy6dcb9b82011-10-23 23:21:25 +00005805 if (image->debug != MagickFalse)
5806 LogPixelChannels(image);
cristy2b9582a2011-07-04 17:38:56 +00005807}
5808
5809/*
5810%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5811% %
5812% %
5813% %
cristybd5a96c2011-08-21 00:04:26 +00005814% 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 +00005815% %
5816% %
5817% %
5818%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5819%
cristy5f95f4f2011-10-23 01:01:01 +00005820% SetPixelChannelMask() sets the pixel channel mask from the specified channel
5821% mask.
cristy2b9582a2011-07-04 17:38:56 +00005822%
cristybd5a96c2011-08-21 00:04:26 +00005823% The format of the SetPixelChannelMask method is:
cristy2b9582a2011-07-04 17:38:56 +00005824%
cristybd5a96c2011-08-21 00:04:26 +00005825% ChannelType SetPixelChannelMask(Image *image,
5826% const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005827%
5828% A description of each parameter follows:
5829%
5830% o image: the image.
5831%
cristybd5a96c2011-08-21 00:04:26 +00005832% o channel_mask: the channel mask.
5833%
cristy2b9582a2011-07-04 17:38:56 +00005834*/
cristybd5a96c2011-08-21 00:04:26 +00005835MagickExport ChannelType SetPixelChannelMask(Image *image,
5836 const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005837{
cristybd5a96c2011-08-21 00:04:26 +00005838 ChannelType
5839 mask;
cristy222b19c2011-08-04 01:35:11 +00005840
cristybd5a96c2011-08-21 00:04:26 +00005841 mask=image->channel_mask;
5842 image->channel_mask=channel_mask;
cristye2a912b2011-12-05 20:02:07 +00005843 SetPixelChannelMapMask(image,channel_mask);
cristybd5a96c2011-08-21 00:04:26 +00005844 return(mask);
cristy2b9582a2011-07-04 17:38:56 +00005845}
cristy322d07d2012-03-18 21:17:23 +00005846
5847/*
5848%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5849% %
5850% %
5851% %
5852% S e t P i x e l M e t a C h a n n e l s %
5853% %
5854% %
5855% %
5856%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5857%
5858% SetPixelMetaChannels() sets the image meta channels.
5859%
5860% The format of the SetPixelMetaChannels method is:
5861%
5862% MagickBooleanType SetPixelMetaChannels(Image *image,
5863% const size_t number_meta_channels,ExceptionInfo *exception)
5864%
5865% A description of each parameter follows:
5866%
5867% o image: the image.
5868%
5869% o number_meta_channels: the number of meta channels.
5870%
5871% o exception: return any errors or warnings in this structure.
5872%
5873*/
5874MagickExport MagickBooleanType SetPixelMetaChannels(Image *image,
5875 const size_t number_meta_channels,ExceptionInfo *exception)
5876{
5877 image->number_meta_channels=number_meta_channels;
5878 return(SyncImagePixelCache(image,exception));
5879}