blob: 82b5e098c4b334f45fa977ff9cd7f8bf5ed8a62b [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%
anthonycf4e33d2012-06-08 07:33:23 +00004016% Interpolation is restricted to just the specified channel.
4017%
cristya085a432011-07-30 01:39:32 +00004018% The format of the InterpolatePixelChannel method is:
4019%
4020% MagickBooleanType InterpolatePixelChannel(const Image *image,
cristy444eda62011-08-10 02:07:46 +00004021% const CacheView *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00004022% const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00004023% double *pixel,ExceptionInfo *exception)
4024%
4025% A description of each parameter follows:
4026%
4027% o image: the image.
4028%
4029% o image_view: the image view.
4030%
4031% o channel: the pixel channel to interpolate.
4032%
4033% o method: the pixel color interpolation method.
4034%
4035% o x,y: A double representing the current (x,y) position of the pixel.
4036%
4037% o pixel: return the interpolated pixel here.
4038%
4039% o exception: return any errors or warnings in this structure.
4040%
4041*/
cristy94ea1632011-07-30 20:40:25 +00004042
cristy884f6002011-07-31 00:51:45 +00004043static inline double MagickMax(const MagickRealType x,const MagickRealType y)
4044{
4045 if (x > y)
4046 return(x);
4047 return(y);
4048}
4049
nicolasd32d5e52012-06-12 15:34:10 +00004050static inline void CatromWeights(const MagickRealType x,
4051 MagickRealType (*weights)[4])
cristy884f6002011-07-31 00:51:45 +00004052{
nicolasd32d5e52012-06-12 15:34:10 +00004053 /*
4054 Nicolas Robidoux' 10 flops (4* + 5- + 1+) refactoring of the
4055 computation of the standard four 1D Catmull-Rom weights. The
4056 sampling location is assumed between the second and third input
4057 pixel locations, and x is the position relative to the second
4058 input pixel location. Formulas originally derived for the VIPS
4059 (Virtual Image Processing System) library.
4060 */
cristy884f6002011-07-31 00:51:45 +00004061 MagickRealType
4062 alpha,
nicolasd32d5e52012-06-12 15:34:10 +00004063 beta,
cristy884f6002011-07-31 00:51:45 +00004064 gamma;
4065
nicolasd32d5e52012-06-12 15:34:10 +00004066 alpha=(MagickRealType) 1.0-x;
4067 beta=(MagickRealType) (-0.5)*x*alpha;
4068 (*weights)[0]=alpha*beta;
4069 (*weights)[3]=x*beta;
4070 /*
4071 The following computation of the inner weights from the outer ones
4072 works for all Keys cubics.
4073 */
4074 gamma=(*weights)[3]-(*weights)[0];
4075 (*weights)[1]=alpha-(*weights)[0]+gamma;
4076 (*weights)[2]=x-(*weights)[3]-gamma;
4077}
4078
4079static inline void SplineWeights(const MagickRealType x,
4080 MagickRealType (*weights)[4])
4081{
4082 /*
4083 Nicolas Robidoux' 12 flops (6* + 5- + 1+) refactoring of the
4084 computation of the standard four 1D cubic B-spline smoothing
4085 weights. The sampling location is assumed between the second and
4086 third input pixel locations, and x is the position relative to the
4087 second input pixel location.
4088 */
4089 MagickRealType
4090 alpha,
4091 beta;
4092
4093 alpha=(MagickRealType) 1.0-x;
4094 (*weights)[3]=(MagickRealType) (1.0/6.0)*x*x*x;
4095 (*weights)[0]=(MagickRealType) (1.0/6.0)*alpha*alpha*alpha;
4096 beta=(*weights)[3]-(*weights)[0];
4097 (*weights)[1]=alpha-(*weights)[0]+beta;
4098 (*weights)[2]=x-(*weights)[3]-beta;
cristy884f6002011-07-31 00:51:45 +00004099}
4100
cristy94ea1632011-07-30 20:40:25 +00004101static inline double MeshInterpolate(const PointInfo *delta,const double p,
4102 const double x,const double y)
4103{
4104 return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p);
4105}
4106
anthonycf4e33d2012-06-08 07:33:23 +00004107/*
cristy884f6002011-07-31 00:51:45 +00004108static inline ssize_t NearestNeighbor(const MagickRealType x)
4109{
4110 if (x >= 0.0)
4111 return((ssize_t) (x+0.5));
4112 return((ssize_t) (x-0.5));
4113}
anthonycf4e33d2012-06-08 07:33:23 +00004114*/
cristy884f6002011-07-31 00:51:45 +00004115
cristya085a432011-07-30 01:39:32 +00004116MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
4117 const CacheView *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00004118 const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00004119 double *pixel,ExceptionInfo *exception)
4120{
4121 MagickBooleanType
4122 status;
4123
cristy94ea1632011-07-30 20:40:25 +00004124 MagickRealType
4125 alpha[16],
cristy884f6002011-07-31 00:51:45 +00004126 gamma,
4127 pixels[16];
cristy94ea1632011-07-30 20:40:25 +00004128
4129 PixelTrait
4130 traits;
4131
cristy94ea1632011-07-30 20:40:25 +00004132 register const Quantum
4133 *p;
4134
anthonycf4e33d2012-06-08 07:33:23 +00004135 register size_t
cristy94ea1632011-07-30 20:40:25 +00004136 i;
4137
cristya085a432011-07-30 01:39:32 +00004138 ssize_t
4139 x_offset,
4140 y_offset;
4141
anthonycf4e33d2012-06-08 07:33:23 +00004142 PixelInterpolateMethod
4143 interpolate;
4144
cristya085a432011-07-30 01:39:32 +00004145 assert(image != (Image *) NULL);
4146 assert(image != (Image *) NULL);
4147 assert(image->signature == MagickSignature);
4148 assert(image_view != (CacheView *) NULL);
4149 status=MagickTrue;
cristy884f6002011-07-31 00:51:45 +00004150 *pixel=0.0;
cristy94ea1632011-07-30 20:40:25 +00004151 traits=GetPixelChannelMapTraits(image,channel);
cristya085a432011-07-30 01:39:32 +00004152 x_offset=(ssize_t) floor(x);
4153 y_offset=(ssize_t) floor(y);
anthonycf4e33d2012-06-08 07:33:23 +00004154 interpolate = method;
4155 if ( interpolate == UndefinedInterpolatePixel )
4156 interpolate = image->interpolate;
4157 switch (interpolate)
cristya085a432011-07-30 01:39:32 +00004158 {
anthonycf4e33d2012-06-08 07:33:23 +00004159 case AverageInterpolatePixel: /* nearest 4 neighbours */
4160 case Average9InterpolatePixel: /* nearest 9 neighbours */
4161 case Average16InterpolatePixel: /* nearest 16 neighbours */
cristy884f6002011-07-31 00:51:45 +00004162 {
anthonycf4e33d2012-06-08 07:33:23 +00004163 size_t
4164 count=2; /* size of the area to average - default nearest 4 */
4165
4166 if (interpolate == Average9InterpolatePixel)
4167 {
4168 count=3;
4169 x_offset=(ssize_t) (floor(x+0.5)-1);
4170 y_offset=(ssize_t) (floor(y+0.5)-1);
4171 }
4172 else if (interpolate == Average16InterpolatePixel)
4173 {
4174 count=4;
4175 x_offset--;
4176 y_offset--;
4177 }
4178 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,count,count,
cristy884f6002011-07-31 00:51:45 +00004179 exception);
4180 if (p == (const Quantum *) NULL)
4181 {
4182 status=MagickFalse;
4183 break;
4184 }
anthonycf4e33d2012-06-08 07:33:23 +00004185
4186 count*=count; /* Number of pixels to Average */
cristy222b19c2011-08-04 01:35:11 +00004187 if ((traits & BlendPixelTrait) == 0)
anthonycf4e33d2012-06-08 07:33:23 +00004188 for (i=0; i < count; i++)
cristy884f6002011-07-31 00:51:45 +00004189 {
4190 alpha[i]=1.0;
4191 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4192 }
4193 else
anthonycf4e33d2012-06-08 07:33:23 +00004194 for (i=0; i < count; i++)
cristy884f6002011-07-31 00:51:45 +00004195 {
4196 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4197 GetPixelChannels(image));
4198 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4199 }
anthonycf4e33d2012-06-08 07:33:23 +00004200 for (i=0; i < count; i++)
cristy884f6002011-07-31 00:51:45 +00004201 {
anthonycf4e33d2012-06-08 07:33:23 +00004202 gamma=MagickEpsilonReciprocal(alpha[i])/count;
4203 *pixel+=gamma*pixels[i];
cristy884f6002011-07-31 00:51:45 +00004204 }
4205 break;
4206 }
anthonycf4e33d2012-06-08 07:33:23 +00004207 case BilinearInterpolatePixel:
4208 default:
4209 {
4210 PointInfo
4211 delta,
4212 epsilon;
4213
4214 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4215 if (p == (const Quantum *) NULL)
4216 {
4217 status=MagickFalse;
4218 break;
4219 }
4220 if ((traits & BlendPixelTrait) == 0)
4221 for (i=0; i < 4; i++)
4222 {
4223 alpha[i]=1.0;
4224 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4225 }
4226 else
4227 for (i=0; i < 4; i++)
4228 {
4229 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4230 GetPixelChannels(image));
4231 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4232 }
4233 delta.x=x-x_offset;
4234 delta.y=y-y_offset;
4235 epsilon.x=1.0-delta.x;
4236 epsilon.y=1.0-delta.y;
4237 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4238 (epsilon.x*alpha[2]+delta.x*alpha[3])));
4239 gamma=MagickEpsilonReciprocal(gamma);
4240 *pixel=gamma*(epsilon.y*(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*
4241 (epsilon.x*pixels[2]+delta.x*pixels[3]));
4242 break;
4243 }
4244 case CatromInterpolatePixel:
cristy884f6002011-07-31 00:51:45 +00004245 {
4246 MagickRealType
cristy380a11c2012-06-02 15:15:22 +00004247 cx[4],
nicolas6676f5a2012-06-12 16:01:15 +00004248 cy[4];
cristy884f6002011-07-31 00:51:45 +00004249
cristy884f6002011-07-31 00:51:45 +00004250 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4251 exception);
4252 if (p == (const Quantum *) NULL)
4253 {
4254 status=MagickFalse;
4255 break;
4256 }
cristy222b19c2011-08-04 01:35:11 +00004257 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004258 for (i=0; i < 16; i++)
4259 {
4260 alpha[i]=1.0;
4261 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4262 }
4263 else
4264 for (i=0; i < 16; i++)
4265 {
4266 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4267 GetPixelChannels(image));
4268 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4269 }
nicolasd32d5e52012-06-12 15:34:10 +00004270 CatromWeights((MagickRealType) (x-x_offset),&cx);
4271 CatromWeights((MagickRealType) (y-y_offset),&cy);
4272 gamma=(channel == AlphaPixelChannel ? (MagickRealType) 1.0 :
4273 MagickEpsilonReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
4274 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4275 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4276 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4277 cx[2]*alpha[14]+cx[3]*alpha[15])));
cristy380a11c2012-06-02 15:15:22 +00004278 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
nicolasd32d5e52012-06-12 15:34:10 +00004279 cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*
4280 pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+
4281 cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*
4282 pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15]));
cristy884f6002011-07-31 00:51:45 +00004283 break;
4284 }
anthonycf4e33d2012-06-08 07:33:23 +00004285#if 0
nicolas20075dc2012-06-12 20:47:38 +00004286 /* deprecated useless and very slow interpolator */
cristy884f6002011-07-31 00:51:45 +00004287 case FilterInterpolatePixel:
4288 {
4289 CacheView
4290 *filter_view;
4291
4292 Image
4293 *excerpt_image,
4294 *filter_image;
4295
4296 RectangleInfo
4297 geometry;
4298
4299 geometry.width=4L;
4300 geometry.height=4L;
4301 geometry.x=x_offset-1;
4302 geometry.y=y_offset-1;
4303 excerpt_image=ExcerptImage(image,&geometry,exception);
4304 if (excerpt_image == (Image *) NULL)
4305 {
4306 status=MagickFalse;
4307 break;
4308 }
cristyaa2c16c2012-03-25 22:21:35 +00004309 filter_image=ResizeImage(excerpt_image,1,1,image->filter,exception);
cristy884f6002011-07-31 00:51:45 +00004310 excerpt_image=DestroyImage(excerpt_image);
4311 if (filter_image == (Image *) NULL)
4312 break;
cristydb070952012-04-20 14:33:00 +00004313 filter_view=AcquireVirtualCacheView(filter_image,exception);
cristy884f6002011-07-31 00:51:45 +00004314 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4315 if (p == (const Quantum *) NULL)
4316 status=MagickFalse;
4317 else
cristy0beccfa2011-09-25 20:47:53 +00004318 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004319 filter_view=DestroyCacheView(filter_view);
4320 filter_image=DestroyImage(filter_image);
4321 break;
4322 }
anthonycf4e33d2012-06-08 07:33:23 +00004323#endif
cristy884f6002011-07-31 00:51:45 +00004324 case IntegerInterpolatePixel:
4325 {
4326 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
4327 if (p == (const Quantum *) NULL)
4328 {
4329 status=MagickFalse;
4330 break;
4331 }
cristy0beccfa2011-09-25 20:47:53 +00004332 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004333 break;
4334 }
anthonycf4e33d2012-06-08 07:33:23 +00004335 case NearestInterpolatePixel:
cristy884f6002011-07-31 00:51:45 +00004336 {
anthonycf4e33d2012-06-08 07:33:23 +00004337 x_offset=(ssize_t) floor(x+0.5);
4338 y_offset=(ssize_t) floor(y+0.5);
4339 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
cristy884f6002011-07-31 00:51:45 +00004340 if (p == (const Quantum *) NULL)
4341 {
4342 status=MagickFalse;
4343 break;
4344 }
cristy0beccfa2011-09-25 20:47:53 +00004345 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004346 break;
4347 }
4348 case MeshInterpolatePixel:
4349 {
4350 PointInfo
4351 delta,
cristy94ea1632011-07-30 20:40:25 +00004352 luminance;
4353
4354 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4355 if (p == (const Quantum *) NULL)
4356 {
4357 status=MagickFalse;
4358 break;
4359 }
cristy222b19c2011-08-04 01:35:11 +00004360 if ((traits & BlendPixelTrait) == 0)
cristy94ea1632011-07-30 20:40:25 +00004361 for (i=0; i < 4; i++)
4362 {
4363 alpha[i]=1.0;
cristy884f6002011-07-31 00:51:45 +00004364 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
cristy94ea1632011-07-30 20:40:25 +00004365 }
4366 else
4367 for (i=0; i < 4; i++)
4368 {
4369 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4370 GetPixelChannels(image));
4371 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4372 }
cristy884f6002011-07-31 00:51:45 +00004373 delta.x=x-x_offset;
4374 delta.y=y-y_offset;
4375 luminance.x=GetPixelLuminance(image,p)-(double)
4376 GetPixelLuminance(image,p+3*GetPixelChannels(image));
cristy28474bf2011-09-11 23:32:52 +00004377 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
cristy884f6002011-07-31 00:51:45 +00004378 GetPixelLuminance(image,p+2*GetPixelChannels(image));
cristy94ea1632011-07-30 20:40:25 +00004379 if (fabs(luminance.x) < fabs(luminance.y))
4380 {
4381 /*
4382 Diagonal 0-3 NW-SE.
4383 */
4384 if (delta.x <= delta.y)
4385 {
4386 /*
4387 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4388 */
4389 delta.y=1.0-delta.y;
4390 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
cristyc58380a2012-06-03 15:12:30 +00004391 gamma=MagickEpsilonReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004392 *pixel=gamma*MeshInterpolate(&delta,pixels[2],pixels[3],
4393 pixels[0]);
4394 }
4395 else
4396 {
4397 /*
4398 Top-right triangle (pixel: 1, diagonal: 0-3).
4399 */
4400 delta.x=1.0-delta.x;
4401 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
cristyc58380a2012-06-03 15:12:30 +00004402 gamma=MagickEpsilonReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004403 *pixel=gamma*MeshInterpolate(&delta,pixels[1],pixels[0],
4404 pixels[3]);
4405 }
4406 }
4407 else
4408 {
4409 /*
4410 Diagonal 1-2 NE-SW.
4411 */
4412 if (delta.x <= (1.0-delta.y))
4413 {
4414 /*
4415 Top-left triangle (pixel: 0, diagonal: 1-2).
4416 */
4417 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
cristyc58380a2012-06-03 15:12:30 +00004418 gamma=MagickEpsilonReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004419 *pixel=gamma*MeshInterpolate(&delta,pixels[0],pixels[1],
4420 pixels[2]);
4421 }
4422 else
4423 {
4424 /*
4425 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4426 */
4427 delta.x=1.0-delta.x;
4428 delta.y=1.0-delta.y;
4429 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
cristyc58380a2012-06-03 15:12:30 +00004430 gamma=MagickEpsilonReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004431 *pixel=gamma*MeshInterpolate(&delta,pixels[3],pixels[2],
4432 pixels[1]);
4433 }
4434 }
cristya085a432011-07-30 01:39:32 +00004435 break;
4436 }
cristy884f6002011-07-31 00:51:45 +00004437 case SplineInterpolatePixel:
4438 {
4439 MagickRealType
nicolasd32d5e52012-06-12 15:34:10 +00004440 cx[4],
nicolas6676f5a2012-06-12 16:01:15 +00004441 cy[4];
cristy884f6002011-07-31 00:51:45 +00004442
4443 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4444 exception);
4445 if (p == (const Quantum *) NULL)
4446 {
4447 status=MagickFalse;
4448 break;
4449 }
cristy222b19c2011-08-04 01:35:11 +00004450 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004451 for (i=0; i < 16; i++)
4452 {
4453 alpha[i]=1.0;
4454 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4455 }
4456 else
4457 for (i=0; i < 16; i++)
4458 {
4459 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4460 GetPixelChannels(image));
4461 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4462 }
nicolasd32d5e52012-06-12 15:34:10 +00004463 SplineWeights((MagickRealType) (x-x_offset),&cx);
4464 SplineWeights((MagickRealType) (y-y_offset),&cy);
4465 gamma=(channel == AlphaPixelChannel ? (MagickRealType) 1.0 :
4466 MagickEpsilonReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
4467 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4468 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4469 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4470 cx[2]*alpha[14]+cx[3]*alpha[15])));
4471 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
4472 cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*
4473 pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+
4474 cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*
4475 pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15]));
cristy884f6002011-07-31 00:51:45 +00004476 break;
4477 }
cristya085a432011-07-30 01:39:32 +00004478 }
4479 return(status);
4480}
4481
4482/*
4483%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4484% %
4485% %
4486% %
cristy5c4e2582011-09-11 19:21:03 +00004487% I n t e r p o l a t e P i x e l C h a n n e l s %
4488% %
4489% %
4490% %
4491%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4492%
4493% InterpolatePixelChannels() applies a pixel interpolation method between a
4494% floating point coordinate and the pixels surrounding that coordinate. No
4495% pixel area resampling, or scaling of the result is performed.
4496%
anthonycf4e33d2012-06-08 07:33:23 +00004497% Interpolation is restricted to just the current channel setting of the
4498% destination image into which the color is to be stored
4499%
cristy5c4e2582011-09-11 19:21:03 +00004500% The format of the InterpolatePixelChannels method is:
4501%
4502% MagickBooleanType InterpolatePixelChannels(const Image *source,
4503% const CacheView *source_view,const Image *destination,
4504% const PixelInterpolateMethod method,const double x,const double y,
4505% Quantum *pixel,ExceptionInfo *exception)
4506%
4507% A description of each parameter follows:
4508%
4509% o source: the source.
4510%
4511% o source_view: the source view.
4512%
anthonycf4e33d2012-06-08 07:33:23 +00004513% o destination: the destination image, for the interpolated color
cristy5c4e2582011-09-11 19:21:03 +00004514%
4515% o method: the pixel color interpolation method.
4516%
4517% o x,y: A double representing the current (x,y) position of the pixel.
4518%
4519% o pixel: return the interpolated pixel here.
4520%
4521% o exception: return any errors or warnings in this structure.
4522%
4523*/
4524MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
4525 const CacheView *source_view,const Image *destination,
4526 const PixelInterpolateMethod method,const double x,const double y,
4527 Quantum *pixel,ExceptionInfo *exception)
4528{
4529 MagickBooleanType
4530 status;
4531
4532 MagickRealType
4533 alpha[16],
4534 gamma,
4535 pixels[16];
4536
4537 PixelChannel
4538 channel;
4539
4540 PixelTrait
4541 destination_traits,
4542 traits;
4543
4544 register const Quantum
4545 *p;
4546
anthonycf4e33d2012-06-08 07:33:23 +00004547 register size_t
cristy5c4e2582011-09-11 19:21:03 +00004548 i;
4549
4550 ssize_t
4551 x_offset,
4552 y_offset;
4553
anthonycf4e33d2012-06-08 07:33:23 +00004554 PixelInterpolateMethod
4555 interpolate;
4556
cristy5c4e2582011-09-11 19:21:03 +00004557 assert(source != (Image *) NULL);
4558 assert(source != (Image *) NULL);
4559 assert(source->signature == MagickSignature);
4560 assert(source_view != (CacheView *) NULL);
4561 status=MagickTrue;
4562 x_offset=(ssize_t) floor(x);
4563 y_offset=(ssize_t) floor(y);
anthonycf4e33d2012-06-08 07:33:23 +00004564 interpolate = method;
4565 if ( interpolate == UndefinedInterpolatePixel )
4566 interpolate = source->interpolate;
4567 switch (interpolate)
cristy5c4e2582011-09-11 19:21:03 +00004568 {
anthonycf4e33d2012-06-08 07:33:23 +00004569 case AverageInterpolatePixel: /* nearest 4 neighbours */
4570 case Average9InterpolatePixel: /* nearest 9 neighbours */
4571 case Average16InterpolatePixel: /* nearest 16 neighbours */
cristy5c4e2582011-09-11 19:21:03 +00004572 {
anthonycf4e33d2012-06-08 07:33:23 +00004573 size_t
4574 count=2; /* size of the area to average - default nearest 4 */
4575
4576 if (interpolate == Average9InterpolatePixel)
4577 {
4578 count=3;
4579 x_offset=(ssize_t) (floor(x+0.5)-1);
4580 y_offset=(ssize_t) (floor(y+0.5)-1);
4581 }
4582 else if (interpolate == Average16InterpolatePixel)
4583 {
4584 count=4;
4585 x_offset--;
4586 y_offset--;
4587 }
4588 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,count,count,
cristy5c4e2582011-09-11 19:21:03 +00004589 exception);
4590 if (p == (const Quantum *) NULL)
4591 {
4592 status=MagickFalse;
4593 break;
4594 }
anthonycf4e33d2012-06-08 07:33:23 +00004595 count*=count; /* Number of pixels to Average */
4596 for (i=0; i < GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004597 {
4598 double
4599 sum;
4600
anthonycf4e33d2012-06-08 07:33:23 +00004601 register size_t
cristy5c4e2582011-09-11 19:21:03 +00004602 j;
4603
cristye2a912b2011-12-05 20:02:07 +00004604 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004605 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004606 destination_traits=GetPixelChannelMapTraits(destination,channel);
4607 if ((traits == UndefinedPixelTrait) ||
4608 (destination_traits == UndefinedPixelTrait))
4609 continue;
anthonycf4e33d2012-06-08 07:33:23 +00004610 for (j=0; j < count; j++)
cristy5c4e2582011-09-11 19:21:03 +00004611 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
cristy4a7ae692011-12-14 12:24:11 +00004612 sum=0.0;
cristy5c4e2582011-09-11 19:21:03 +00004613 if ((traits & BlendPixelTrait) == 0)
4614 {
anthonycf4e33d2012-06-08 07:33:23 +00004615 for (j=0; j < count; j++)
4616 sum+=pixels[j];
4617 sum/=count;
cristy4a7ae692011-12-14 12:24:11 +00004618 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004619 continue;
4620 }
anthonycf4e33d2012-06-08 07:33:23 +00004621 for (j=0; j < count; j++)
cristy5c4e2582011-09-11 19:21:03 +00004622 {
4623 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4624 GetPixelChannels(source));
4625 pixels[j]*=alpha[j];
cristyc58380a2012-06-03 15:12:30 +00004626 gamma=MagickEpsilonReciprocal(alpha[j]);
anthonycf4e33d2012-06-08 07:33:23 +00004627 sum+=gamma*pixels[j];
cristy5c4e2582011-09-11 19:21:03 +00004628 }
anthonycf4e33d2012-06-08 07:33:23 +00004629 sum/=count;
cristy4a7ae692011-12-14 12:24:11 +00004630 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004631 }
4632 break;
4633 }
anthonycf4e33d2012-06-08 07:33:23 +00004634 case BilinearInterpolatePixel:
4635 default:
4636 {
4637 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4638 if (p == (const Quantum *) NULL)
4639 {
4640 status=MagickFalse;
4641 break;
4642 }
4643 for (i=0; i < GetPixelChannels(source); i++)
4644 {
4645 PointInfo
4646 delta,
4647 epsilon;
4648
4649 channel=GetPixelChannelMapChannel(source,i);
4650 traits=GetPixelChannelMapTraits(source,channel);
4651 destination_traits=GetPixelChannelMapTraits(destination,channel);
4652 if ((traits == UndefinedPixelTrait) ||
4653 (destination_traits == UndefinedPixelTrait))
4654 continue;
4655 delta.x=x-x_offset;
4656 delta.y=y-y_offset;
4657 epsilon.x=1.0-delta.x;
4658 epsilon.y=1.0-delta.y;
4659 pixels[0]=(MagickRealType) p[i];
4660 pixels[1]=(MagickRealType) p[GetPixelChannels(source)+i];
4661 pixels[2]=(MagickRealType) p[2*GetPixelChannels(source)+i];
4662 pixels[3]=(MagickRealType) p[3*GetPixelChannels(source)+i];
4663 if ((traits & BlendPixelTrait) == 0)
4664 {
4665 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
4666 gamma=MagickEpsilonReciprocal(gamma);
4667 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
4668 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*
4669 pixels[2]+delta.x*pixels[3]))),pixel);
4670 continue;
4671 }
4672 alpha[0]=QuantumScale*GetPixelAlpha(source,p);
4673 alpha[1]=QuantumScale*GetPixelAlpha(source,p+GetPixelChannels(source));
4674 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
4675 GetPixelChannels(source));
4676 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
4677 GetPixelChannels(source));
4678 pixels[0]*=alpha[0];
4679 pixels[1]*=alpha[1];
4680 pixels[2]*=alpha[2];
4681 pixels[3]*=alpha[3];
4682 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4683 (epsilon.x*alpha[2]+delta.x*alpha[3])));
4684 gamma=MagickEpsilonReciprocal(gamma);
4685 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
4686 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*pixels[2]+
4687 delta.x*pixels[3]))),pixel);
4688 }
4689 break;
4690 }
4691 case CatromInterpolatePixel:
cristy5c4e2582011-09-11 19:21:03 +00004692 {
4693 MagickRealType
cristy380a11c2012-06-02 15:15:22 +00004694 cx[4],
4695 cy[4];
cristy5c4e2582011-09-11 19:21:03 +00004696
cristy5c4e2582011-09-11 19:21:03 +00004697 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4698 exception);
4699 if (p == (const Quantum *) NULL)
4700 {
4701 status=MagickFalse;
4702 break;
4703 }
anthonycf4e33d2012-06-08 07:33:23 +00004704 for (i=0; i < GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004705 {
4706 register ssize_t
4707 j;
4708
cristye2a912b2011-12-05 20:02:07 +00004709 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004710 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004711 destination_traits=GetPixelChannelMapTraits(destination,channel);
4712 if ((traits == UndefinedPixelTrait) ||
4713 (destination_traits == UndefinedPixelTrait))
4714 continue;
4715 if ((traits & BlendPixelTrait) == 0)
4716 for (j=0; j < 16; j++)
4717 {
4718 alpha[j]=1.0;
4719 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
4720 }
4721 else
4722 for (j=0; j < 16; j++)
4723 {
4724 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4725 GetPixelChannels(source));
4726 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
4727 }
nicolasd32d5e52012-06-12 15:34:10 +00004728 CatromWeights((MagickRealType) (x-x_offset),&cx);
4729 CatromWeights((MagickRealType) (y-y_offset),&cy);
4730 gamma=((traits & BlendPixelTrait) ? (MagickRealType) (1.0) :
4731 MagickEpsilonReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
4732 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4733 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4734 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4735 cx[2]*alpha[14]+cx[3]*alpha[15])));
cristy380a11c2012-06-02 15:15:22 +00004736 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]*
4737 pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]*
4738 (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+
4739 cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*
nicolasd32d5e52012-06-12 15:34:10 +00004740 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*
4741 pixels[14]+cx[3]*pixels[15]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004742 }
4743 break;
4744 }
anthonycf4e33d2012-06-08 07:33:23 +00004745#if 0
nicolas20075dc2012-06-12 20:47:38 +00004746 /* deprecated useless and very slow interpolator */
cristy5c4e2582011-09-11 19:21:03 +00004747 case FilterInterpolatePixel:
4748 {
anthonycf4e33d2012-06-08 07:33:23 +00004749 for (i=0; i < GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004750 {
4751 CacheView
4752 *filter_view;
4753
4754 Image
4755 *excerpt_source,
4756 *filter_source;
4757
4758 RectangleInfo
4759 geometry;
4760
cristye2a912b2011-12-05 20:02:07 +00004761 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004762 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004763 destination_traits=GetPixelChannelMapTraits(destination,channel);
4764 if ((traits == UndefinedPixelTrait) ||
4765 (destination_traits == UndefinedPixelTrait))
4766 continue;
4767 geometry.width=4L;
4768 geometry.height=4L;
4769 geometry.x=x_offset-1;
4770 geometry.y=y_offset-1;
4771 excerpt_source=ExcerptImage(source,&geometry,exception);
4772 if (excerpt_source == (Image *) NULL)
4773 {
4774 status=MagickFalse;
4775 continue;
4776 }
cristyaa2c16c2012-03-25 22:21:35 +00004777 filter_source=ResizeImage(excerpt_source,1,1,source->filter,exception);
cristy5c4e2582011-09-11 19:21:03 +00004778 excerpt_source=DestroyImage(excerpt_source);
4779 if (filter_source == (Image *) NULL)
4780 continue;
cristydb070952012-04-20 14:33:00 +00004781 filter_view=AcquireVirtualCacheView(filter_source,exception);
cristy5c4e2582011-09-11 19:21:03 +00004782 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4783 if (p == (const Quantum *) NULL)
4784 status=MagickFalse;
4785 else
cristy1861c902011-12-14 02:30:00 +00004786 {
cristy4a7ae692011-12-14 12:24:11 +00004787 SetPixelChannel(destination,channel,p[i],pixel);
cristy1861c902011-12-14 02:30:00 +00004788 }
cristy5c4e2582011-09-11 19:21:03 +00004789 filter_view=DestroyCacheView(filter_view);
4790 filter_source=DestroyImage(filter_source);
4791 }
4792 break;
4793 }
anthonycf4e33d2012-06-08 07:33:23 +00004794#endif
cristy5c4e2582011-09-11 19:21:03 +00004795 case IntegerInterpolatePixel:
4796 {
4797 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
4798 if (p == (const Quantum *) NULL)
4799 {
4800 status=MagickFalse;
4801 break;
4802 }
anthonycf4e33d2012-06-08 07:33:23 +00004803 for (i=0; i < GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004804 {
cristye2a912b2011-12-05 20:02:07 +00004805 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004806 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004807 destination_traits=GetPixelChannelMapTraits(destination,channel);
4808 if ((traits == UndefinedPixelTrait) ||
4809 (destination_traits == UndefinedPixelTrait))
4810 continue;
cristy4a7ae692011-12-14 12:24:11 +00004811 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004812 }
4813 break;
4814 }
anthonycf4e33d2012-06-08 07:33:23 +00004815 case NearestInterpolatePixel:
cristy5c4e2582011-09-11 19:21:03 +00004816 {
anthonycf4e33d2012-06-08 07:33:23 +00004817 x_offset=(ssize_t) floor(x+0.5);
4818 y_offset=(ssize_t) floor(y+0.5);
4819 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
cristy5c4e2582011-09-11 19:21:03 +00004820 if (p == (const Quantum *) NULL)
4821 {
4822 status=MagickFalse;
4823 break;
4824 }
anthonycf4e33d2012-06-08 07:33:23 +00004825 for (i=0; i < GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004826 {
cristye2a912b2011-12-05 20:02:07 +00004827 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004828 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004829 destination_traits=GetPixelChannelMapTraits(destination,channel);
4830 if ((traits == UndefinedPixelTrait) ||
4831 (destination_traits == UndefinedPixelTrait))
4832 continue;
cristy4a7ae692011-12-14 12:24:11 +00004833 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004834 }
4835 break;
4836 }
4837 case MeshInterpolatePixel:
4838 {
4839 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4840 if (p == (const Quantum *) NULL)
4841 {
4842 status=MagickFalse;
4843 break;
4844 }
anthonycf4e33d2012-06-08 07:33:23 +00004845 for (i=0; i < GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004846 {
4847 PointInfo
4848 delta,
4849 luminance;
4850
cristye2a912b2011-12-05 20:02:07 +00004851 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004852 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004853 destination_traits=GetPixelChannelMapTraits(destination,channel);
4854 if ((traits == UndefinedPixelTrait) ||
4855 (destination_traits == UndefinedPixelTrait))
4856 continue;
cristy1861c902011-12-14 02:30:00 +00004857 pixels[0]=(MagickRealType) p[i];
4858 pixels[1]=(MagickRealType) p[GetPixelChannels(source)+i];
4859 pixels[2]=(MagickRealType) p[2*GetPixelChannels(source)+i];
4860 pixels[3]=(MagickRealType) p[3*GetPixelChannels(source)+i];
4861 if ((traits & BlendPixelTrait) == 0)
4862 {
4863 alpha[0]=1.0;
4864 alpha[1]=1.0;
4865 alpha[2]=1.0;
4866 alpha[3]=1.0;
4867 }
4868 else
4869 {
4870 alpha[0]=QuantumScale*GetPixelAlpha(source,p);
4871 alpha[1]=QuantumScale*GetPixelAlpha(source,p+
4872 GetPixelChannels(source));
4873 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
4874 GetPixelChannels(source));
4875 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
4876 GetPixelChannels(source));
4877 }
4878 delta.x=x-x_offset;
4879 delta.y=y-y_offset;
anthonycf4e33d2012-06-08 07:33:23 +00004880 luminance.x=fabs((double)(
4881 GetPixelLuminance(source,p)
4882 -GetPixelLuminance(source,p+3*GetPixelChannels(source))));
4883 luminance.y=fabs((double)(
4884 GetPixelLuminance(source,p+GetPixelChannels(source))
4885 -GetPixelLuminance(source,p+2*GetPixelChannels(source))));
4886 if (luminance.x < luminance.y)
cristy1861c902011-12-14 02:30:00 +00004887 {
4888 /*
4889 Diagonal 0-3 NW-SE.
4890 */
4891 if (delta.x <= delta.y)
4892 {
4893 /*
4894 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4895 */
4896 delta.y=1.0-delta.y;
4897 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
cristyc58380a2012-06-03 15:12:30 +00004898 gamma=MagickEpsilonReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00004899 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4900 MeshInterpolate(&delta,pixels[2],pixels[3],pixels[0])),pixel);
cristy1861c902011-12-14 02:30:00 +00004901 }
4902 else
4903 {
4904 /*
4905 Top-right triangle (pixel: 1, diagonal: 0-3).
4906 */
4907 delta.x=1.0-delta.x;
4908 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
cristyc58380a2012-06-03 15:12:30 +00004909 gamma=MagickEpsilonReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00004910 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4911 MeshInterpolate(&delta,pixels[1],pixels[0],pixels[3])),pixel);
cristy1861c902011-12-14 02:30:00 +00004912 }
4913 }
4914 else
4915 {
4916 /*
4917 Diagonal 1-2 NE-SW.
4918 */
4919 if (delta.x <= (1.0-delta.y))
4920 {
4921 /*
4922 Top-left triangle (pixel: 0, diagonal: 1-2).
4923 */
4924 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
cristyc58380a2012-06-03 15:12:30 +00004925 gamma=MagickEpsilonReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00004926 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4927 MeshInterpolate(&delta,pixels[0],pixels[1],pixels[2])),pixel);
cristy1861c902011-12-14 02:30:00 +00004928 }
4929 else
4930 {
4931 /*
4932 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4933 */
4934 delta.x=1.0-delta.x;
4935 delta.y=1.0-delta.y;
4936 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
cristyc58380a2012-06-03 15:12:30 +00004937 gamma=MagickEpsilonReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00004938 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4939 MeshInterpolate(&delta,pixels[3],pixels[2],pixels[1])),pixel);
cristy1861c902011-12-14 02:30:00 +00004940 }
4941 }
cristy5c4e2582011-09-11 19:21:03 +00004942 }
4943 break;
4944 }
4945 case SplineInterpolatePixel:
4946 {
nicolasd32d5e52012-06-12 15:34:10 +00004947 MagickRealType
4948 cx[4],
4949 cy[4];
4950
cristy5c4e2582011-09-11 19:21:03 +00004951 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4952 exception);
4953 if (p == (const Quantum *) NULL)
4954 {
4955 status=MagickFalse;
4956 break;
4957 }
anthonycf4e33d2012-06-08 07:33:23 +00004958 for (i=0; i < GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004959 {
cristy5c4e2582011-09-11 19:21:03 +00004960 register ssize_t
4961 j;
4962
cristye2a912b2011-12-05 20:02:07 +00004963 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004964 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004965 destination_traits=GetPixelChannelMapTraits(destination,channel);
4966 if ((traits == UndefinedPixelTrait) ||
4967 (destination_traits == UndefinedPixelTrait))
4968 continue;
4969 if ((traits & BlendPixelTrait) == 0)
4970 for (j=0; j < 16; j++)
4971 {
4972 alpha[j]=1.0;
4973 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
4974 }
4975 else
4976 for (j=0; j < 16; j++)
4977 {
4978 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4979 GetPixelChannels(source));
4980 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
4981 }
nicolasd32d5e52012-06-12 15:34:10 +00004982 SplineWeights((MagickRealType) (x-x_offset),&cx);
4983 SplineWeights((MagickRealType) (y-y_offset),&cy);
4984 gamma=((traits & BlendPixelTrait) ? (MagickRealType) (1.0) :
4985 MagickEpsilonReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
4986 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4987 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4988 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4989 cx[2]*alpha[14]+cx[3]*alpha[15])));
4990 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]*
4991 pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]*
4992 (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+
4993 cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*
4994 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*
4995 pixels[14]+cx[3]*pixels[15]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004996 }
4997 break;
4998 }
4999 }
5000 return(status);
5001}
5002
5003/*
5004%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5005% %
5006% %
5007% %
cristy9075cdb2011-07-30 01:06:23 +00005008% 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 +00005009% %
5010% %
5011% %
5012%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5013%
cristy884f6002011-07-31 00:51:45 +00005014% InterpolatePixelInfo() applies a pixel interpolation method between a
5015% floating point coordinate and the pixels surrounding that coordinate. No
5016% pixel area resampling, or scaling of the result is performed.
cristy4c08aed2011-07-01 19:47:50 +00005017%
anthonycf4e33d2012-06-08 07:33:23 +00005018% Interpolation is restricted to just RGBKA channels.
5019%
cristy4c08aed2011-07-01 19:47:50 +00005020% The format of the InterpolatePixelInfo method is:
5021%
5022% MagickBooleanType InterpolatePixelInfo(const Image *image,
cristy5c4e2582011-09-11 19:21:03 +00005023% const CacheView *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00005024% const double x,const double y,PixelInfo *pixel,
5025% ExceptionInfo *exception)
5026%
5027% A description of each parameter follows:
5028%
5029% o image: the image.
5030%
5031% o image_view: the image view.
5032%
5033% o method: the pixel color interpolation method.
5034%
5035% o x,y: A double representing the current (x,y) position of the pixel.
5036%
5037% o pixel: return the interpolated pixel here.
5038%
5039% o exception: return any errors or warnings in this structure.
5040%
5041*/
5042
5043static inline void AlphaBlendPixelInfo(const Image *image,
5044 const Quantum *pixel,PixelInfo *pixel_info,MagickRealType *alpha)
5045{
5046 if (image->matte == MagickFalse)
5047 {
5048 *alpha=1.0;
5049 pixel_info->red=(MagickRealType) GetPixelRed(image,pixel);
5050 pixel_info->green=(MagickRealType) GetPixelGreen(image,pixel);
5051 pixel_info->blue=(MagickRealType) GetPixelBlue(image,pixel);
5052 pixel_info->black=0.0;
5053 if (image->colorspace == CMYKColorspace)
5054 pixel_info->black=(MagickRealType) GetPixelBlack(image,pixel);
5055 pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
5056 return;
5057 }
5058 *alpha=QuantumScale*GetPixelAlpha(image,pixel);
5059 pixel_info->red=(*alpha*GetPixelRed(image,pixel));
5060 pixel_info->green=(*alpha*GetPixelGreen(image,pixel));
5061 pixel_info->blue=(*alpha*GetPixelBlue(image,pixel));
5062 pixel_info->black=0.0;
5063 if (image->colorspace == CMYKColorspace)
5064 pixel_info->black=(*alpha*GetPixelBlack(image,pixel));
5065 pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
5066}
5067
cristy4c08aed2011-07-01 19:47:50 +00005068MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
cristy5c4e2582011-09-11 19:21:03 +00005069 const CacheView *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00005070 const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception)
5071{
5072 MagickBooleanType
5073 status;
5074
cristy4c08aed2011-07-01 19:47:50 +00005075 MagickRealType
5076 alpha[16],
5077 gamma;
5078
cristy865d58d2011-07-09 00:44:52 +00005079 PixelInfo
5080 pixels[16];
5081
cristy4c08aed2011-07-01 19:47:50 +00005082 register const Quantum
5083 *p;
5084
anthonycf4e33d2012-06-08 07:33:23 +00005085 register size_t
cristy4c08aed2011-07-01 19:47:50 +00005086 i;
5087
5088 ssize_t
5089 x_offset,
5090 y_offset;
5091
anthonycf4e33d2012-06-08 07:33:23 +00005092 PixelInterpolateMethod
5093 interpolate;
5094
cristy4c08aed2011-07-01 19:47:50 +00005095 assert(image != (Image *) NULL);
5096 assert(image->signature == MagickSignature);
5097 assert(image_view != (CacheView *) NULL);
5098 status=MagickTrue;
5099 x_offset=(ssize_t) floor(x);
5100 y_offset=(ssize_t) floor(y);
anthonycf4e33d2012-06-08 07:33:23 +00005101 interpolate = method;
5102 if ( interpolate == UndefinedInterpolatePixel )
5103 interpolate = image->interpolate;
5104 switch (interpolate)
cristy4c08aed2011-07-01 19:47:50 +00005105 {
anthonycf4e33d2012-06-08 07:33:23 +00005106 case AverageInterpolatePixel: /* nearest 4 neighbours */
5107 case Average9InterpolatePixel: /* nearest 9 neighbours */
5108 case Average16InterpolatePixel: /* nearest 16 neighbours */
cristy4c08aed2011-07-01 19:47:50 +00005109 {
anthonycf4e33d2012-06-08 07:33:23 +00005110 size_t
5111 count=2; /* size of the area to average - default nearest 4 */
5112
5113 if (interpolate == Average9InterpolatePixel)
5114 {
5115 count=3;
5116 x_offset=(ssize_t) (floor(x+0.5)-1);
5117 y_offset=(ssize_t) (floor(y+0.5)-1);
5118 }
5119 else if (interpolate == Average16InterpolatePixel)
5120 {
5121 count=4;
5122 x_offset--;
5123 y_offset--;
5124 }
5125 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,count,count,
cristy4c08aed2011-07-01 19:47:50 +00005126 exception);
5127 if (p == (const Quantum *) NULL)
5128 {
5129 status=MagickFalse;
5130 break;
5131 }
cristy4c08aed2011-07-01 19:47:50 +00005132 pixel->red=0.0;
5133 pixel->green=0.0;
5134 pixel->blue=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005135 pixel->black=0.0;
cristy865d58d2011-07-09 00:44:52 +00005136 pixel->alpha=0.0;
anthonycf4e33d2012-06-08 07:33:23 +00005137 count*=count; /* number of pixels - square of size */
5138 for (i=0; i < count; i++)
cristy4c08aed2011-07-01 19:47:50 +00005139 {
anthonycf4e33d2012-06-08 07:33:23 +00005140 AlphaBlendPixelInfo(image,p,pixels,alpha);
5141 gamma=MagickEpsilonReciprocal(alpha[0]);
5142 pixel->red += gamma*pixels[0].red;
5143 pixel->green += gamma*pixels[0].green;
5144 pixel->blue += gamma*pixels[0].blue;
5145 pixel->black += gamma*pixels[0].black;
5146 pixel->alpha += pixels[0].alpha;
5147 p += GetPixelChannels(image);
cristy4c08aed2011-07-01 19:47:50 +00005148 }
anthonycf4e33d2012-06-08 07:33:23 +00005149 gamma=1.0/count; /* average weighting of each pixel in area */
5150 pixel->red *= gamma;
5151 pixel->green *= gamma;
5152 pixel->blue *= gamma;
5153 pixel->black *= gamma;
5154 pixel->alpha *= gamma;
cristy4c08aed2011-07-01 19:47:50 +00005155 break;
5156 }
anthonycf4e33d2012-06-08 07:33:23 +00005157 case BackgroundInterpolatePixel:
5158 {
5159 *pixel = image->background_color; /* Copy PixelInfo Structure */
5160 break;
5161 }
5162 case BilinearInterpolatePixel:
5163 default:
5164 {
5165 PointInfo
5166 delta,
5167 epsilon;
5168
5169 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5170 if (p == (const Quantum *) NULL)
5171 {
5172 status=MagickFalse;
5173 break;
5174 }
5175 for (i=0; i < 4L; i++)
5176 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
5177 delta.x=x-x_offset;
5178 delta.y=y-y_offset;
5179 epsilon.x=1.0-delta.x;
5180 epsilon.y=1.0-delta.y;
5181 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
5182 (epsilon.x*alpha[2]+delta.x*alpha[3])));
5183 gamma=MagickEpsilonReciprocal(gamma);
5184 pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x*
5185 pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red));
5186 pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x*
5187 pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x*
5188 pixels[3].green));
5189 pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x*
5190 pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x*
5191 pixels[3].blue));
5192 if (image->colorspace == CMYKColorspace)
5193 pixel->black=gamma*(epsilon.y*(epsilon.x*pixels[0].black+delta.x*
5194 pixels[1].black)+delta.y*(epsilon.x*pixels[2].black+delta.x*
5195 pixels[3].black));
5196 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
5197 gamma=MagickEpsilonReciprocal(gamma);
5198 pixel->alpha=(epsilon.y*(epsilon.x*pixels[0].alpha+delta.x*
5199 pixels[1].alpha)+delta.y*(epsilon.x*pixels[2].alpha+delta.x*
5200 pixels[3].alpha));
5201 break;
5202 }
5203 case BlendInterpolatePixel:
5204 {
5205 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5206 if (p == (const Quantum *) NULL)
5207 {
5208 status=MagickFalse;
5209 break;
5210 }
5211 for (i=0; i < 4L; i++)
5212 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
5213 gamma=1.0; /* number of pixels blended together */
5214 for (i=0; i <= 1L; i++) {
5215 if ( y-y_offset >= 0.75 ) {
5216 alpha[i] = alpha[i+2];
5217 pixels[i] = pixels[i+2];
5218 }
5219 else if ( y-y_offset > 0.25 ) {
5220 gamma = 2.0; /* each y pixels have been blended */
5221 alpha[i] += alpha[i+2]; /* add up alpha weights */
5222 pixels[i].red += pixels[i+2].red;
5223 pixels[i].green += pixels[i+2].green;
5224 pixels[i].blue += pixels[i+2].blue;
5225 pixels[i].black += pixels[i+2].black;
5226 pixels[i].alpha += pixels[i+2].alpha;
5227 }
5228 }
5229 if ( x-x_offset >= 0.75 ) {
5230 alpha[0] = alpha[1];
5231 pixels[0] = pixels[1];
5232 }
5233 else if ( x-x_offset > 0.25 ) {
5234 gamma *= 2.0; /* double number of pixels blended */
5235 alpha[0] += alpha[1]; /* add up alpha weights */
5236 pixels[0].red += pixels[1].red;
5237 pixels[0].green += pixels[1].green;
5238 pixels[0].blue += pixels[1].blue;
5239 pixels[0].black += pixels[1].black;
5240 pixels[0].alpha += pixels[1].alpha;
5241 }
5242 gamma = 1.0/gamma;
5243 alpha[0]=MagickEpsilonReciprocal(alpha[0]);
5244 pixel->red = alpha[0]*pixels[0].red;
5245 pixel->green = alpha[0]*pixels[0].green; /* divide by sum of alpha */
5246 pixel->blue = alpha[0]*pixels[0].blue;
5247 pixel->black = alpha[0]*pixels[0].black;
5248 pixel->alpha = gamma*pixels[0].alpha; /* divide by number of pixels */
5249 break;
5250 }
5251 case CatromInterpolatePixel:
cristy4c08aed2011-07-01 19:47:50 +00005252 {
cristy380a11c2012-06-02 15:15:22 +00005253 MagickRealType
cristy380a11c2012-06-02 15:15:22 +00005254 cx[4],
5255 cy[4];
cristy4c08aed2011-07-01 19:47:50 +00005256
cristy4c08aed2011-07-01 19:47:50 +00005257 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5258 exception);
5259 if (p == (const Quantum *) NULL)
5260 {
5261 status=MagickFalse;
5262 break;
5263 }
anthonycf4e33d2012-06-08 07:33:23 +00005264 for (i=0; i < 16L; i++)
5265 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
nicolasd32d5e52012-06-12 15:34:10 +00005266 CatromWeights((MagickRealType) (x-x_offset),&cx);
5267 CatromWeights((MagickRealType) (y-y_offset),&cy);
cristy380a11c2012-06-02 15:15:22 +00005268 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*
5269 pixels[1].red+cx[2]*pixels[2].red+cx[3]*
5270 pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
5271 pixels[5].red+cx[2]*pixels[6].red+cx[3]*
5272 pixels[7].red)+cy[2]*(cx[0]*pixels[8].red+cx[1]*
5273 pixels[9].red+cx[2]*pixels[10].red+cx[3]*
5274 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*
5275 pixels[13].red+cx[2]*pixels[14].red+cx[3]*pixels[15].red));
5276 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*
5277 pixels[1].green+cx[2]*pixels[2].green+cx[3]*
5278 pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+cx[1]*
5279 pixels[5].green+cx[2]*pixels[6].green+cx[3]*
5280 pixels[7].green)+cy[2]*(cx[0]*pixels[8].green+cx[1]*
5281 pixels[9].green+cx[2]*pixels[10].green+cx[3]*
5282 pixels[11].green)+cy[3]*(cx[0]*pixels[12].green+cx[1]*
5283 pixels[13].green+cx[2]*pixels[14].green+cx[3]*pixels[15].green));
5284 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*
5285 pixels[1].blue+cx[2]*pixels[2].blue+cx[3]*
5286 pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]*
5287 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*
5288 pixels[7].blue)+cy[2]*(cx[0]*pixels[8].blue+cx[1]*
5289 pixels[9].blue+cx[2]*pixels[10].blue+cx[3]*
5290 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*
5291 pixels[13].blue+cx[2]*pixels[14].blue+cx[3]*pixels[15].blue));
5292 if (image->colorspace == CMYKColorspace)
5293 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*
5294 pixels[1].black+cx[2]*pixels[2].black+cx[3]*
5295 pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+cx[1]*
5296 pixels[5].black+cx[2]*pixels[6].black+cx[3]*
5297 pixels[7].black)+cy[2]*(cx[0]*pixels[8].black+cx[1]*
5298 pixels[9].black+cx[2]*pixels[10].black+cx[3]*
5299 pixels[11].black)+cy[3]*(cx[0]*pixels[12].black+cx[1]*
5300 pixels[13].black+cx[2]*pixels[14].black+cx[3]*pixels[15].black));
5301 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*
5302 pixels[1].alpha+cx[2]*pixels[2].alpha+cx[3]*
5303 pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+cx[1]*
5304 pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*
5305 pixels[7].alpha)+cy[2]*(cx[0]*pixels[8].alpha+cx[1]*
5306 pixels[9].alpha+cx[2]*pixels[10].alpha+cx[3]*
5307 pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+cx[1]*
5308 pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha));
cristy4c08aed2011-07-01 19:47:50 +00005309 break;
5310 }
anthonycf4e33d2012-06-08 07:33:23 +00005311#if 0
nicolas20075dc2012-06-12 20:47:38 +00005312 /* deprecated useless and very slow interpolator */
cristy4c08aed2011-07-01 19:47:50 +00005313 case FilterInterpolatePixel:
5314 {
5315 CacheView
5316 *filter_view;
5317
5318 Image
5319 *excerpt_image,
5320 *filter_image;
5321
5322 RectangleInfo
5323 geometry;
5324
5325 geometry.width=4L;
5326 geometry.height=4L;
5327 geometry.x=x_offset-1;
5328 geometry.y=y_offset-1;
5329 excerpt_image=ExcerptImage(image,&geometry,exception);
5330 if (excerpt_image == (Image *) NULL)
5331 {
5332 status=MagickFalse;
5333 break;
5334 }
cristyaa2c16c2012-03-25 22:21:35 +00005335 filter_image=ResizeImage(excerpt_image,1,1,image->filter,exception);
cristy4c08aed2011-07-01 19:47:50 +00005336 excerpt_image=DestroyImage(excerpt_image);
5337 if (filter_image == (Image *) NULL)
5338 break;
cristydb070952012-04-20 14:33:00 +00005339 filter_view=AcquireVirtualCacheView(filter_image,exception);
cristy4c08aed2011-07-01 19:47:50 +00005340 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
5341 if (p != (const Quantum *) NULL)
cristy803640d2011-11-17 02:11:32 +00005342 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005343 filter_view=DestroyCacheView(filter_view);
5344 filter_image=DestroyImage(filter_image);
5345 break;
5346 }
anthonycf4e33d2012-06-08 07:33:23 +00005347#endif
cristy4c08aed2011-07-01 19:47:50 +00005348 case IntegerInterpolatePixel:
5349 {
5350 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
5351 if (p == (const Quantum *) NULL)
5352 {
5353 status=MagickFalse;
5354 break;
5355 }
cristy803640d2011-11-17 02:11:32 +00005356 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005357 break;
5358 }
5359 case MeshInterpolatePixel:
5360 {
5361 PointInfo
5362 delta,
5363 luminance;
5364
cristy94ea1632011-07-30 20:40:25 +00005365 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
cristy4c08aed2011-07-01 19:47:50 +00005366 if (p == (const Quantum *) NULL)
5367 {
5368 status=MagickFalse;
5369 break;
5370 }
cristy94ea1632011-07-30 20:40:25 +00005371 delta.x=x-x_offset;
5372 delta.y=y-y_offset;
cristy884f6002011-07-31 00:51:45 +00005373 luminance.x=GetPixelLuminance(image,p)-(double)
cristy94ea1632011-07-30 20:40:25 +00005374 GetPixelLuminance(image,p+3*GetPixelChannels(image));
cristy28474bf2011-09-11 23:32:52 +00005375 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
cristy94ea1632011-07-30 20:40:25 +00005376 GetPixelLuminance(image,p+2*GetPixelChannels(image));
cristy5ce8df82011-07-07 14:52:23 +00005377 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005378 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005379 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5380 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
cristy4c08aed2011-07-01 19:47:50 +00005381 if (fabs(luminance.x) < fabs(luminance.y))
5382 {
5383 /*
5384 Diagonal 0-3 NW-SE.
5385 */
5386 if (delta.x <= delta.y)
5387 {
5388 /*
cristy94ea1632011-07-30 20:40:25 +00005389 Bottom-left triangle (pixel: 2, diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005390 */
5391 delta.y=1.0-delta.y;
5392 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
cristyc58380a2012-06-03 15:12:30 +00005393 gamma=MagickEpsilonReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005394 pixel->red=gamma*MeshInterpolate(&delta,pixels[2].red,
5395 pixels[3].red,pixels[0].red);
5396 pixel->green=gamma*MeshInterpolate(&delta,pixels[2].green,
5397 pixels[3].green,pixels[0].green);
5398 pixel->blue=gamma*MeshInterpolate(&delta,pixels[2].blue,
5399 pixels[3].blue,pixels[0].blue);
cristy4c08aed2011-07-01 19:47:50 +00005400 if (image->colorspace == CMYKColorspace)
5401 pixel->black=gamma*MeshInterpolate(&delta,pixels[2].black,
5402 pixels[3].black,pixels[0].black);
cristy94ea1632011-07-30 20:40:25 +00005403 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005404 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[2].alpha,
5405 pixels[3].alpha,pixels[0].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005406 }
5407 else
5408 {
5409 /*
cristy94ea1632011-07-30 20:40:25 +00005410 Top-right triangle (pixel:1 , diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005411 */
5412 delta.x=1.0-delta.x;
5413 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
cristyc58380a2012-06-03 15:12:30 +00005414 gamma=MagickEpsilonReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005415 pixel->red=gamma*MeshInterpolate(&delta,pixels[1].red,
5416 pixels[0].red,pixels[3].red);
5417 pixel->green=gamma*MeshInterpolate(&delta,pixels[1].green,
5418 pixels[0].green,pixels[3].green);
5419 pixel->blue=gamma*MeshInterpolate(&delta,pixels[1].blue,
5420 pixels[0].blue,pixels[3].blue);
cristy4c08aed2011-07-01 19:47:50 +00005421 if (image->colorspace == CMYKColorspace)
5422 pixel->black=gamma*MeshInterpolate(&delta,pixels[1].black,
5423 pixels[0].black,pixels[3].black);
cristy94ea1632011-07-30 20:40:25 +00005424 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005425 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[1].alpha,
5426 pixels[0].alpha,pixels[3].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005427 }
5428 }
5429 else
5430 {
5431 /*
5432 Diagonal 1-2 NE-SW.
5433 */
5434 if (delta.x <= (1.0-delta.y))
5435 {
5436 /*
cristy94ea1632011-07-30 20:40:25 +00005437 Top-left triangle (pixel: 0, diagonal: 1-2).
cristy4c08aed2011-07-01 19:47:50 +00005438 */
5439 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
cristyc58380a2012-06-03 15:12:30 +00005440 gamma=MagickEpsilonReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005441 pixel->red=gamma*MeshInterpolate(&delta,pixels[0].red,
5442 pixels[1].red,pixels[2].red);
5443 pixel->green=gamma*MeshInterpolate(&delta,pixels[0].green,
5444 pixels[1].green,pixels[2].green);
5445 pixel->blue=gamma*MeshInterpolate(&delta,pixels[0].blue,
5446 pixels[1].blue,pixels[2].blue);
cristy4c08aed2011-07-01 19:47:50 +00005447 if (image->colorspace == CMYKColorspace)
5448 pixel->black=gamma*MeshInterpolate(&delta,pixels[0].black,
5449 pixels[1].black,pixels[2].black);
cristy94ea1632011-07-30 20:40:25 +00005450 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005451 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[0].alpha,
5452 pixels[1].alpha,pixels[2].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005453 }
5454 else
5455 {
5456 /*
5457 Bottom-right triangle (pixel: 3, diagonal: 1-2).
5458 */
5459 delta.x=1.0-delta.x;
5460 delta.y=1.0-delta.y;
5461 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
cristyc58380a2012-06-03 15:12:30 +00005462 gamma=MagickEpsilonReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005463 pixel->red=gamma*MeshInterpolate(&delta,pixels[3].red,
5464 pixels[2].red,pixels[1].red);
5465 pixel->green=gamma*MeshInterpolate(&delta,pixels[3].green,
5466 pixels[2].green,pixels[1].green);
5467 pixel->blue=gamma*MeshInterpolate(&delta,pixels[3].blue,
5468 pixels[2].blue,pixels[1].blue);
cristy4c08aed2011-07-01 19:47:50 +00005469 if (image->colorspace == CMYKColorspace)
5470 pixel->black=gamma*MeshInterpolate(&delta,pixels[3].black,
5471 pixels[2].black,pixels[1].black);
cristy94ea1632011-07-30 20:40:25 +00005472 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005473 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[3].alpha,
5474 pixels[2].alpha,pixels[1].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005475 }
5476 }
5477 break;
5478 }
anthonycf4e33d2012-06-08 07:33:23 +00005479 case NearestInterpolatePixel:
cristy4c08aed2011-07-01 19:47:50 +00005480 {
anthonycf4e33d2012-06-08 07:33:23 +00005481 x_offset=(ssize_t) floor(x+0.5);
5482 y_offset=(ssize_t) floor(y+0.5);
5483 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00005484 if (p == (const Quantum *) NULL)
5485 {
5486 status=MagickFalse;
5487 break;
5488 }
cristy803640d2011-11-17 02:11:32 +00005489 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005490 break;
5491 }
5492 case SplineInterpolatePixel:
5493 {
5494 MagickRealType
nicolasd32d5e52012-06-12 15:34:10 +00005495 cx[4],
5496 cy[4];
cristy4c08aed2011-07-01 19:47:50 +00005497
5498 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5499 exception);
5500 if (p == (const Quantum *) NULL)
5501 {
5502 status=MagickFalse;
5503 break;
5504 }
anthonycf4e33d2012-06-08 07:33:23 +00005505 for (i=0; i < 16L; i++)
5506 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
nicolasd32d5e52012-06-12 15:34:10 +00005507 SplineWeights((MagickRealType) (x-x_offset),&cx);
5508 SplineWeights((MagickRealType) (y-y_offset),&cy);
5509 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*
5510 pixels[1].red+cx[2]*pixels[2].red+cx[3]*
5511 pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
5512 pixels[5].red+cx[2]*pixels[6].red+cx[3]*
5513 pixels[7].red)+cy[2]*(cx[0]*pixels[8].red+cx[1]*
5514 pixels[9].red+cx[2]*pixels[10].red+cx[3]*
5515 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*
5516 pixels[13].red+cx[2]*pixels[14].red+cx[3]*pixels[15].red));
5517 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*
5518 pixels[1].green+cx[2]*pixels[2].green+cx[3]*
5519 pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+cx[1]*
5520 pixels[5].green+cx[2]*pixels[6].green+cx[3]*
5521 pixels[7].green)+cy[2]*(cx[0]*pixels[8].green+cx[1]*
5522 pixels[9].green+cx[2]*pixels[10].green+cx[3]*
5523 pixels[11].green)+cy[3]*(cx[0]*pixels[12].green+cx[1]*
5524 pixels[13].green+cx[2]*pixels[14].green+cx[3]*pixels[15].green));
5525 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*
5526 pixels[1].blue+cx[2]*pixels[2].blue+cx[3]*
5527 pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]*
5528 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*
5529 pixels[7].blue)+cy[2]*(cx[0]*pixels[8].blue+cx[1]*
5530 pixels[9].blue+cx[2]*pixels[10].blue+cx[3]*
5531 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*
5532 pixels[13].blue+cx[2]*pixels[14].blue+cx[3]*pixels[15].blue));
5533 if (image->colorspace == CMYKColorspace)
5534 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*
5535 pixels[1].black+cx[2]*pixels[2].black+cx[3]*
5536 pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+cx[1]*
5537 pixels[5].black+cx[2]*pixels[6].black+cx[3]*
5538 pixels[7].black)+cy[2]*(cx[0]*pixels[8].black+cx[1]*
5539 pixels[9].black+cx[2]*pixels[10].black+cx[3]*
5540 pixels[11].black)+cy[3]*(cx[0]*pixels[12].black+cx[1]*
5541 pixels[13].black+cx[2]*pixels[14].black+cx[3]*pixels[15].black));
5542 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*
5543 pixels[1].alpha+cx[2]*pixels[2].alpha+cx[3]*
5544 pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+cx[1]*
5545 pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*
5546 pixels[7].alpha)+cy[2]*(cx[0]*pixels[8].alpha+cx[1]*
5547 pixels[9].alpha+cx[2]*pixels[10].alpha+cx[3]*
5548 pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+cx[1]*
5549 pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha));
cristy4c08aed2011-07-01 19:47:50 +00005550 break;
5551 }
5552 }
5553 return(status);
5554}
5555
5556/*
5557%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5558% %
5559% %
5560% %
5561+ I s F u z z y E q u i v a l e n c e P i x e l %
5562% %
5563% %
5564% %
5565%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5566%
5567% IsFuzzyEquivalencePixel() returns MagickTrue if the distance between two
5568% pixels is less than the specified distance in a linear three (or four)u
5569% dimensional color space.
5570%
5571% The format of the IsFuzzyEquivalencePixel method is:
5572%
cristye4a40472011-12-22 02:56:19 +00005573% void IsFuzzyEquivalencePixel(const Image *source,const Quantum *p,
5574% const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005575%
5576% A description of each parameter follows:
5577%
cristye4a40472011-12-22 02:56:19 +00005578% o source: the source image.
cristy4c08aed2011-07-01 19:47:50 +00005579%
5580% o p: Pixel p.
5581%
cristye4a40472011-12-22 02:56:19 +00005582% o destination: the destination image.
5583%
cristy4c08aed2011-07-01 19:47:50 +00005584% o q: Pixel q.
5585%
5586*/
cristye4a40472011-12-22 02:56:19 +00005587MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source,
5588 const Quantum *p,const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005589{
5590 MagickRealType
5591 fuzz,
5592 pixel;
5593
5594 register MagickRealType
5595 distance,
5596 scale;
5597
cristye4a40472011-12-22 02:56:19 +00005598 fuzz=MagickMax(source->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(
5599 destination->fuzz,(MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005600 scale=1.0;
5601 distance=0.0;
cristye4a40472011-12-22 02:56:19 +00005602 if (source->matte != MagickFalse)
cristy4c08aed2011-07-01 19:47:50 +00005603 {
5604 /*
5605 Transparencies are involved - set alpha distance
5606 */
cristy99abff32011-12-24 20:45:16 +00005607 pixel=GetPixelAlpha(source,p)-(MagickRealType)
5608 GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005609 distance=pixel*pixel;
5610 if (distance > fuzz)
5611 return(MagickFalse);
5612 /*
5613 Generate a alpha scaling factor to generate a 4D cone on colorspace
5614 Note that if one color is transparent, distance has no color component.
5615 */
cristye4a40472011-12-22 02:56:19 +00005616 scale=QuantumScale*GetPixelAlpha(source,p);
5617 scale*=QuantumScale*GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005618 if (scale <= MagickEpsilon)
5619 return(MagickTrue);
5620 }
5621 /*
5622 RGB or CMY color cube
5623 */
5624 distance*=3.0; /* rescale appropriately */
5625 fuzz*=3.0;
cristye4a40472011-12-22 02:56:19 +00005626 pixel=GetPixelRed(source,p)-(MagickRealType) GetPixelRed(destination,q);
5627 if ((source->colorspace == HSLColorspace) ||
5628 (source->colorspace == HSBColorspace) ||
5629 (source->colorspace == HWBColorspace))
cristy4c08aed2011-07-01 19:47:50 +00005630 {
5631 /*
5632 Compute an arc distance for hue. It should be a vector angle of
5633 'S'/'W' length with 'L'/'B' forming appropriate cones.
5634 */
5635 if (fabs((double) pixel) > (QuantumRange/2))
5636 pixel-=QuantumRange;
5637 pixel*=2;
5638 }
5639 distance+=scale*pixel*pixel;
5640 if (distance > fuzz)
5641 return(MagickFalse);
cristye4a40472011-12-22 02:56:19 +00005642 pixel=GetPixelGreen(source,p)-(MagickRealType) GetPixelGreen(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005643 distance+=scale*pixel*pixel;
5644 if (distance > fuzz)
5645 return(MagickFalse);
cristye4a40472011-12-22 02:56:19 +00005646 pixel=GetPixelBlue(source,p)-(MagickRealType) GetPixelBlue(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005647 distance+=scale*pixel*pixel;
5648 if (distance > fuzz)
5649 return(MagickFalse);
5650 return(MagickTrue);
5651}
5652
5653/*
5654%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5655% %
5656% %
5657% %
5658+ 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 %
5659% %
5660% %
5661% %
5662%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5663%
5664% IsFuzzyEquivalencePixelInfo() returns true if the distance between two
5665% colors is less than the specified distance in a linear three (or four)
5666% dimensional color space.
5667%
cristy5f95f4f2011-10-23 01:01:01 +00005668% This implements the equivalent of:
5669% fuzz < sqrt(color_distance^2 * u.a*v.a + alpha_distance^2)
cristy4c08aed2011-07-01 19:47:50 +00005670%
5671% Which produces a multi-dimensional cone for that colorspace along the
5672% transparency vector.
5673%
cristy5f95f4f2011-10-23 01:01:01 +00005674% For example for an RGB:
cristy4c08aed2011-07-01 19:47:50 +00005675% color_distance^2 = ( (u.r-v.r)^2 + (u.g-v.g)^2 + (u.b-v.b)^2 ) / 3
5676%
5677% See http://www.imagemagick.org/Usage/bugs/fuzz_distance/
5678%
5679% Hue colorspace distances need more work. Hue is not a distance, it is an
5680% angle!
5681%
5682% A check that q is in the same color space as p should be made and the
5683% appropriate mapping made. -- Anthony Thyssen 8 December 2010
5684%
5685% The format of the IsFuzzyEquivalencePixelInfo method is:
5686%
5687% MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5688% const PixelInfo *q)
5689%
5690% A description of each parameter follows:
5691%
5692% o p: Pixel p.
5693%
5694% o q: Pixel q.
5695%
5696*/
5697MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5698 const PixelInfo *q)
5699{
5700 MagickRealType
5701 fuzz,
5702 pixel;
5703
5704 register MagickRealType
5705 scale,
5706 distance;
5707
5708 if ((p->fuzz == 0.0) && (q->fuzz == 0.0))
5709 return(IsPixelInfoEquivalent(p,q));
5710 if (p->fuzz == 0.0)
cristy5f95f4f2011-10-23 01:01:01 +00005711 fuzz=MagickMax(q->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(q->fuzz,
5712 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005713 else if (q->fuzz == 0.0)
cristy5f95f4f2011-10-23 01:01:01 +00005714 fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(p->fuzz,
5715 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005716 else
cristy5f95f4f2011-10-23 01:01:01 +00005717 fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(q->fuzz,
5718 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005719 scale=1.0;
5720 distance=0.0;
5721 if ((p->matte != MagickFalse) || (q->matte != MagickFalse))
5722 {
5723 /*
5724 Transparencies are involved - set alpha distance.
5725 */
5726 pixel=(p->matte != MagickFalse ? p->alpha : OpaqueAlpha)-
5727 (q->matte != MagickFalse ? q->alpha : OpaqueAlpha);
5728 distance=pixel*pixel;
5729 if (distance > fuzz)
5730 return(MagickFalse);
5731 /*
5732 Generate a alpha scaling factor to generate a 4D cone on colorspace.
cristy5f95f4f2011-10-23 01:01:01 +00005733 If one color is transparent, distance has no color component.
cristy4c08aed2011-07-01 19:47:50 +00005734 */
5735 if (p->matte != MagickFalse)
5736 scale=(QuantumScale*p->alpha);
5737 if (q->matte != MagickFalse)
5738 scale*=(QuantumScale*q->alpha);
5739 if (scale <= MagickEpsilon )
5740 return(MagickTrue);
5741 }
5742 /*
5743 CMYK create a CMY cube with a multi-dimensional cone toward black.
5744 */
5745 if (p->colorspace == CMYKColorspace)
5746 {
5747 pixel=p->black-q->black;
5748 distance+=pixel*pixel*scale;
5749 if (distance > fuzz)
5750 return(MagickFalse);
5751 scale*=(MagickRealType) (QuantumScale*(QuantumRange-p->black));
5752 scale*=(MagickRealType) (QuantumScale*(QuantumRange-q->black));
5753 }
5754 /*
5755 RGB or CMY color cube.
5756 */
5757 distance*=3.0; /* rescale appropriately */
5758 fuzz*=3.0;
5759 pixel=p->red-q->red;
5760 if ((p->colorspace == HSLColorspace) || (p->colorspace == HSBColorspace) ||
5761 (p->colorspace == HWBColorspace))
5762 {
cristy5f95f4f2011-10-23 01:01:01 +00005763 /*
5764 This calculates a arc distance for hue-- it should be a vector angle
5765 of 'S'/'W' length with 'L'/'B' forming appropriate cones. In other
5766 words this is a hack - Anthony.
cristy4c08aed2011-07-01 19:47:50 +00005767 */
5768 if (fabs((double) pixel) > (QuantumRange/2))
5769 pixel-=QuantumRange;
5770 pixel*=2;
5771 }
5772 distance+=pixel*pixel*scale;
5773 if (distance > fuzz)
5774 return(MagickFalse);
5775 pixel=p->green-q->green;
5776 distance+=pixel*pixel*scale;
5777 if (distance > fuzz)
5778 return(MagickFalse);
5779 pixel=p->blue-q->blue;
5780 distance+=pixel*pixel*scale;
5781 if (distance > fuzz)
5782 return(MagickFalse);
5783 return(MagickTrue);
5784}
5785
5786/*
5787%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5788% %
5789% %
5790% %
cristye2a912b2011-12-05 20:02:07 +00005791% 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 +00005792% %
5793% %
5794% %
5795%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5796%
cristye2a912b2011-12-05 20:02:07 +00005797% SetPixelChannelMapMask() sets the pixel channel map from the specified
5798% channel mask.
cristy2b9582a2011-07-04 17:38:56 +00005799%
cristye2a912b2011-12-05 20:02:07 +00005800% The format of the SetPixelChannelMapMask method is:
cristy2b9582a2011-07-04 17:38:56 +00005801%
cristye2a912b2011-12-05 20:02:07 +00005802% void SetPixelChannelMapMask(Image *image,const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005803%
5804% A description of each parameter follows:
5805%
5806% o image: the image.
5807%
cristydfdb19e2012-03-21 22:22:24 +00005808% o channel_mask: the channel mask.
cristy2b9582a2011-07-04 17:38:56 +00005809%
5810*/
cristye2a912b2011-12-05 20:02:07 +00005811MagickExport void SetPixelChannelMapMask(Image *image,
cristy07a67852011-08-26 13:25:03 +00005812 const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005813{
cristy6a917d62011-08-24 17:31:30 +00005814#define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01)
cristydafd2872011-07-24 22:06:13 +00005815
cristy2b9582a2011-07-04 17:38:56 +00005816 register ssize_t
5817 i;
5818
cristy177e41c2012-04-15 15:08:25 +00005819 if (image->debug != MagickFalse)
5820 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%08x]", \
5821 image->filename,channel_mask); \
cristy3c309812011-11-08 02:40:43 +00005822 image->channel_mask=channel_mask;
cristydafd2872011-07-24 22:06:13 +00005823 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
cristye2a912b2011-12-05 20:02:07 +00005824 {
5825 PixelChannel
5826 channel;
5827
5828 channel=GetPixelChannelMapChannel(image,i);
5829 SetPixelChannelMapTraits(image,channel,
5830 GetChannelBit(channel_mask,channel) == 0 ? CopyPixelTrait :
cristy0bbd87c2011-12-13 19:34:45 +00005831 image->matte == MagickFalse || (channel == AlphaPixelChannel) ?
5832 UpdatePixelTrait : (PixelTrait) (UpdatePixelTrait | BlendPixelTrait));
cristye2a912b2011-12-05 20:02:07 +00005833 }
cristy1685e722011-09-06 00:04:19 +00005834 if (image->storage_class == PseudoClass)
5835 SetPixelChannelMapTraits(image,IndexPixelChannel,CopyPixelTrait);
cristy183a5c72012-01-30 01:40:35 +00005836 if (image->mask != MagickFalse)
cristy10a6c612012-01-29 21:41:05 +00005837 SetPixelChannelMapTraits(image,MaskPixelChannel,CopyPixelTrait);
cristy6dcb9b82011-10-23 23:21:25 +00005838 if (image->debug != MagickFalse)
5839 LogPixelChannels(image);
cristy2b9582a2011-07-04 17:38:56 +00005840}
5841
5842/*
5843%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5844% %
5845% %
5846% %
cristybd5a96c2011-08-21 00:04:26 +00005847% 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 +00005848% %
5849% %
5850% %
5851%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5852%
cristy5f95f4f2011-10-23 01:01:01 +00005853% SetPixelChannelMask() sets the pixel channel mask from the specified channel
5854% mask.
cristy2b9582a2011-07-04 17:38:56 +00005855%
cristybd5a96c2011-08-21 00:04:26 +00005856% The format of the SetPixelChannelMask method is:
cristy2b9582a2011-07-04 17:38:56 +00005857%
cristybd5a96c2011-08-21 00:04:26 +00005858% ChannelType SetPixelChannelMask(Image *image,
5859% const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005860%
5861% A description of each parameter follows:
5862%
5863% o image: the image.
5864%
cristybd5a96c2011-08-21 00:04:26 +00005865% o channel_mask: the channel mask.
5866%
cristy2b9582a2011-07-04 17:38:56 +00005867*/
cristybd5a96c2011-08-21 00:04:26 +00005868MagickExport ChannelType SetPixelChannelMask(Image *image,
5869 const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005870{
cristybd5a96c2011-08-21 00:04:26 +00005871 ChannelType
5872 mask;
cristy222b19c2011-08-04 01:35:11 +00005873
cristybd5a96c2011-08-21 00:04:26 +00005874 mask=image->channel_mask;
5875 image->channel_mask=channel_mask;
cristye2a912b2011-12-05 20:02:07 +00005876 SetPixelChannelMapMask(image,channel_mask);
cristybd5a96c2011-08-21 00:04:26 +00005877 return(mask);
cristy2b9582a2011-07-04 17:38:56 +00005878}
cristy322d07d2012-03-18 21:17:23 +00005879
5880/*
5881%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5882% %
5883% %
5884% %
5885% S e t P i x e l M e t a C h a n n e l s %
5886% %
5887% %
5888% %
5889%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5890%
5891% SetPixelMetaChannels() sets the image meta channels.
5892%
5893% The format of the SetPixelMetaChannels method is:
5894%
5895% MagickBooleanType SetPixelMetaChannels(Image *image,
5896% const size_t number_meta_channels,ExceptionInfo *exception)
5897%
5898% A description of each parameter follows:
5899%
5900% o image: the image.
5901%
5902% o number_meta_channels: the number of meta channels.
5903%
5904% o exception: return any errors or warnings in this structure.
5905%
5906*/
5907MagickExport MagickBooleanType SetPixelMetaChannels(Image *image,
5908 const size_t number_meta_channels,ExceptionInfo *exception)
5909{
5910 image->number_meta_channels=number_meta_channels;
5911 return(SyncImagePixelCache(image,exception));
5912}