blob: 8a7624e0e0386f1a76676d1c2491ac07d23eaf2e [file] [log] [blame]
cristy4c08aed2011-07-01 19:47:50 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% PPPP IIIII X X EEEEE L %
7% P P I X X E L %
8% PPPP I X EEE L %
9% P I X X E L %
10% P IIIII X X EEEEE LLLLL %
11% %
12% MagickCore Methods to Import/Export Pixels %
13% %
14% Software Design %
15% John Cristy %
16% October 1998 %
17% %
18% %
cristy45ef08f2012-12-07 13:13:34 +000019% Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization %
cristy4c08aed2011-07-01 19:47:50 +000020% dedicated to making software imaging solutions freely available. %
21% %
22% You may not use this file except in compliance with the License. You may %
23% obtain a copy of the License at %
24% %
25% http://www.imagemagick.org/script/license.php %
26% %
27% Unless required by applicable law or agreed to in writing, software %
28% distributed under the License is distributed on an "AS IS" BASIS, %
29% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30% See the License for the specific language governing permissions and %
31% limitations under the License. %
32% %
33%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34%
35%
36*/
37
38/*
39 Include declarations.
40*/
41#include "MagickCore/studio.h"
42#include "MagickCore/property.h"
43#include "MagickCore/blob.h"
44#include "MagickCore/blob-private.h"
cristy322d07d2012-03-18 21:17:23 +000045#include "MagickCore/cache-private.h"
cristy4c08aed2011-07-01 19:47:50 +000046#include "MagickCore/color-private.h"
47#include "MagickCore/draw.h"
48#include "MagickCore/exception.h"
49#include "MagickCore/exception-private.h"
50#include "MagickCore/cache.h"
51#include "MagickCore/constitute.h"
52#include "MagickCore/delegate.h"
53#include "MagickCore/geometry.h"
54#include "MagickCore/image-private.h"
55#include "MagickCore/list.h"
56#include "MagickCore/magick.h"
57#include "MagickCore/memory_.h"
58#include "MagickCore/monitor.h"
59#include "MagickCore/option.h"
60#include "MagickCore/pixel.h"
61#include "MagickCore/pixel-accessor.h"
cristy380a11c2012-06-02 15:15:22 +000062#include "MagickCore/pixel-private.h"
cristy4c08aed2011-07-01 19:47:50 +000063#include "MagickCore/quantum.h"
64#include "MagickCore/quantum-private.h"
65#include "MagickCore/resource_.h"
66#include "MagickCore/semaphore.h"
67#include "MagickCore/statistic.h"
68#include "MagickCore/stream.h"
69#include "MagickCore/string_.h"
70#include "MagickCore/transform.h"
71#include "MagickCore/utility.h"
72
cristy146a62b2011-10-23 23:40:46 +000073#define LogPixelChannels(image) \
74{ \
75 register ssize_t \
76 i; \
77 \
78 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%.20g]", \
79 image->filename,(double) image->number_channels); \
80 for (i=0; i < (ssize_t) image->number_channels; i++) \
81 { \
82 char \
83 traits[MaxTextExtent]; \
84 \
85 const char \
cristy46795722011-12-10 23:56:57 +000086 *name; \
87 \
88 PixelChannel \
89 channel; \
cristy146a62b2011-10-23 23:40:46 +000090 \
cristycf1296e2012-08-26 23:40:49 +000091 switch (GetPixelChannelChannel(image,i)) \
cristy146a62b2011-10-23 23:40:46 +000092 { \
93 case RedPixelChannel: \
94 { \
cristy46795722011-12-10 23:56:57 +000095 name="red"; \
cristy146a62b2011-10-23 23:40:46 +000096 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +000097 name="cyan"; \
cristy146a62b2011-10-23 23:40:46 +000098 if (image->colorspace == GRAYColorspace) \
cristy46795722011-12-10 23:56:57 +000099 name="gray"; \
cristy146a62b2011-10-23 23:40:46 +0000100 break; \
101 } \
102 case GreenPixelChannel: \
103 { \
cristy46795722011-12-10 23:56:57 +0000104 name="green"; \
cristy146a62b2011-10-23 23:40:46 +0000105 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +0000106 name="magenta"; \
cristy146a62b2011-10-23 23:40:46 +0000107 break; \
108 } \
109 case BluePixelChannel: \
110 { \
cristy46795722011-12-10 23:56:57 +0000111 name="blue"; \
cristy146a62b2011-10-23 23:40:46 +0000112 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +0000113 name="yellow"; \
cristy146a62b2011-10-23 23:40:46 +0000114 break; \
115 } \
116 case BlackPixelChannel: \
117 { \
cristy46795722011-12-10 23:56:57 +0000118 name="black"; \
cristy146a62b2011-10-23 23:40:46 +0000119 if (image->storage_class == PseudoClass) \
cristy46795722011-12-10 23:56:57 +0000120 name="index"; \
cristy146a62b2011-10-23 23:40:46 +0000121 break; \
122 } \
cristye2a912b2011-12-05 20:02:07 +0000123 case IndexPixelChannel: \
124 { \
cristy46795722011-12-10 23:56:57 +0000125 name="index"; \
cristye2a912b2011-12-05 20:02:07 +0000126 break; \
127 } \
cristy146a62b2011-10-23 23:40:46 +0000128 case AlphaPixelChannel: \
129 { \
cristy46795722011-12-10 23:56:57 +0000130 name="alpha"; \
cristy146a62b2011-10-23 23:40:46 +0000131 break; \
132 } \
133 case MaskPixelChannel: \
134 { \
cristy46795722011-12-10 23:56:57 +0000135 name="mask"; \
cristy146a62b2011-10-23 23:40:46 +0000136 break; \
137 } \
cristye2a912b2011-12-05 20:02:07 +0000138 case MetaPixelChannel: \
cristy146a62b2011-10-23 23:40:46 +0000139 { \
cristy46795722011-12-10 23:56:57 +0000140 name="meta"; \
cristye2a912b2011-12-05 20:02:07 +0000141 break; \
cristy146a62b2011-10-23 23:40:46 +0000142 } \
cristye2a912b2011-12-05 20:02:07 +0000143 default: \
cristy46795722011-12-10 23:56:57 +0000144 name="undefined"; \
cristy146a62b2011-10-23 23:40:46 +0000145 } \
cristycf1296e2012-08-26 23:40:49 +0000146 channel=GetPixelChannelChannel(image,i); \
cristy146a62b2011-10-23 23:40:46 +0000147 *traits='\0'; \
cristycf1296e2012-08-26 23:40:49 +0000148 if ((GetPixelChannelTraits(image,channel) & UpdatePixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000149 (void) ConcatenateMagickString(traits,"update,",MaxTextExtent); \
cristycf1296e2012-08-26 23:40:49 +0000150 if ((GetPixelChannelTraits(image,channel) & BlendPixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000151 (void) ConcatenateMagickString(traits,"blend,",MaxTextExtent); \
cristycf1296e2012-08-26 23:40:49 +0000152 if ((GetPixelChannelTraits(image,channel) & CopyPixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000153 (void) ConcatenateMagickString(traits,"copy,",MaxTextExtent); \
154 if (*traits == '\0') \
155 (void) ConcatenateMagickString(traits,"undefined,",MaxTextExtent); \
156 traits[strlen(traits)-1]='\0'; \
157 (void) LogMagickEvent(PixelEvent,GetMagickModule()," %.20g: %s (%s)", \
cristy46795722011-12-10 23:56:57 +0000158 (double) i,name,traits); \
cristy146a62b2011-10-23 23:40:46 +0000159 } \
160}
161
162/*
cristy4c08aed2011-07-01 19:47:50 +0000163%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164% %
165% %
166% %
cristyed231572011-07-14 02:18:59 +0000167+ A c q u i r e P i x e l C h a n n e l M a p %
cristy4c08aed2011-07-01 19:47:50 +0000168% %
169% %
170% %
171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172%
cristyed231572011-07-14 02:18:59 +0000173% AcquirePixelChannelMap() acquires a pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000174%
cristyed231572011-07-14 02:18:59 +0000175% The format of the AcquirePixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000176%
cristybd5a96c2011-08-21 00:04:26 +0000177% PixelChannelMap *AcquirePixelChannelMap(void)
cristy4c08aed2011-07-01 19:47:50 +0000178%
179*/
cristybd5a96c2011-08-21 00:04:26 +0000180MagickExport PixelChannelMap *AcquirePixelChannelMap(void)
cristy4c08aed2011-07-01 19:47:50 +0000181{
cristyed231572011-07-14 02:18:59 +0000182 PixelChannelMap
cristybd5a96c2011-08-21 00:04:26 +0000183 *channel_map;
cristy4c08aed2011-07-01 19:47:50 +0000184
185 register ssize_t
186 i;
187
cristybd5a96c2011-08-21 00:04:26 +0000188 channel_map=(PixelChannelMap *) AcquireQuantumMemory(MaxPixelChannels,
189 sizeof(*channel_map));
190 if (channel_map == (PixelChannelMap *) NULL)
cristy4c08aed2011-07-01 19:47:50 +0000191 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristybd5a96c2011-08-21 00:04:26 +0000192 (void) ResetMagickMemory(channel_map,0,MaxPixelChannels*sizeof(*channel_map));
193 for (i=0; i < MaxPixelChannels; i++)
194 channel_map[i].channel=(PixelChannel) i;
cristyed231572011-07-14 02:18:59 +0000195 return(channel_map);
cristy4c08aed2011-07-01 19:47:50 +0000196}
197
198/*
199%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
200% %
201% %
202% %
cristyed231572011-07-14 02:18:59 +0000203+ C l o n e P i x e l C h a n n e l M a p %
cristy4c08aed2011-07-01 19:47:50 +0000204% %
205% %
206% %
207%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
208%
cristyed231572011-07-14 02:18:59 +0000209% ClonePixelChannelMap() clones a pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000210%
cristyed231572011-07-14 02:18:59 +0000211% The format of the ClonePixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000212%
cristybd5a96c2011-08-21 00:04:26 +0000213% PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000214%
215% A description of each parameter follows:
216%
cristyed231572011-07-14 02:18:59 +0000217% o channel_map: the pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000218%
219*/
cristybd5a96c2011-08-21 00:04:26 +0000220MagickExport PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000221{
cristyed231572011-07-14 02:18:59 +0000222 PixelChannelMap
cristybd5a96c2011-08-21 00:04:26 +0000223 *clone_map;
cristy4c08aed2011-07-01 19:47:50 +0000224
cristybd5a96c2011-08-21 00:04:26 +0000225 assert(channel_map != (PixelChannelMap *) NULL);
cristyed231572011-07-14 02:18:59 +0000226 clone_map=AcquirePixelChannelMap();
cristybd5a96c2011-08-21 00:04:26 +0000227 if (clone_map == (PixelChannelMap *) NULL)
228 return((PixelChannelMap *) NULL);
229 (void) CopyMagickMemory(clone_map,channel_map,MaxPixelChannels*
230 sizeof(*channel_map));
cristy4c08aed2011-07-01 19:47:50 +0000231 return(clone_map);
232}
233
234/*
235%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
236% %
237% %
238% %
239+ C l o n e P i x e l I n f o %
240% %
241% %
242% %
243%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244%
245% ClonePixelInfo() makes a duplicate of the given pixel info structure, or if
246% pixel info is NULL, a new one.
247%
248% The format of the ClonePixelInfo method is:
249%
250% PixelInfo *ClonePixelInfo(const PixelInfo *pixel_info)
251%
252% A description of each parameter follows:
253%
254% o pixel_info: the pixel info.
255%
256*/
257MagickExport PixelInfo *ClonePixelInfo(const PixelInfo *pixel)
258{
259 PixelInfo
260 *pixel_info;
261
cristya64b85d2011-09-14 01:02:31 +0000262 pixel_info=(PixelInfo *) AcquireQuantumMemory(1,sizeof(*pixel_info));
cristy4c08aed2011-07-01 19:47:50 +0000263 if (pixel_info == (PixelInfo *) NULL)
264 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
265 *pixel_info=(*pixel);
266 return(pixel_info);
267}
268
269/*
270%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271% %
272% %
273% %
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
cristy2dc655d2012-07-05 13:16:28 +0000355static void ExportCharPixel(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
cristy2dc655d2012-07-05 13:16:28 +0000561static void ExportDoublePixel(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
cristy2dc655d2012-07-05 13:16:28 +0000768static void ExportFloatPixel(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
cristy2dc655d2012-07-05 13:16:28 +0000974static void ExportLongPixel(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
cristy2dc655d2012-07-05 13:16:28 +00001180static void ExportLongLongPixel(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
cristy2dc655d2012-07-05 13:16:28 +00001386static void ExportQuantumPixel(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
cristy2dc655d2012-07-05 13:16:28 +00001595static void ExportShortPixel(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
cristy2dc655d2012-07-05 13:16:28 +00001801MagickExport MagickBooleanType ExportImagePixels(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;
cristy8a46d822012-08-28 23:32:39 +00002009 pixel->alpha_trait=UndefinedPixelTrait;
cristy4c08aed2011-07-01 19:47:50 +00002010 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;
cristya19f1d72012-08-07 18:24:38 +00002016 pixel->alpha=(double) OpaqueAlpha;
cristy4c08aed2011-07-01 19:47:50 +00002017 pixel->index=0.0;
2018 if (image == (const Image *) NULL)
2019 return;
2020 pixel->storage_class=image->storage_class;
2021 pixel->colorspace=image->colorspace;
cristy8a46d822012-08-28 23:32:39 +00002022 pixel->alpha_trait=image->alpha_trait;
cristy4c08aed2011-07-01 19:47:50 +00002023 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 {
cristy8cd03c32012-07-07 18:57:59 +00002372 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002373 p++;
cristy8cd03c32012-07-07 18:57:59 +00002374 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002375 p++;
cristy8cd03c32012-07-07 18:57:59 +00002376 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002377 p++;
2378 q+=GetPixelChannels(image);
2379 }
2380 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2381 break;
2382 }
2383 return;
2384 }
2385 if (LocaleCompare(map,"BGRA") == 0)
2386 {
cristycafe0412012-01-10 13:29:58 +00002387 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002388 {
cristycafe0412012-01-10 13:29:58 +00002389 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002390 if (q == (Quantum *) NULL)
2391 break;
cristycafe0412012-01-10 13:29:58 +00002392 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002393 {
cristy8cd03c32012-07-07 18:57:59 +00002394 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002395 p++;
cristy8cd03c32012-07-07 18:57:59 +00002396 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002397 p++;
cristy8cd03c32012-07-07 18:57:59 +00002398 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002399 p++;
cristy8cd03c32012-07-07 18:57:59 +00002400 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002401 p++;
2402 q+=GetPixelChannels(image);
2403 }
2404 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2405 break;
2406 }
2407 return;
2408 }
2409 if (LocaleCompare(map,"BGRP") == 0)
2410 {
cristycafe0412012-01-10 13:29:58 +00002411 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002412 {
cristycafe0412012-01-10 13:29:58 +00002413 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002414 if (q == (Quantum *) NULL)
2415 break;
cristycafe0412012-01-10 13:29:58 +00002416 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002417 {
cristy8cd03c32012-07-07 18:57:59 +00002418 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002419 p++;
cristy8cd03c32012-07-07 18:57:59 +00002420 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002421 p++;
cristy8cd03c32012-07-07 18:57:59 +00002422 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002423 p++;
2424 p++;
2425 q+=GetPixelChannels(image);
2426 }
2427 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2428 break;
2429 }
2430 return;
2431 }
2432 if (LocaleCompare(map,"I") == 0)
2433 {
cristycafe0412012-01-10 13:29:58 +00002434 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002435 {
cristycafe0412012-01-10 13:29:58 +00002436 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002437 if (q == (Quantum *) NULL)
2438 break;
cristycafe0412012-01-10 13:29:58 +00002439 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002440 {
cristy8cd03c32012-07-07 18:57:59 +00002441 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002442 p++;
2443 q+=GetPixelChannels(image);
2444 }
2445 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2446 break;
2447 }
2448 return;
2449 }
2450 if (LocaleCompare(map,"RGB") == 0)
2451 {
cristycafe0412012-01-10 13:29:58 +00002452 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002453 {
cristycafe0412012-01-10 13:29:58 +00002454 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002455 if (q == (Quantum *) NULL)
2456 break;
cristycafe0412012-01-10 13:29:58 +00002457 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002458 {
cristy8cd03c32012-07-07 18:57:59 +00002459 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002460 p++;
cristy8cd03c32012-07-07 18:57:59 +00002461 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002462 p++;
cristy8cd03c32012-07-07 18:57:59 +00002463 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002464 p++;
2465 q+=GetPixelChannels(image);
2466 }
2467 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2468 break;
2469 }
2470 return;
2471 }
2472 if (LocaleCompare(map,"RGBA") == 0)
2473 {
cristycafe0412012-01-10 13:29:58 +00002474 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002475 {
cristycafe0412012-01-10 13:29:58 +00002476 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002477 if (q == (Quantum *) NULL)
2478 break;
cristycafe0412012-01-10 13:29:58 +00002479 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002480 {
cristy8cd03c32012-07-07 18:57:59 +00002481 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002482 p++;
cristy8cd03c32012-07-07 18:57:59 +00002483 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002484 p++;
cristy8cd03c32012-07-07 18:57:59 +00002485 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002486 p++;
cristy8cd03c32012-07-07 18:57:59 +00002487 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002488 p++;
2489 q+=GetPixelChannels(image);
2490 }
2491 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2492 break;
2493 }
2494 return;
2495 }
2496 if (LocaleCompare(map,"RGBP") == 0)
2497 {
cristycafe0412012-01-10 13:29:58 +00002498 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002499 {
cristycafe0412012-01-10 13:29:58 +00002500 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002501 if (q == (Quantum *) NULL)
2502 break;
cristycafe0412012-01-10 13:29:58 +00002503 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002504 {
cristy8cd03c32012-07-07 18:57:59 +00002505 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002506 p++;
cristy8cd03c32012-07-07 18:57:59 +00002507 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002508 p++;
cristy8cd03c32012-07-07 18:57:59 +00002509 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002510 p++;
2511 q+=GetPixelChannels(image);
2512 }
2513 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2514 break;
2515 }
2516 return;
2517 }
cristy14d71292012-05-20 16:48:13 +00002518 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00002519 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002520 {
cristycafe0412012-01-10 13:29:58 +00002521 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002522 if (q == (Quantum *) NULL)
2523 break;
cristycafe0412012-01-10 13:29:58 +00002524 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002525 {
2526 register ssize_t
2527 i;
2528
cristy14d71292012-05-20 16:48:13 +00002529 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00002530 {
2531 switch (quantum_map[i])
2532 {
2533 case RedQuantum:
2534 case CyanQuantum:
2535 {
cristy8cd03c32012-07-07 18:57:59 +00002536 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002537 break;
2538 }
2539 case GreenQuantum:
2540 case MagentaQuantum:
2541 {
cristy8cd03c32012-07-07 18:57:59 +00002542 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002543 break;
2544 }
2545 case BlueQuantum:
2546 case YellowQuantum:
2547 {
cristy8cd03c32012-07-07 18:57:59 +00002548 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002549 break;
2550 }
2551 case AlphaQuantum:
2552 {
cristy8cd03c32012-07-07 18:57:59 +00002553 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002554 break;
2555 }
2556 case OpacityQuantum:
2557 {
cristy8cd03c32012-07-07 18:57:59 +00002558 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002559 break;
2560 }
2561 case BlackQuantum:
2562 {
cristy8cd03c32012-07-07 18:57:59 +00002563 SetPixelBlack(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002564 break;
2565 }
2566 case IndexQuantum:
2567 {
cristy8cd03c32012-07-07 18:57:59 +00002568 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002569 break;
2570 }
2571 default:
2572 break;
2573 }
2574 p++;
2575 }
2576 q+=GetPixelChannels(image);
2577 }
2578 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2579 break;
2580 }
2581}
2582
cristycafe0412012-01-10 13:29:58 +00002583static void ImportFloatPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002584 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2585 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002586{
2587 register const float
2588 *restrict p;
2589
2590 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002591 *restrict q;
cristye5370942012-01-06 03:49:31 +00002592
2593 register ssize_t
2594 x;
2595
cristy14d71292012-05-20 16:48:13 +00002596 size_t
2597 length;
2598
cristye5370942012-01-06 03:49:31 +00002599 ssize_t
2600 y;
2601
2602 p=(const float *) pixels;
2603 if (LocaleCompare(map,"BGR") == 0)
2604 {
cristycafe0412012-01-10 13:29:58 +00002605 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002606 {
cristycafe0412012-01-10 13:29:58 +00002607 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002608 if (q == (Quantum *) NULL)
2609 break;
cristycafe0412012-01-10 13:29:58 +00002610 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002611 {
cristy8cd03c32012-07-07 18:57:59 +00002612 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002613 p++;
cristy8cd03c32012-07-07 18:57:59 +00002614 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002615 p++;
cristy8cd03c32012-07-07 18:57:59 +00002616 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002617 p++;
2618 q+=GetPixelChannels(image);
2619 }
2620 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2621 break;
2622 }
2623 return;
2624 }
2625 if (LocaleCompare(map,"BGRA") == 0)
2626 {
cristycafe0412012-01-10 13:29:58 +00002627 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002628 {
cristycafe0412012-01-10 13:29:58 +00002629 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002630 if (q == (Quantum *) NULL)
2631 break;
cristycafe0412012-01-10 13:29:58 +00002632 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002633 {
cristy8cd03c32012-07-07 18:57:59 +00002634 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002635 p++;
cristy8cd03c32012-07-07 18:57:59 +00002636 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002637 p++;
cristy8cd03c32012-07-07 18:57:59 +00002638 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002639 p++;
cristy8cd03c32012-07-07 18:57:59 +00002640 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002641 p++;
2642 q+=GetPixelChannels(image);
2643 }
2644 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2645 break;
2646 }
2647 return;
2648 }
2649 if (LocaleCompare(map,"BGRP") == 0)
2650 {
cristycafe0412012-01-10 13:29:58 +00002651 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002652 {
cristycafe0412012-01-10 13:29:58 +00002653 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002654 if (q == (Quantum *) NULL)
2655 break;
cristycafe0412012-01-10 13:29:58 +00002656 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002657 {
cristy8cd03c32012-07-07 18:57:59 +00002658 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002659 p++;
cristy8cd03c32012-07-07 18:57:59 +00002660 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002661 p++;
cristy8cd03c32012-07-07 18:57:59 +00002662 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002663 p++;
2664 p++;
2665 q+=GetPixelChannels(image);
2666 }
2667 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2668 break;
2669 }
2670 return;
2671 }
2672 if (LocaleCompare(map,"I") == 0)
2673 {
cristycafe0412012-01-10 13:29:58 +00002674 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002675 {
cristycafe0412012-01-10 13:29:58 +00002676 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002677 if (q == (Quantum *) NULL)
2678 break;
cristycafe0412012-01-10 13:29:58 +00002679 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002680 {
cristy8cd03c32012-07-07 18:57:59 +00002681 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002682 p++;
2683 q+=GetPixelChannels(image);
2684 }
2685 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2686 break;
2687 }
2688 return;
2689 }
2690 if (LocaleCompare(map,"RGB") == 0)
2691 {
cristycafe0412012-01-10 13:29:58 +00002692 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002693 {
cristycafe0412012-01-10 13:29:58 +00002694 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002695 if (q == (Quantum *) NULL)
2696 break;
cristycafe0412012-01-10 13:29:58 +00002697 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002698 {
cristy8cd03c32012-07-07 18:57:59 +00002699 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002700 p++;
cristy8cd03c32012-07-07 18:57:59 +00002701 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002702 p++;
cristy8cd03c32012-07-07 18:57:59 +00002703 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002704 p++;
2705 q+=GetPixelChannels(image);
2706 }
2707 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2708 break;
2709 }
2710 return;
2711 }
2712 if (LocaleCompare(map,"RGBA") == 0)
2713 {
cristycafe0412012-01-10 13:29:58 +00002714 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002715 {
cristycafe0412012-01-10 13:29:58 +00002716 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002717 if (q == (Quantum *) NULL)
2718 break;
cristycafe0412012-01-10 13:29:58 +00002719 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002720 {
cristy8cd03c32012-07-07 18:57:59 +00002721 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002722 p++;
cristy8cd03c32012-07-07 18:57:59 +00002723 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002724 p++;
cristy8cd03c32012-07-07 18:57:59 +00002725 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002726 p++;
cristy8cd03c32012-07-07 18:57:59 +00002727 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002728 p++;
2729 q+=GetPixelChannels(image);
2730 }
2731 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2732 break;
2733 }
2734 return;
2735 }
2736 if (LocaleCompare(map,"RGBP") == 0)
2737 {
cristycafe0412012-01-10 13:29:58 +00002738 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002739 {
cristycafe0412012-01-10 13:29:58 +00002740 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002741 if (q == (Quantum *) NULL)
2742 break;
cristycafe0412012-01-10 13:29:58 +00002743 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002744 {
cristy8cd03c32012-07-07 18:57:59 +00002745 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002746 p++;
cristy8cd03c32012-07-07 18:57:59 +00002747 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002748 p++;
cristy8cd03c32012-07-07 18:57:59 +00002749 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002750 p++;
2751 q+=GetPixelChannels(image);
2752 }
2753 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2754 break;
2755 }
2756 return;
2757 }
cristy14d71292012-05-20 16:48:13 +00002758 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00002759 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002760 {
cristycafe0412012-01-10 13:29:58 +00002761 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002762 if (q == (Quantum *) NULL)
2763 break;
cristycafe0412012-01-10 13:29:58 +00002764 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002765 {
2766 register ssize_t
2767 i;
2768
cristy14d71292012-05-20 16:48:13 +00002769 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00002770 {
2771 switch (quantum_map[i])
2772 {
2773 case RedQuantum:
2774 case CyanQuantum:
2775 {
cristy8cd03c32012-07-07 18:57:59 +00002776 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002777 break;
2778 }
2779 case GreenQuantum:
2780 case MagentaQuantum:
2781 {
cristy8cd03c32012-07-07 18:57:59 +00002782 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002783 break;
2784 }
2785 case BlueQuantum:
2786 case YellowQuantum:
2787 {
cristy8cd03c32012-07-07 18:57:59 +00002788 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002789 break;
2790 }
2791 case AlphaQuantum:
2792 {
cristy8cd03c32012-07-07 18:57:59 +00002793 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002794 break;
2795 }
2796 case OpacityQuantum:
2797 {
cristy8cd03c32012-07-07 18:57:59 +00002798 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002799 break;
2800 }
2801 case BlackQuantum:
2802 {
cristy8cd03c32012-07-07 18:57:59 +00002803 SetPixelBlack(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002804 break;
2805 }
2806 case IndexQuantum:
2807 {
cristy8cd03c32012-07-07 18:57:59 +00002808 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002809 break;
2810 }
2811 default:
2812 break;
2813 }
2814 p++;
2815 }
2816 q+=GetPixelChannels(image);
2817 }
2818 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2819 break;
2820 }
2821}
2822
cristycafe0412012-01-10 13:29:58 +00002823static void ImportLongPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002824 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2825 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002826{
2827 register const unsigned int
2828 *restrict p;
2829
2830 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002831 *restrict q;
cristye5370942012-01-06 03:49:31 +00002832
2833 register ssize_t
2834 x;
2835
cristy14d71292012-05-20 16:48:13 +00002836 size_t
2837 length;
2838
cristye5370942012-01-06 03:49:31 +00002839 ssize_t
2840 y;
2841
2842 p=(const unsigned int *) pixels;
2843 if (LocaleCompare(map,"BGR") == 0)
2844 {
cristycafe0412012-01-10 13:29:58 +00002845 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002846 {
cristycafe0412012-01-10 13:29:58 +00002847 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002848 if (q == (Quantum *) NULL)
2849 break;
cristycafe0412012-01-10 13:29:58 +00002850 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002851 {
2852 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2853 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2854 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2855 q+=GetPixelChannels(image);
2856 }
2857 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2858 break;
2859 }
2860 return;
2861 }
2862 if (LocaleCompare(map,"BGRA") == 0)
2863 {
cristycafe0412012-01-10 13:29:58 +00002864 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002865 {
cristycafe0412012-01-10 13:29:58 +00002866 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002867 if (q == (Quantum *) NULL)
2868 break;
cristycafe0412012-01-10 13:29:58 +00002869 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002870 {
2871 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2872 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2873 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2874 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
2875 q+=GetPixelChannels(image);
2876 }
2877 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2878 break;
2879 }
2880 return;
2881 }
2882 if (LocaleCompare(map,"BGRP") == 0)
2883 {
cristycafe0412012-01-10 13:29:58 +00002884 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002885 {
cristycafe0412012-01-10 13:29:58 +00002886 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002887 if (q == (Quantum *) NULL)
2888 break;
cristycafe0412012-01-10 13:29:58 +00002889 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002890 {
2891 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2892 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2893 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2894 p++;
2895 q+=GetPixelChannels(image);
2896 }
2897 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2898 break;
2899 }
2900 return;
2901 }
2902 if (LocaleCompare(map,"I") == 0)
2903 {
cristycafe0412012-01-10 13:29:58 +00002904 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002905 {
cristycafe0412012-01-10 13:29:58 +00002906 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002907 if (q == (Quantum *) NULL)
2908 break;
cristycafe0412012-01-10 13:29:58 +00002909 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002910 {
2911 SetPixelGray(image,ScaleLongToQuantum(*p++),q);
2912 q+=GetPixelChannels(image);
2913 }
2914 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2915 break;
2916 }
2917 return;
2918 }
2919 if (LocaleCompare(map,"RGB") == 0)
2920 {
cristycafe0412012-01-10 13:29:58 +00002921 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002922 {
cristycafe0412012-01-10 13:29:58 +00002923 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002924 if (q == (Quantum *) NULL)
2925 break;
cristycafe0412012-01-10 13:29:58 +00002926 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002927 {
2928 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2929 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2930 SetPixelBlue(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,"RGBA") == 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 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2948 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2949 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2950 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
2951 q+=GetPixelChannels(image);
2952 }
2953 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2954 break;
2955 }
2956 return;
2957 }
2958 if (LocaleCompare(map,"RGBP") == 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 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2968 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2969 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2970 p++;
2971 q+=GetPixelChannels(image);
2972 }
2973 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2974 break;
2975 }
2976 return;
2977 }
cristy14d71292012-05-20 16:48:13 +00002978 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00002979 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002980 {
cristycafe0412012-01-10 13:29:58 +00002981 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002982 if (q == (Quantum *) NULL)
2983 break;
cristycafe0412012-01-10 13:29:58 +00002984 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002985 {
2986 register ssize_t
2987 i;
2988
cristy14d71292012-05-20 16:48:13 +00002989 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00002990 {
2991 switch (quantum_map[i])
2992 {
2993 case RedQuantum:
2994 case CyanQuantum:
2995 {
2996 SetPixelRed(image,ScaleLongToQuantum(*p),q);
2997 break;
2998 }
2999 case GreenQuantum:
3000 case MagentaQuantum:
3001 {
3002 SetPixelGreen(image,ScaleLongToQuantum(*p),q);
3003 break;
3004 }
3005 case BlueQuantum:
3006 case YellowQuantum:
3007 {
3008 SetPixelBlue(image,ScaleLongToQuantum(*p),q);
3009 break;
3010 }
3011 case AlphaQuantum:
3012 {
3013 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3014 break;
3015 }
3016 case OpacityQuantum:
3017 {
3018 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3019 break;
3020 }
3021 case BlackQuantum:
3022 {
3023 SetPixelBlack(image,ScaleLongToQuantum(*p),q);
3024 break;
3025 }
3026 case IndexQuantum:
3027 {
3028 SetPixelGray(image,ScaleLongToQuantum(*p),q);
3029 break;
3030 }
3031 default:
3032 break;
3033 }
3034 p++;
3035 }
3036 q+=GetPixelChannels(image);
3037 }
3038 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3039 break;
3040 }
3041}
3042
cristycafe0412012-01-10 13:29:58 +00003043static void ImportLongLongPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003044 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3045 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003046{
cristyb13e12a2012-01-06 21:48:27 +00003047 register const MagickSizeType
cristye5370942012-01-06 03:49:31 +00003048 *restrict p;
3049
3050 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003051 *restrict q;
cristye5370942012-01-06 03:49:31 +00003052
3053 register ssize_t
3054 x;
3055
cristy14d71292012-05-20 16:48:13 +00003056 size_t
3057 length;
3058
cristye5370942012-01-06 03:49:31 +00003059 ssize_t
3060 y;
3061
cristyb13e12a2012-01-06 21:48:27 +00003062 p=(const MagickSizeType *) pixels;
cristye5370942012-01-06 03:49:31 +00003063 if (LocaleCompare(map,"BGR") == 0)
3064 {
cristycafe0412012-01-10 13:29:58 +00003065 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003066 {
cristycafe0412012-01-10 13:29:58 +00003067 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003068 if (q == (Quantum *) NULL)
3069 break;
cristycafe0412012-01-10 13:29:58 +00003070 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003071 {
cristyb13e12a2012-01-06 21:48:27 +00003072 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3073 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3074 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003075 q+=GetPixelChannels(image);
3076 }
3077 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3078 break;
3079 }
3080 return;
3081 }
3082 if (LocaleCompare(map,"BGRA") == 0)
3083 {
cristycafe0412012-01-10 13:29:58 +00003084 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003085 {
cristycafe0412012-01-10 13:29:58 +00003086 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003087 if (q == (Quantum *) NULL)
3088 break;
cristycafe0412012-01-10 13:29:58 +00003089 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003090 {
cristyb13e12a2012-01-06 21:48:27 +00003091 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3092 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3093 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3094 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003095 q+=GetPixelChannels(image);
3096 }
3097 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3098 break;
3099 }
3100 return;
3101 }
3102 if (LocaleCompare(map,"BGRP") == 0)
3103 {
cristycafe0412012-01-10 13:29:58 +00003104 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003105 {
cristycafe0412012-01-10 13:29:58 +00003106 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003107 if (q == (Quantum *) NULL)
3108 break;
cristycafe0412012-01-10 13:29:58 +00003109 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003110 {
cristyb13e12a2012-01-06 21:48:27 +00003111 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3112 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3113 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003114 p++;
3115 q+=GetPixelChannels(image);
3116 }
3117 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3118 break;
3119 }
3120 return;
3121 }
3122 if (LocaleCompare(map,"I") == 0)
3123 {
cristycafe0412012-01-10 13:29:58 +00003124 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003125 {
cristycafe0412012-01-10 13:29:58 +00003126 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003127 if (q == (Quantum *) NULL)
3128 break;
cristycafe0412012-01-10 13:29:58 +00003129 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003130 {
cristyb13e12a2012-01-06 21:48:27 +00003131 SetPixelGray(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003132 q+=GetPixelChannels(image);
3133 }
3134 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3135 break;
3136 }
3137 return;
3138 }
3139 if (LocaleCompare(map,"RGB") == 0)
3140 {
cristycafe0412012-01-10 13:29:58 +00003141 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003142 {
cristycafe0412012-01-10 13:29:58 +00003143 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003144 if (q == (Quantum *) NULL)
3145 break;
cristycafe0412012-01-10 13:29:58 +00003146 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003147 {
cristyb13e12a2012-01-06 21:48:27 +00003148 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3149 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3150 SetPixelBlue(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,"RGBA") == 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 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3168 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3169 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3170 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003171 q+=GetPixelChannels(image);
3172 }
3173 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3174 break;
3175 }
3176 return;
3177 }
3178 if (LocaleCompare(map,"RGBP") == 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 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3188 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3189 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003190 p++;
3191 q+=GetPixelChannels(image);
3192 }
3193 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3194 break;
3195 }
3196 return;
3197 }
cristy14d71292012-05-20 16:48:13 +00003198 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003199 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003200 {
cristycafe0412012-01-10 13:29:58 +00003201 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003202 if (q == (Quantum *) NULL)
3203 break;
cristycafe0412012-01-10 13:29:58 +00003204 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003205 {
3206 register ssize_t
3207 i;
3208
cristy14d71292012-05-20 16:48:13 +00003209 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003210 {
3211 switch (quantum_map[i])
3212 {
3213 case RedQuantum:
3214 case CyanQuantum:
3215 {
cristyb13e12a2012-01-06 21:48:27 +00003216 SetPixelRed(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003217 break;
3218 }
3219 case GreenQuantum:
3220 case MagentaQuantum:
3221 {
cristyb13e12a2012-01-06 21:48:27 +00003222 SetPixelGreen(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003223 break;
3224 }
3225 case BlueQuantum:
3226 case YellowQuantum:
3227 {
cristyb13e12a2012-01-06 21:48:27 +00003228 SetPixelBlue(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003229 break;
3230 }
3231 case AlphaQuantum:
3232 {
cristyb13e12a2012-01-06 21:48:27 +00003233 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003234 break;
3235 }
3236 case OpacityQuantum:
3237 {
cristyb13e12a2012-01-06 21:48:27 +00003238 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003239 break;
3240 }
3241 case BlackQuantum:
3242 {
cristyb13e12a2012-01-06 21:48:27 +00003243 SetPixelBlack(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003244 break;
3245 }
3246 case IndexQuantum:
3247 {
cristyb13e12a2012-01-06 21:48:27 +00003248 SetPixelGray(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003249 break;
3250 }
3251 default:
3252 break;
3253 }
3254 p++;
3255 }
3256 q+=GetPixelChannels(image);
3257 }
3258 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3259 break;
3260 }
3261}
3262
cristycafe0412012-01-10 13:29:58 +00003263static void ImportQuantumPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003264 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3265 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003266{
3267 register const Quantum
3268 *restrict p;
3269
3270 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003271 *restrict q;
cristye5370942012-01-06 03:49:31 +00003272
3273 register ssize_t
3274 x;
3275
cristy14d71292012-05-20 16:48:13 +00003276 size_t
3277 length;
3278
cristye5370942012-01-06 03:49:31 +00003279 ssize_t
3280 y;
3281
3282 p=(const Quantum *) pixels;
3283 if (LocaleCompare(map,"BGR") == 0)
3284 {
cristycafe0412012-01-10 13:29:58 +00003285 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003286 {
cristycafe0412012-01-10 13:29:58 +00003287 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003288 if (q == (Quantum *) NULL)
3289 break;
cristycafe0412012-01-10 13:29:58 +00003290 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003291 {
3292 SetPixelBlue(image,*p++,q);
3293 SetPixelGreen(image,*p++,q);
3294 SetPixelRed(image,*p++,q);
3295 q+=GetPixelChannels(image);
3296 }
3297 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3298 break;
3299 }
3300 return;
3301 }
3302 if (LocaleCompare(map,"BGRA") == 0)
3303 {
cristycafe0412012-01-10 13:29:58 +00003304 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003305 {
cristycafe0412012-01-10 13:29:58 +00003306 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003307 if (q == (Quantum *) NULL)
3308 break;
cristycafe0412012-01-10 13:29:58 +00003309 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003310 {
3311 SetPixelBlue(image,*p++,q);
3312 SetPixelGreen(image,*p++,q);
3313 SetPixelRed(image,*p++,q);
3314 SetPixelAlpha(image,*p++,q);
3315 q+=GetPixelChannels(image);
3316 }
3317 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3318 break;
3319 }
3320 return;
3321 }
3322 if (LocaleCompare(map,"BGRP") == 0)
3323 {
cristycafe0412012-01-10 13:29:58 +00003324 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003325 {
cristycafe0412012-01-10 13:29:58 +00003326 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003327 if (q == (Quantum *) NULL)
3328 break;
cristycafe0412012-01-10 13:29:58 +00003329 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003330 {
3331 SetPixelBlue(image,*p++,q);
3332 SetPixelGreen(image,*p++,q);
3333 SetPixelRed(image,*p++,q);
3334 p++;
3335 q+=GetPixelChannels(image);
3336 }
3337 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3338 break;
3339 }
3340 return;
3341 }
3342 if (LocaleCompare(map,"I") == 0)
3343 {
cristycafe0412012-01-10 13:29:58 +00003344 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003345 {
cristycafe0412012-01-10 13:29:58 +00003346 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003347 if (q == (Quantum *) NULL)
3348 break;
cristycafe0412012-01-10 13:29:58 +00003349 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003350 {
3351 SetPixelGray(image,*p++,q);
3352 q+=GetPixelChannels(image);
3353 }
3354 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3355 break;
3356 }
3357 return;
3358 }
3359 if (LocaleCompare(map,"RGB") == 0)
3360 {
cristycafe0412012-01-10 13:29:58 +00003361 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003362 {
cristycafe0412012-01-10 13:29:58 +00003363 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003364 if (q == (Quantum *) NULL)
3365 break;
cristycafe0412012-01-10 13:29:58 +00003366 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003367 {
3368 SetPixelRed(image,*p++,q);
3369 SetPixelGreen(image,*p++,q);
3370 SetPixelBlue(image,*p++,q);
3371 q+=GetPixelChannels(image);
3372 }
3373 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3374 break;
3375 }
3376 return;
3377 }
3378 if (LocaleCompare(map,"RGBA") == 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 SetPixelRed(image,*p++,q);
3388 SetPixelGreen(image,*p++,q);
3389 SetPixelBlue(image,*p++,q);
3390 SetPixelAlpha(image,*p++,q);
3391 q+=GetPixelChannels(image);
3392 }
3393 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3394 break;
3395 }
3396 return;
3397 }
3398 if (LocaleCompare(map,"RGBP") == 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 SetPixelRed(image,*p++,q);
3408 SetPixelGreen(image,*p++,q);
3409 SetPixelBlue(image,*p++,q);
3410 p++;
3411 q+=GetPixelChannels(image);
3412 }
3413 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3414 break;
3415 }
3416 return;
3417 }
cristy14d71292012-05-20 16:48:13 +00003418 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003419 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003420 {
cristycafe0412012-01-10 13:29:58 +00003421 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003422 if (q == (Quantum *) NULL)
3423 break;
cristycafe0412012-01-10 13:29:58 +00003424 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003425 {
3426 register ssize_t
3427 i;
3428
cristy14d71292012-05-20 16:48:13 +00003429 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003430 {
3431 switch (quantum_map[i])
3432 {
3433 case RedQuantum:
3434 case CyanQuantum:
3435 {
3436 SetPixelRed(image,*p,q);
3437 break;
3438 }
3439 case GreenQuantum:
3440 case MagentaQuantum:
3441 {
3442 SetPixelGreen(image,*p,q);
3443 break;
3444 }
3445 case BlueQuantum:
3446 case YellowQuantum:
3447 {
3448 SetPixelBlue(image,*p,q);
3449 break;
3450 }
3451 case AlphaQuantum:
3452 {
3453 SetPixelAlpha(image,*p,q);
3454 break;
3455 }
3456 case OpacityQuantum:
3457 {
3458 SetPixelAlpha(image,*p,q);
3459 break;
3460 }
3461 case BlackQuantum:
3462 {
3463 SetPixelBlack(image,*p,q);
3464 break;
3465 }
3466 case IndexQuantum:
3467 {
3468 SetPixelGray(image,*p,q);
3469 break;
3470 }
3471 default:
3472 break;
3473 }
3474 p++;
3475 }
3476 q+=GetPixelChannels(image);
3477 }
3478 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3479 break;
3480 }
3481}
3482
cristycafe0412012-01-10 13:29:58 +00003483static void ImportShortPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003484 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3485 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003486{
3487 register const unsigned short
3488 *restrict p;
3489
3490 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003491 *restrict q;
cristye5370942012-01-06 03:49:31 +00003492
3493 register ssize_t
3494 x;
3495
cristy14d71292012-05-20 16:48:13 +00003496 size_t
3497 length;
3498
cristye5370942012-01-06 03:49:31 +00003499 ssize_t
3500 y;
3501
3502 p=(const unsigned short *) pixels;
3503 if (LocaleCompare(map,"BGR") == 0)
3504 {
cristycafe0412012-01-10 13:29:58 +00003505 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003506 {
cristycafe0412012-01-10 13:29:58 +00003507 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003508 if (q == (Quantum *) NULL)
3509 break;
cristycafe0412012-01-10 13:29:58 +00003510 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003511 {
3512 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3513 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3514 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3515 q+=GetPixelChannels(image);
3516 }
3517 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3518 break;
3519 }
3520 return;
3521 }
3522 if (LocaleCompare(map,"BGRA") == 0)
3523 {
cristycafe0412012-01-10 13:29:58 +00003524 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003525 {
cristycafe0412012-01-10 13:29:58 +00003526 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003527 if (q == (Quantum *) NULL)
3528 break;
cristycafe0412012-01-10 13:29:58 +00003529 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003530 {
3531 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3532 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3533 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3534 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3535 q+=GetPixelChannels(image);
3536 }
3537 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3538 break;
3539 }
3540 return;
3541 }
3542 if (LocaleCompare(map,"BGRP") == 0)
3543 {
cristycafe0412012-01-10 13:29:58 +00003544 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003545 {
cristycafe0412012-01-10 13:29:58 +00003546 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003547 if (q == (Quantum *) NULL)
3548 break;
cristycafe0412012-01-10 13:29:58 +00003549 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003550 {
3551 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3552 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3553 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3554 p++;
3555 q+=GetPixelChannels(image);
3556 }
3557 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3558 break;
3559 }
3560 return;
3561 }
3562 if (LocaleCompare(map,"I") == 0)
3563 {
cristycafe0412012-01-10 13:29:58 +00003564 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003565 {
cristycafe0412012-01-10 13:29:58 +00003566 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003567 if (q == (Quantum *) NULL)
3568 break;
cristycafe0412012-01-10 13:29:58 +00003569 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003570 {
3571 SetPixelGray(image,ScaleShortToQuantum(*p++),q);
3572 q+=GetPixelChannels(image);
3573 }
3574 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3575 break;
3576 }
3577 return;
3578 }
3579 if (LocaleCompare(map,"RGB") == 0)
3580 {
cristycafe0412012-01-10 13:29:58 +00003581 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003582 {
cristycafe0412012-01-10 13:29:58 +00003583 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003584 if (q == (Quantum *) NULL)
3585 break;
cristycafe0412012-01-10 13:29:58 +00003586 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003587 {
3588 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3589 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3590 SetPixelBlue(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,"RGBA") == 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 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3608 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3609 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3610 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3611 q+=GetPixelChannels(image);
3612 }
3613 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3614 break;
3615 }
3616 return;
3617 }
3618 if (LocaleCompare(map,"RGBP") == 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 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3628 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3629 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3630 p++;
3631 q+=GetPixelChannels(image);
3632 }
3633 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3634 break;
3635 }
3636 return;
3637 }
cristy14d71292012-05-20 16:48:13 +00003638 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003639 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003640 {
cristycafe0412012-01-10 13:29:58 +00003641 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003642 if (q == (Quantum *) NULL)
3643 break;
cristycafe0412012-01-10 13:29:58 +00003644 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003645 {
3646 register ssize_t
3647 i;
3648
cristy14d71292012-05-20 16:48:13 +00003649 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003650 {
3651 switch (quantum_map[i])
3652 {
3653 case RedQuantum:
3654 case CyanQuantum:
3655 {
3656 SetPixelRed(image,ScaleShortToQuantum(*p),q);
3657 break;
3658 }
3659 case GreenQuantum:
3660 case MagentaQuantum:
3661 {
3662 SetPixelGreen(image,ScaleShortToQuantum(*p),q);
3663 break;
3664 }
3665 case BlueQuantum:
3666 case YellowQuantum:
3667 {
3668 SetPixelBlue(image,ScaleShortToQuantum(*p),q);
3669 break;
3670 }
3671 case AlphaQuantum:
3672 {
3673 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
3674 break;
3675 }
3676 case OpacityQuantum:
3677 {
3678 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
3679 break;
3680 }
3681 case BlackQuantum:
3682 {
3683 SetPixelBlack(image,ScaleShortToQuantum(*p),q);
3684 break;
3685 }
3686 case IndexQuantum:
3687 {
3688 SetPixelGray(image,ScaleShortToQuantum(*p),q);
3689 break;
3690 }
3691 default:
3692 break;
3693 }
3694 p++;
3695 }
3696 q+=GetPixelChannels(image);
3697 }
3698 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3699 break;
3700 }
3701}
3702
cristycafe0412012-01-10 13:29:58 +00003703MagickExport MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
3704 const ssize_t y,const size_t width,const size_t height,const char *map,
3705 const StorageType type,const void *pixels,ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00003706{
cristy4c08aed2011-07-01 19:47:50 +00003707 QuantumType
3708 *quantum_map;
3709
cristycafe0412012-01-10 13:29:58 +00003710 RectangleInfo
3711 roi;
3712
cristy4c08aed2011-07-01 19:47:50 +00003713 register ssize_t
cristye5370942012-01-06 03:49:31 +00003714 i;
cristy4c08aed2011-07-01 19:47:50 +00003715
cristy14d71292012-05-20 16:48:13 +00003716 size_t
3717 length;
3718
cristy4c08aed2011-07-01 19:47:50 +00003719 /*
3720 Allocate image structure.
3721 */
3722 assert(image != (Image *) NULL);
3723 assert(image->signature == MagickSignature);
3724 if (image->debug != MagickFalse)
3725 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristy14d71292012-05-20 16:48:13 +00003726 length=strlen(map);
3727 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
cristy4c08aed2011-07-01 19:47:50 +00003728 if (quantum_map == (QuantumType *) NULL)
3729 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
3730 image->filename);
cristy14d71292012-05-20 16:48:13 +00003731 for (i=0; i < (ssize_t) length; i++)
cristy4c08aed2011-07-01 19:47:50 +00003732 {
3733 switch (map[i])
3734 {
3735 case 'a':
3736 case 'A':
3737 {
3738 quantum_map[i]=AlphaQuantum;
cristy8a46d822012-08-28 23:32:39 +00003739 image->alpha_trait=BlendPixelTrait;
cristy4c08aed2011-07-01 19:47:50 +00003740 break;
3741 }
3742 case 'B':
3743 case 'b':
3744 {
3745 quantum_map[i]=BlueQuantum;
3746 break;
3747 }
3748 case 'C':
3749 case 'c':
3750 {
3751 quantum_map[i]=CyanQuantum;
cristy63240882011-08-05 19:05:27 +00003752 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003753 break;
3754 }
3755 case 'g':
3756 case 'G':
3757 {
3758 quantum_map[i]=GreenQuantum;
3759 break;
3760 }
3761 case 'K':
3762 case 'k':
3763 {
3764 quantum_map[i]=BlackQuantum;
cristy63240882011-08-05 19:05:27 +00003765 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003766 break;
3767 }
3768 case 'I':
3769 case 'i':
3770 {
3771 quantum_map[i]=IndexQuantum;
cristyb7b3da62012-07-05 15:43:37 +00003772 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003773 break;
3774 }
3775 case 'm':
3776 case 'M':
3777 {
3778 quantum_map[i]=MagentaQuantum;
cristy63240882011-08-05 19:05:27 +00003779 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003780 break;
3781 }
3782 case 'O':
3783 case 'o':
3784 {
3785 quantum_map[i]=OpacityQuantum;
cristy8a46d822012-08-28 23:32:39 +00003786 image->alpha_trait=BlendPixelTrait;
cristy4c08aed2011-07-01 19:47:50 +00003787 break;
3788 }
3789 case 'P':
3790 case 'p':
3791 {
3792 quantum_map[i]=UndefinedQuantum;
3793 break;
3794 }
3795 case 'R':
3796 case 'r':
3797 {
3798 quantum_map[i]=RedQuantum;
3799 break;
3800 }
3801 case 'Y':
3802 case 'y':
3803 {
3804 quantum_map[i]=YellowQuantum;
cristy63240882011-08-05 19:05:27 +00003805 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003806 break;
3807 }
3808 default:
3809 {
3810 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
cristy63240882011-08-05 19:05:27 +00003811 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthonye5b39652012-04-21 05:37:29 +00003812 "UnrecognizedPixelMap","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00003813 return(MagickFalse);
3814 }
3815 }
3816 }
cristy63240882011-08-05 19:05:27 +00003817 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
cristy4c08aed2011-07-01 19:47:50 +00003818 return(MagickFalse);
3819 /*
cristye5370942012-01-06 03:49:31 +00003820 Transfer the pixels from the pixel data to the image.
cristy4c08aed2011-07-01 19:47:50 +00003821 */
cristycafe0412012-01-10 13:29:58 +00003822 roi.width=width;
3823 roi.height=height;
3824 roi.x=x;
3825 roi.y=y;
cristy4c08aed2011-07-01 19:47:50 +00003826 switch (type)
3827 {
3828 case CharPixel:
3829 {
cristycafe0412012-01-10 13:29:58 +00003830 ImportCharPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003831 break;
3832 }
3833 case DoublePixel:
3834 {
cristycafe0412012-01-10 13:29:58 +00003835 ImportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003836 break;
3837 }
3838 case FloatPixel:
3839 {
cristycafe0412012-01-10 13:29:58 +00003840 ImportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003841 break;
3842 }
cristy4c08aed2011-07-01 19:47:50 +00003843 case LongPixel:
3844 {
cristycafe0412012-01-10 13:29:58 +00003845 ImportLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003846 break;
3847 }
cristy6c9e1682012-01-07 21:37:44 +00003848 case LongLongPixel:
3849 {
cristycafe0412012-01-10 13:29:58 +00003850 ImportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy6c9e1682012-01-07 21:37:44 +00003851 break;
3852 }
cristy4c08aed2011-07-01 19:47:50 +00003853 case QuantumPixel:
3854 {
cristycafe0412012-01-10 13:29:58 +00003855 ImportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003856 break;
3857 }
3858 case ShortPixel:
3859 {
cristycafe0412012-01-10 13:29:58 +00003860 ImportShortPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003861 break;
3862 }
3863 default:
3864 {
3865 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
cristyc82a27b2011-10-21 01:07:16 +00003866 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthonye5b39652012-04-21 05:37:29 +00003867 "UnrecognizedPixelMap","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00003868 break;
3869 }
3870 }
3871 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
3872 return(MagickTrue);
3873}
3874
3875/*
3876%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3877% %
3878% %
3879% %
cristybd5a96c2011-08-21 00:04:26 +00003880+ 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 %
3881% %
3882% %
3883% %
3884%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3885%
3886% InitializePixelChannelMap() defines the standard pixel component map.
3887%
3888% The format of the InitializePixelChannelMap() method is:
3889%
3890% void InitializePixelChannelMap(Image *image)
3891%
3892% A description of each parameter follows:
3893%
3894% o image: the image.
3895%
3896*/
cristye2a912b2011-12-05 20:02:07 +00003897MagickExport void InitializePixelChannelMap(Image *image)
cristy77c30f52011-10-24 18:56:57 +00003898{
cristye2a912b2011-12-05 20:02:07 +00003899 PixelTrait
3900 trait;
3901
cristy77c30f52011-10-24 18:56:57 +00003902 register ssize_t
3903 i;
3904
cristyd26338f2011-12-14 02:39:30 +00003905 ssize_t
cristy77c30f52011-10-24 18:56:57 +00003906 n;
3907
3908 assert(image != (Image *) NULL);
3909 assert(image->signature == MagickSignature);
cristye2a912b2011-12-05 20:02:07 +00003910 (void) ResetMagickMemory(image->channel_map,0,MaxPixelChannels*
3911 sizeof(*image->channel_map));
3912 trait=UpdatePixelTrait;
cristy8a46d822012-08-28 23:32:39 +00003913 if (image->alpha_trait == BlendPixelTrait)
cristy61f18ad2011-12-08 21:12:37 +00003914 trait=(PixelTrait) (trait | BlendPixelTrait);
cristy77c30f52011-10-24 18:56:57 +00003915 n=0;
cristyc06c5802011-12-31 23:36:16 +00003916 if (image->colorspace == GRAYColorspace)
cristy77c30f52011-10-24 18:56:57 +00003917 {
cristycf1296e2012-08-26 23:40:49 +00003918 SetPixelChannelAttributes(image,BluePixelChannel,trait,n);
3919 SetPixelChannelAttributes(image,GreenPixelChannel,trait,n);
3920 SetPixelChannelAttributes(image,RedPixelChannel,trait,n++);
cristy3c316282011-12-15 15:43:24 +00003921 }
3922 else
3923 {
cristycf1296e2012-08-26 23:40:49 +00003924 SetPixelChannelAttributes(image,RedPixelChannel,trait,n++);
3925 SetPixelChannelAttributes(image,GreenPixelChannel,trait,n++);
3926 SetPixelChannelAttributes(image,BluePixelChannel,trait,n++);
cristy77c30f52011-10-24 18:56:57 +00003927 }
3928 if (image->colorspace == CMYKColorspace)
cristycf1296e2012-08-26 23:40:49 +00003929 SetPixelChannelAttributes(image,BlackPixelChannel,trait,n++);
cristy8a46d822012-08-28 23:32:39 +00003930 if (image->alpha_trait != UndefinedPixelTrait)
cristycf1296e2012-08-26 23:40:49 +00003931 SetPixelChannelAttributes(image,AlphaPixelChannel,CopyPixelTrait,n++);
cristye2a912b2011-12-05 20:02:07 +00003932 if (image->storage_class == PseudoClass)
cristycf1296e2012-08-26 23:40:49 +00003933 SetPixelChannelAttributes(image,IndexPixelChannel,CopyPixelTrait,n++);
cristy183a5c72012-01-30 01:40:35 +00003934 if (image->mask != MagickFalse)
cristycf1296e2012-08-26 23:40:49 +00003935 SetPixelChannelAttributes(image,MaskPixelChannel,CopyPixelTrait,n++);
cristye2a912b2011-12-05 20:02:07 +00003936 assert((n+image->number_meta_channels) < MaxPixelChannels);
3937 for (i=0; i < (ssize_t) image->number_meta_channels; i++)
cristycf1296e2012-08-26 23:40:49 +00003938 SetPixelChannelAttributes(image,(PixelChannel) (MetaPixelChannel+i),
3939 CopyPixelTrait,n++);
cristyd26338f2011-12-14 02:39:30 +00003940 image->number_channels=(size_t) n;
cristy77c30f52011-10-24 18:56:57 +00003941 if (image->debug != MagickFalse)
3942 LogPixelChannels(image);
cristycf1296e2012-08-26 23:40:49 +00003943 (void) SetImageChannelMask(image,image->channel_mask);
cristy77c30f52011-10-24 18:56:57 +00003944}
cristybd5a96c2011-08-21 00:04:26 +00003945
3946/*
3947%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3948% %
3949% %
3950% %
cristya085a432011-07-30 01:39:32 +00003951% I n t e r p o l a t e P i x e l C h a n n e l %
3952% %
3953% %
3954% %
3955%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3956%
cristy884f6002011-07-31 00:51:45 +00003957% InterpolatePixelChannel() applies a pixel interpolation method between a
3958% floating point coordinate and the pixels surrounding that coordinate. No
3959% pixel area resampling, or scaling of the result is performed.
cristya085a432011-07-30 01:39:32 +00003960%
anthonycf4e33d2012-06-08 07:33:23 +00003961% Interpolation is restricted to just the specified channel.
3962%
cristya085a432011-07-30 01:39:32 +00003963% The format of the InterpolatePixelChannel method is:
3964%
3965% MagickBooleanType InterpolatePixelChannel(const Image *image,
cristy444eda62011-08-10 02:07:46 +00003966% const CacheView *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00003967% const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00003968% double *pixel,ExceptionInfo *exception)
3969%
3970% A description of each parameter follows:
3971%
3972% o image: the image.
3973%
3974% o image_view: the image view.
3975%
3976% o channel: the pixel channel to interpolate.
3977%
3978% o method: the pixel color interpolation method.
3979%
3980% o x,y: A double representing the current (x,y) position of the pixel.
3981%
3982% o pixel: return the interpolated pixel here.
3983%
3984% o exception: return any errors or warnings in this structure.
3985%
3986*/
cristy94ea1632011-07-30 20:40:25 +00003987
cristya19f1d72012-08-07 18:24:38 +00003988static inline double MagickMax(const double x,const double y)
cristy884f6002011-07-31 00:51:45 +00003989{
3990 if (x > y)
3991 return(x);
3992 return(y);
3993}
3994
cristyb0a657e2012-08-29 00:45:37 +00003995static inline void CatromWeights(const double x,double (*weights)[4])
cristy884f6002011-07-31 00:51:45 +00003996{
cristya19f1d72012-08-07 18:24:38 +00003997 double
cristy884f6002011-07-31 00:51:45 +00003998 alpha,
nicolasd32d5e52012-06-12 15:34:10 +00003999 beta,
cristy884f6002011-07-31 00:51:45 +00004000 gamma;
4001
cristy5a5e4d92012-08-29 00:06:25 +00004002 /*
4003 Nicolas Robidoux' 10 flops (4* + 5- + 1+) refactoring of the computation
4004 of the standard four 1D Catmull-Rom weights. The sampling location is
4005 assumed between the second and third input pixel locations, and x is the
4006 position relative to the second input pixel location. Formulas originally
4007 derived for the VIPS (Virtual Image Processing System) library.
4008 */
cristya19f1d72012-08-07 18:24:38 +00004009 alpha=(double) 1.0-x;
4010 beta=(double) (-0.5)*x*alpha;
nicolasd32d5e52012-06-12 15:34:10 +00004011 (*weights)[0]=alpha*beta;
4012 (*weights)[3]=x*beta;
4013 /*
cristy5a5e4d92012-08-29 00:06:25 +00004014 The following computation of the inner weights from the outer ones work
4015 for all Keys cubics.
nicolasd32d5e52012-06-12 15:34:10 +00004016 */
4017 gamma=(*weights)[3]-(*weights)[0];
4018 (*weights)[1]=alpha-(*weights)[0]+gamma;
4019 (*weights)[2]=x-(*weights)[3]-gamma;
4020}
4021
cristyb0a657e2012-08-29 00:45:37 +00004022static inline void SplineWeights(const double x,double (*weights)[4])
nicolasd32d5e52012-06-12 15:34:10 +00004023{
cristy5a5e4d92012-08-29 00:06:25 +00004024 double
4025 alpha,
4026 beta;
4027
nicolasd32d5e52012-06-12 15:34:10 +00004028 /*
4029 Nicolas Robidoux' 12 flops (6* + 5- + 1+) refactoring of the
4030 computation of the standard four 1D cubic B-spline smoothing
4031 weights. The sampling location is assumed between the second and
4032 third input pixel locations, and x is the position relative to the
4033 second input pixel location.
4034 */
cristya19f1d72012-08-07 18:24:38 +00004035 alpha=(double) 1.0-x;
4036 (*weights)[3]=(double) (1.0/6.0)*x*x*x;
4037 (*weights)[0]=(double) (1.0/6.0)*alpha*alpha*alpha;
nicolasd32d5e52012-06-12 15:34:10 +00004038 beta=(*weights)[3]-(*weights)[0];
4039 (*weights)[1]=alpha-(*weights)[0]+beta;
4040 (*weights)[2]=x-(*weights)[3]-beta;
cristy884f6002011-07-31 00:51:45 +00004041}
4042
cristy94ea1632011-07-30 20:40:25 +00004043static inline double MeshInterpolate(const PointInfo *delta,const double p,
4044 const double x,const double y)
4045{
4046 return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p);
4047}
4048
anthonycf4e33d2012-06-08 07:33:23 +00004049/*
cristya19f1d72012-08-07 18:24:38 +00004050static inline ssize_t NearestNeighbor(const double x)
cristy884f6002011-07-31 00:51:45 +00004051{
4052 if (x >= 0.0)
4053 return((ssize_t) (x+0.5));
4054 return((ssize_t) (x-0.5));
4055}
anthonycf4e33d2012-06-08 07:33:23 +00004056*/
cristy884f6002011-07-31 00:51:45 +00004057
cristya085a432011-07-30 01:39:32 +00004058MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
4059 const CacheView *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00004060 const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00004061 double *pixel,ExceptionInfo *exception)
4062{
4063 MagickBooleanType
4064 status;
4065
cristya19f1d72012-08-07 18:24:38 +00004066 double
cristy94ea1632011-07-30 20:40:25 +00004067 alpha[16],
cristy884f6002011-07-31 00:51:45 +00004068 gamma,
4069 pixels[16];
cristy94ea1632011-07-30 20:40:25 +00004070
4071 PixelTrait
4072 traits;
4073
cristy94ea1632011-07-30 20:40:25 +00004074 register const Quantum
4075 *p;
4076
cristy50e64b82012-06-22 17:46:19 +00004077 register ssize_t
cristy94ea1632011-07-30 20:40:25 +00004078 i;
4079
cristya085a432011-07-30 01:39:32 +00004080 ssize_t
4081 x_offset,
4082 y_offset;
4083
anthonycf4e33d2012-06-08 07:33:23 +00004084 PixelInterpolateMethod
4085 interpolate;
4086
cristya085a432011-07-30 01:39:32 +00004087 assert(image != (Image *) NULL);
4088 assert(image != (Image *) NULL);
4089 assert(image->signature == MagickSignature);
4090 assert(image_view != (CacheView *) NULL);
4091 status=MagickTrue;
cristy884f6002011-07-31 00:51:45 +00004092 *pixel=0.0;
cristycf1296e2012-08-26 23:40:49 +00004093 traits=GetPixelChannelTraits(image,channel);
cristya085a432011-07-30 01:39:32 +00004094 x_offset=(ssize_t) floor(x);
4095 y_offset=(ssize_t) floor(y);
anthonycf4e33d2012-06-08 07:33:23 +00004096 interpolate = method;
4097 if ( interpolate == UndefinedInterpolatePixel )
4098 interpolate = image->interpolate;
4099 switch (interpolate)
cristya085a432011-07-30 01:39:32 +00004100 {
anthonycf4e33d2012-06-08 07:33:23 +00004101 case AverageInterpolatePixel: /* nearest 4 neighbours */
4102 case Average9InterpolatePixel: /* nearest 9 neighbours */
4103 case Average16InterpolatePixel: /* nearest 16 neighbours */
cristy884f6002011-07-31 00:51:45 +00004104 {
cristyfb122372012-10-17 23:31:21 +00004105 ssize_t
4106 count;
anthonycf4e33d2012-06-08 07:33:23 +00004107
cristyfb122372012-10-17 23:31:21 +00004108 count=2; /* size of the area to average - default nearest 4 */
anthonycf4e33d2012-06-08 07:33:23 +00004109 if (interpolate == Average9InterpolatePixel)
4110 {
4111 count=3;
4112 x_offset=(ssize_t) (floor(x+0.5)-1);
4113 y_offset=(ssize_t) (floor(y+0.5)-1);
4114 }
cristyfb122372012-10-17 23:31:21 +00004115 else
4116 if (interpolate == Average16InterpolatePixel)
4117 {
4118 count=4;
4119 x_offset--;
4120 y_offset--;
4121 }
anthonycf4e33d2012-06-08 07:33:23 +00004122 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,count,count,
cristy884f6002011-07-31 00:51:45 +00004123 exception);
4124 if (p == (const Quantum *) NULL)
4125 {
4126 status=MagickFalse;
4127 break;
4128 }
anthonycf4e33d2012-06-08 07:33:23 +00004129 count*=count; /* Number of pixels to Average */
cristy222b19c2011-08-04 01:35:11 +00004130 if ((traits & BlendPixelTrait) == 0)
cristy50e64b82012-06-22 17:46:19 +00004131 for (i=0; i < (ssize_t) count; i++)
cristy884f6002011-07-31 00:51:45 +00004132 {
4133 alpha[i]=1.0;
cristya19f1d72012-08-07 18:24:38 +00004134 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
cristy884f6002011-07-31 00:51:45 +00004135 }
4136 else
cristy50e64b82012-06-22 17:46:19 +00004137 for (i=0; i < (ssize_t) count; i++)
cristy884f6002011-07-31 00:51:45 +00004138 {
4139 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4140 GetPixelChannels(image));
4141 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4142 }
cristy50e64b82012-06-22 17:46:19 +00004143 for (i=0; i < (ssize_t) count; i++)
cristy884f6002011-07-31 00:51:45 +00004144 {
cristy3e3ec3a2012-11-03 23:11:06 +00004145 gamma=PerceptibleReciprocal(alpha[i])/count;
anthonycf4e33d2012-06-08 07:33:23 +00004146 *pixel+=gamma*pixels[i];
cristy884f6002011-07-31 00:51:45 +00004147 }
4148 break;
4149 }
anthonycf4e33d2012-06-08 07:33:23 +00004150 case BilinearInterpolatePixel:
4151 default:
4152 {
4153 PointInfo
4154 delta,
4155 epsilon;
4156
4157 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4158 if (p == (const Quantum *) NULL)
4159 {
4160 status=MagickFalse;
4161 break;
4162 }
4163 if ((traits & BlendPixelTrait) == 0)
4164 for (i=0; i < 4; i++)
4165 {
4166 alpha[i]=1.0;
cristya19f1d72012-08-07 18:24:38 +00004167 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
anthonycf4e33d2012-06-08 07:33:23 +00004168 }
4169 else
4170 for (i=0; i < 4; i++)
4171 {
4172 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4173 GetPixelChannels(image));
4174 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4175 }
4176 delta.x=x-x_offset;
4177 delta.y=y-y_offset;
4178 epsilon.x=1.0-delta.x;
4179 epsilon.y=1.0-delta.y;
4180 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4181 (epsilon.x*alpha[2]+delta.x*alpha[3])));
cristy3e3ec3a2012-11-03 23:11:06 +00004182 gamma=PerceptibleReciprocal(gamma);
anthonycf4e33d2012-06-08 07:33:23 +00004183 *pixel=gamma*(epsilon.y*(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*
4184 (epsilon.x*pixels[2]+delta.x*pixels[3]));
4185 break;
4186 }
anthony5f78bca2012-10-05 06:51:00 +00004187 case BlendInterpolatePixel:
4188 {
4189 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4190 if (p == (const Quantum *) NULL)
4191 {
4192 status=MagickFalse;
4193 break;
4194 }
4195 if ((traits & BlendPixelTrait) == 0)
4196 for (i=0; i < 4; i++)
4197 {
4198 alpha[i]=1.0;
4199 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4200 }
4201 else
4202 for (i=0; i < 4; i++)
4203 {
4204 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4205 GetPixelChannels(image));
4206 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4207 }
4208 gamma=1.0; /* number of pixels blended together (its variable) */
4209 for (i=0; i <= 1L; i++) {
cristyfb122372012-10-17 23:31:21 +00004210 if ((y-y_offset) >= 0.75)
4211 {
4212 alpha[i]=alpha[i+2]; /* take right pixels */
4213 pixels[i]=pixels[i+2];
4214 }
4215 else
4216 if ((y-y_offset) > 0.25)
4217 {
4218 gamma=2.0; /* blend both pixels in row */
4219 alpha[i]+=alpha[i+2]; /* add up alpha weights */
4220 pixels[i]+=pixels[i+2];
4221 }
4222 }
4223 if ((x-x_offset) >= 0.75)
4224 {
4225 alpha[0]=alpha[1]; /* take bottom row blend */
4226 pixels[0]=pixels[1];
anthony5f78bca2012-10-05 06:51:00 +00004227 }
cristyfb122372012-10-17 23:31:21 +00004228 else
4229 if ((x-x_offset) > 0.25)
4230 {
4231 gamma*=2.0; /* blend both rows */
4232 alpha[0]+=alpha[1]; /* add up alpha weights */
4233 pixels[0]+=pixels[1];
4234 }
anthony5f78bca2012-10-05 06:51:00 +00004235 if (channel != AlphaPixelChannel)
cristy3e3ec3a2012-11-03 23:11:06 +00004236 gamma=PerceptibleReciprocal(alpha[0]); /* (color) 1/alpha_weights */
anthony5f78bca2012-10-05 06:51:00 +00004237 else
cristy3e3ec3a2012-11-03 23:11:06 +00004238 gamma=PerceptibleReciprocal(gamma); /* (alpha) 1/number_of_pixels */
anthony5f78bca2012-10-05 06:51:00 +00004239 *pixel=gamma*pixels[0];
4240 break;
4241 }
anthonycf4e33d2012-06-08 07:33:23 +00004242 case CatromInterpolatePixel:
cristy884f6002011-07-31 00:51:45 +00004243 {
cristya19f1d72012-08-07 18:24:38 +00004244 double
cristy380a11c2012-06-02 15:15:22 +00004245 cx[4],
nicolas6676f5a2012-06-12 16:01:15 +00004246 cy[4];
cristy884f6002011-07-31 00:51:45 +00004247
cristy884f6002011-07-31 00:51:45 +00004248 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4249 exception);
4250 if (p == (const Quantum *) NULL)
4251 {
4252 status=MagickFalse;
4253 break;
4254 }
cristy222b19c2011-08-04 01:35:11 +00004255 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004256 for (i=0; i < 16; i++)
4257 {
4258 alpha[i]=1.0;
cristya19f1d72012-08-07 18:24:38 +00004259 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
cristy884f6002011-07-31 00:51:45 +00004260 }
4261 else
4262 for (i=0; i < 16; i++)
4263 {
4264 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4265 GetPixelChannels(image));
4266 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4267 }
cristya19f1d72012-08-07 18:24:38 +00004268 CatromWeights((double) (x-x_offset),&cx);
4269 CatromWeights((double) (y-y_offset),&cy);
4270 gamma=(channel == AlphaPixelChannel ? (double) 1.0 :
cristy3e3ec3a2012-11-03 23:11:06 +00004271 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
nicolasd32d5e52012-06-12 15:34:10 +00004272 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4273 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4274 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4275 cx[2]*alpha[14]+cx[3]*alpha[15])));
cristy380a11c2012-06-02 15:15:22 +00004276 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
nicolasd32d5e52012-06-12 15:34:10 +00004277 cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*
4278 pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+
4279 cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*
4280 pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15]));
cristy884f6002011-07-31 00:51:45 +00004281 break;
4282 }
anthonycf4e33d2012-06-08 07:33:23 +00004283#if 0
nicolas20075dc2012-06-12 20:47:38 +00004284 /* deprecated useless and very slow interpolator */
cristy884f6002011-07-31 00:51:45 +00004285 case FilterInterpolatePixel:
4286 {
4287 CacheView
4288 *filter_view;
4289
4290 Image
4291 *excerpt_image,
4292 *filter_image;
4293
4294 RectangleInfo
4295 geometry;
4296
4297 geometry.width=4L;
4298 geometry.height=4L;
4299 geometry.x=x_offset-1;
4300 geometry.y=y_offset-1;
4301 excerpt_image=ExcerptImage(image,&geometry,exception);
4302 if (excerpt_image == (Image *) NULL)
4303 {
4304 status=MagickFalse;
4305 break;
4306 }
cristyaa2c16c2012-03-25 22:21:35 +00004307 filter_image=ResizeImage(excerpt_image,1,1,image->filter,exception);
cristy884f6002011-07-31 00:51:45 +00004308 excerpt_image=DestroyImage(excerpt_image);
4309 if (filter_image == (Image *) NULL)
4310 break;
cristydb070952012-04-20 14:33:00 +00004311 filter_view=AcquireVirtualCacheView(filter_image,exception);
cristy884f6002011-07-31 00:51:45 +00004312 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4313 if (p == (const Quantum *) NULL)
4314 status=MagickFalse;
4315 else
cristy0beccfa2011-09-25 20:47:53 +00004316 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004317 filter_view=DestroyCacheView(filter_view);
4318 filter_image=DestroyImage(filter_image);
4319 break;
4320 }
anthonycf4e33d2012-06-08 07:33:23 +00004321#endif
cristy884f6002011-07-31 00:51:45 +00004322 case IntegerInterpolatePixel:
4323 {
4324 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
4325 if (p == (const Quantum *) NULL)
4326 {
4327 status=MagickFalse;
4328 break;
4329 }
cristy0beccfa2011-09-25 20:47:53 +00004330 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004331 break;
4332 }
anthonycf4e33d2012-06-08 07:33:23 +00004333 case NearestInterpolatePixel:
cristy884f6002011-07-31 00:51:45 +00004334 {
anthonycf4e33d2012-06-08 07:33:23 +00004335 x_offset=(ssize_t) floor(x+0.5);
4336 y_offset=(ssize_t) floor(y+0.5);
4337 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
cristy884f6002011-07-31 00:51:45 +00004338 if (p == (const Quantum *) NULL)
4339 {
4340 status=MagickFalse;
4341 break;
4342 }
cristy0beccfa2011-09-25 20:47:53 +00004343 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004344 break;
4345 }
4346 case MeshInterpolatePixel:
4347 {
4348 PointInfo
4349 delta,
cristy94ea1632011-07-30 20:40:25 +00004350 luminance;
4351
4352 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4353 if (p == (const Quantum *) NULL)
4354 {
4355 status=MagickFalse;
4356 break;
4357 }
cristy222b19c2011-08-04 01:35:11 +00004358 if ((traits & BlendPixelTrait) == 0)
cristy94ea1632011-07-30 20:40:25 +00004359 for (i=0; i < 4; i++)
4360 {
4361 alpha[i]=1.0;
cristya19f1d72012-08-07 18:24:38 +00004362 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
cristy94ea1632011-07-30 20:40:25 +00004363 }
4364 else
4365 for (i=0; i < 4; i++)
4366 {
4367 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4368 GetPixelChannels(image));
4369 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4370 }
cristy884f6002011-07-31 00:51:45 +00004371 delta.x=x-x_offset;
4372 delta.y=y-y_offset;
4373 luminance.x=GetPixelLuminance(image,p)-(double)
4374 GetPixelLuminance(image,p+3*GetPixelChannels(image));
cristy28474bf2011-09-11 23:32:52 +00004375 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
cristy884f6002011-07-31 00:51:45 +00004376 GetPixelLuminance(image,p+2*GetPixelChannels(image));
cristy94ea1632011-07-30 20:40:25 +00004377 if (fabs(luminance.x) < fabs(luminance.y))
4378 {
4379 /*
4380 Diagonal 0-3 NW-SE.
4381 */
4382 if (delta.x <= delta.y)
4383 {
4384 /*
4385 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4386 */
4387 delta.y=1.0-delta.y;
4388 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
cristy3e3ec3a2012-11-03 23:11:06 +00004389 gamma=PerceptibleReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004390 *pixel=gamma*MeshInterpolate(&delta,pixels[2],pixels[3],
4391 pixels[0]);
4392 }
4393 else
4394 {
4395 /*
4396 Top-right triangle (pixel: 1, diagonal: 0-3).
4397 */
4398 delta.x=1.0-delta.x;
4399 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
cristy3e3ec3a2012-11-03 23:11:06 +00004400 gamma=PerceptibleReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004401 *pixel=gamma*MeshInterpolate(&delta,pixels[1],pixels[0],
4402 pixels[3]);
4403 }
4404 }
4405 else
4406 {
4407 /*
4408 Diagonal 1-2 NE-SW.
4409 */
4410 if (delta.x <= (1.0-delta.y))
4411 {
4412 /*
4413 Top-left triangle (pixel: 0, diagonal: 1-2).
4414 */
4415 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
cristy3e3ec3a2012-11-03 23:11:06 +00004416 gamma=PerceptibleReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004417 *pixel=gamma*MeshInterpolate(&delta,pixels[0],pixels[1],
4418 pixels[2]);
4419 }
4420 else
4421 {
4422 /*
4423 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4424 */
4425 delta.x=1.0-delta.x;
4426 delta.y=1.0-delta.y;
4427 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
cristy3e3ec3a2012-11-03 23:11:06 +00004428 gamma=PerceptibleReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004429 *pixel=gamma*MeshInterpolate(&delta,pixels[3],pixels[2],
4430 pixels[1]);
4431 }
4432 }
cristya085a432011-07-30 01:39:32 +00004433 break;
4434 }
cristy884f6002011-07-31 00:51:45 +00004435 case SplineInterpolatePixel:
4436 {
cristya19f1d72012-08-07 18:24:38 +00004437 double
nicolasd32d5e52012-06-12 15:34:10 +00004438 cx[4],
nicolas6676f5a2012-06-12 16:01:15 +00004439 cy[4];
cristy884f6002011-07-31 00:51:45 +00004440
4441 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4442 exception);
4443 if (p == (const Quantum *) NULL)
4444 {
4445 status=MagickFalse;
4446 break;
4447 }
cristy222b19c2011-08-04 01:35:11 +00004448 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004449 for (i=0; i < 16; i++)
4450 {
4451 alpha[i]=1.0;
cristya19f1d72012-08-07 18:24:38 +00004452 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
cristy884f6002011-07-31 00:51:45 +00004453 }
4454 else
4455 for (i=0; i < 16; i++)
4456 {
4457 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4458 GetPixelChannels(image));
4459 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4460 }
cristya19f1d72012-08-07 18:24:38 +00004461 SplineWeights((double) (x-x_offset),&cx);
4462 SplineWeights((double) (y-y_offset),&cy);
4463 gamma=(channel == AlphaPixelChannel ? (double) 1.0 :
cristy3e3ec3a2012-11-03 23:11:06 +00004464 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
nicolasd32d5e52012-06-12 15:34:10 +00004465 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4466 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4467 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4468 cx[2]*alpha[14]+cx[3]*alpha[15])));
4469 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
4470 cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*
4471 pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+
4472 cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*
4473 pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15]));
cristy884f6002011-07-31 00:51:45 +00004474 break;
4475 }
cristya085a432011-07-30 01:39:32 +00004476 }
4477 return(status);
4478}
4479
4480/*
4481%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4482% %
4483% %
4484% %
cristy5c4e2582011-09-11 19:21:03 +00004485% I n t e r p o l a t e P i x e l C h a n n e l s %
4486% %
4487% %
4488% %
4489%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4490%
4491% InterpolatePixelChannels() applies a pixel interpolation method between a
4492% floating point coordinate and the pixels surrounding that coordinate. No
4493% pixel area resampling, or scaling of the result is performed.
4494%
anthonycf4e33d2012-06-08 07:33:23 +00004495% Interpolation is restricted to just the current channel setting of the
4496% destination image into which the color is to be stored
4497%
cristy5c4e2582011-09-11 19:21:03 +00004498% The format of the InterpolatePixelChannels method is:
4499%
4500% MagickBooleanType InterpolatePixelChannels(const Image *source,
4501% const CacheView *source_view,const Image *destination,
4502% const PixelInterpolateMethod method,const double x,const double y,
4503% Quantum *pixel,ExceptionInfo *exception)
4504%
4505% A description of each parameter follows:
4506%
4507% o source: the source.
4508%
4509% o source_view: the source view.
4510%
anthonycf4e33d2012-06-08 07:33:23 +00004511% o destination: the destination image, for the interpolated color
cristy5c4e2582011-09-11 19:21:03 +00004512%
4513% o method: the pixel color interpolation method.
4514%
4515% o x,y: A double representing the current (x,y) position of the pixel.
4516%
4517% o pixel: return the interpolated pixel here.
4518%
4519% o exception: return any errors or warnings in this structure.
4520%
4521*/
4522MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
4523 const CacheView *source_view,const Image *destination,
4524 const PixelInterpolateMethod method,const double x,const double y,
4525 Quantum *pixel,ExceptionInfo *exception)
4526{
4527 MagickBooleanType
4528 status;
4529
cristya19f1d72012-08-07 18:24:38 +00004530 double
cristy5c4e2582011-09-11 19:21:03 +00004531 alpha[16],
4532 gamma,
4533 pixels[16];
4534
4535 PixelChannel
4536 channel;
4537
4538 PixelTrait
4539 destination_traits,
4540 traits;
4541
4542 register const Quantum
4543 *p;
4544
cristy50e64b82012-06-22 17:46:19 +00004545 register ssize_t
cristy5c4e2582011-09-11 19:21:03 +00004546 i;
4547
4548 ssize_t
4549 x_offset,
4550 y_offset;
4551
anthonycf4e33d2012-06-08 07:33:23 +00004552 PixelInterpolateMethod
4553 interpolate;
4554
cristy5c4e2582011-09-11 19:21:03 +00004555 assert(source != (Image *) NULL);
4556 assert(source != (Image *) NULL);
4557 assert(source->signature == MagickSignature);
4558 assert(source_view != (CacheView *) NULL);
4559 status=MagickTrue;
4560 x_offset=(ssize_t) floor(x);
4561 y_offset=(ssize_t) floor(y);
anthonycf4e33d2012-06-08 07:33:23 +00004562 interpolate = method;
4563 if ( interpolate == UndefinedInterpolatePixel )
4564 interpolate = source->interpolate;
4565 switch (interpolate)
cristy5c4e2582011-09-11 19:21:03 +00004566 {
anthonycf4e33d2012-06-08 07:33:23 +00004567 case AverageInterpolatePixel: /* nearest 4 neighbours */
4568 case Average9InterpolatePixel: /* nearest 9 neighbours */
4569 case Average16InterpolatePixel: /* nearest 16 neighbours */
cristy5c4e2582011-09-11 19:21:03 +00004570 {
cristyfb122372012-10-17 23:31:21 +00004571 ssize_t
4572 count;
anthonycf4e33d2012-06-08 07:33:23 +00004573
cristyfb122372012-10-17 23:31:21 +00004574 count=2; /* size of the area to average - default nearest 4 */
anthonycf4e33d2012-06-08 07:33:23 +00004575 if (interpolate == Average9InterpolatePixel)
4576 {
4577 count=3;
4578 x_offset=(ssize_t) (floor(x+0.5)-1);
4579 y_offset=(ssize_t) (floor(y+0.5)-1);
4580 }
cristyfb122372012-10-17 23:31:21 +00004581 else
4582 if (interpolate == Average16InterpolatePixel)
4583 {
4584 count=4;
4585 x_offset--;
4586 y_offset--;
4587 }
anthonycf4e33d2012-06-08 07:33:23 +00004588 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 }
cristyfb122372012-10-17 23:31:21 +00004595 count*=count; /* Number of pixels to Average */
cristy50e64b82012-06-22 17:46:19 +00004596 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004597 {
4598 double
4599 sum;
4600
cristy50e64b82012-06-22 17:46:19 +00004601 register ssize_t
cristy5c4e2582011-09-11 19:21:03 +00004602 j;
4603
cristycf1296e2012-08-26 23:40:49 +00004604 channel=GetPixelChannelChannel(source,i);
4605 traits=GetPixelChannelTraits(source,channel);
4606 destination_traits=GetPixelChannelTraits(destination,channel);
cristy5c4e2582011-09-11 19:21:03 +00004607 if ((traits == UndefinedPixelTrait) ||
4608 (destination_traits == UndefinedPixelTrait))
4609 continue;
cristy50e64b82012-06-22 17:46:19 +00004610 for (j=0; j < (ssize_t) count; j++)
cristya19f1d72012-08-07 18:24:38 +00004611 pixels[j]=(double) 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 {
cristy50e64b82012-06-22 17:46:19 +00004615 for (j=0; j < (ssize_t) count; j++)
anthonycf4e33d2012-06-08 07:33:23 +00004616 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 }
cristy50e64b82012-06-22 17:46:19 +00004621 for (j=0; j < (ssize_t) 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];
cristy3e3ec3a2012-11-03 23:11:06 +00004626 gamma=PerceptibleReciprocal(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 }
cristy50e64b82012-06-22 17:46:19 +00004643 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
anthonycf4e33d2012-06-08 07:33:23 +00004644 {
4645 PointInfo
4646 delta,
4647 epsilon;
4648
cristycf1296e2012-08-26 23:40:49 +00004649 channel=GetPixelChannelChannel(source,i);
4650 traits=GetPixelChannelTraits(source,channel);
4651 destination_traits=GetPixelChannelTraits(destination,channel);
anthonycf4e33d2012-06-08 07:33:23 +00004652 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;
cristya19f1d72012-08-07 18:24:38 +00004659 pixels[0]=(double) p[i];
4660 pixels[1]=(double) p[GetPixelChannels(source)+i];
4661 pixels[2]=(double) p[2*GetPixelChannels(source)+i];
4662 pixels[3]=(double) p[3*GetPixelChannels(source)+i];
anthonycf4e33d2012-06-08 07:33:23 +00004663 if ((traits & BlendPixelTrait) == 0)
4664 {
4665 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
cristy3e3ec3a2012-11-03 23:11:06 +00004666 gamma=PerceptibleReciprocal(gamma);
anthonycf4e33d2012-06-08 07:33:23 +00004667 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])));
cristy3e3ec3a2012-11-03 23:11:06 +00004684 gamma=PerceptibleReciprocal(gamma);
anthonycf4e33d2012-06-08 07:33:23 +00004685 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 }
anthony5f78bca2012-10-05 06:51:00 +00004691 case BlendInterpolatePixel:
4692 {
4693 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4694 if (p == (const Quantum *) NULL)
4695 {
4696 status=MagickFalse;
4697 break;
4698 }
4699 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4700 {
4701 register ssize_t
4702 j;
4703
4704 channel=GetPixelChannelChannel(source,i);
4705 traits=GetPixelChannelTraits(source,channel);
4706 destination_traits=GetPixelChannelTraits(destination,channel);
4707 if ((traits == UndefinedPixelTrait) ||
4708 (destination_traits == UndefinedPixelTrait))
4709 continue;
4710 if ((traits & BlendPixelTrait) == 0)
4711 for (j=0; j < 4; j++)
4712 {
4713 alpha[j]=1.0;
4714 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+channel];
4715 }
4716 else
4717 for (j=0; j < 4; j++)
4718 {
4719 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4720 GetPixelChannels(source));
4721 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+channel];
4722 }
cristyfb122372012-10-17 23:31:21 +00004723 gamma=1.0; /* number of pixels blended together (its variable) */
4724 for (j=0; j <= 1L; j++)
4725 {
4726 if ((y-y_offset) >= 0.75)
4727 {
4728 alpha[j]=alpha[j+2]; /* take right pixels */
4729 pixels[j]=pixels[j+2];
4730 }
4731 else
4732 if ((y-y_offset) > 0.25)
4733 {
4734 gamma=2.0; /* blend both pixels in row */
4735 alpha[j]+=alpha[j+2]; /* add up alpha weights */
4736 pixels[j]+=pixels[j+2];
4737 }
4738 }
4739 if ((x-x_offset) >= 0.75)
4740 {
4741 alpha[0]=alpha[1]; /* take bottom row blend */
4742 pixels[0]=pixels[1];
anthony5f78bca2012-10-05 06:51:00 +00004743 }
cristyfb122372012-10-17 23:31:21 +00004744 else
4745 if ((x-x_offset) > 0.25)
4746 {
4747 gamma*=2.0; /* blend both rows */
4748 alpha[0]+=alpha[1]; /* add up alpha weights */
4749 pixels[0]+=pixels[1];
4750 }
anthony5f78bca2012-10-05 06:51:00 +00004751 if ((traits & BlendPixelTrait) == 0)
cristy3e3ec3a2012-11-03 23:11:06 +00004752 gamma=PerceptibleReciprocal(alpha[0]); /* (color) 1/alpha_weights */
anthony5f78bca2012-10-05 06:51:00 +00004753 else
cristy3e3ec3a2012-11-03 23:11:06 +00004754 gamma=PerceptibleReciprocal(gamma); /* (alpha) 1/number_of_pixels */
anthony5f78bca2012-10-05 06:51:00 +00004755 SetPixelChannel(destination,channel,ClampToQuantum(gamma*pixels[0]),
cristyfb122372012-10-17 23:31:21 +00004756 pixel);
anthony5f78bca2012-10-05 06:51:00 +00004757 }
4758 break;
4759 }
anthonycf4e33d2012-06-08 07:33:23 +00004760 case CatromInterpolatePixel:
cristy5c4e2582011-09-11 19:21:03 +00004761 {
cristya19f1d72012-08-07 18:24:38 +00004762 double
cristy380a11c2012-06-02 15:15:22 +00004763 cx[4],
4764 cy[4];
cristy5c4e2582011-09-11 19:21:03 +00004765
cristy5c4e2582011-09-11 19:21:03 +00004766 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4767 exception);
4768 if (p == (const Quantum *) NULL)
4769 {
4770 status=MagickFalse;
4771 break;
4772 }
cristy50e64b82012-06-22 17:46:19 +00004773 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004774 {
4775 register ssize_t
4776 j;
4777
cristycf1296e2012-08-26 23:40:49 +00004778 channel=GetPixelChannelChannel(source,i);
4779 traits=GetPixelChannelTraits(source,channel);
4780 destination_traits=GetPixelChannelTraits(destination,channel);
cristy5c4e2582011-09-11 19:21:03 +00004781 if ((traits == UndefinedPixelTrait) ||
4782 (destination_traits == UndefinedPixelTrait))
4783 continue;
4784 if ((traits & BlendPixelTrait) == 0)
4785 for (j=0; j < 16; j++)
4786 {
4787 alpha[j]=1.0;
cristya19f1d72012-08-07 18:24:38 +00004788 pixels[j]=(double) p[j*GetPixelChannels(source)+i];
cristy5c4e2582011-09-11 19:21:03 +00004789 }
4790 else
4791 for (j=0; j < 16; j++)
4792 {
4793 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4794 GetPixelChannels(source));
4795 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
4796 }
cristya19f1d72012-08-07 18:24:38 +00004797 CatromWeights((double) (x-x_offset),&cx);
4798 CatromWeights((double) (y-y_offset),&cy);
4799 gamma=((traits & BlendPixelTrait) ? (double) (1.0) :
cristy3e3ec3a2012-11-03 23:11:06 +00004800 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
nicolasd32d5e52012-06-12 15:34:10 +00004801 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4802 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4803 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4804 cx[2]*alpha[14]+cx[3]*alpha[15])));
cristy380a11c2012-06-02 15:15:22 +00004805 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]*
4806 pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]*
4807 (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+
4808 cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*
nicolasd32d5e52012-06-12 15:34:10 +00004809 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*
4810 pixels[14]+cx[3]*pixels[15]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004811 }
4812 break;
4813 }
anthonycf4e33d2012-06-08 07:33:23 +00004814#if 0
nicolas20075dc2012-06-12 20:47:38 +00004815 /* deprecated useless and very slow interpolator */
cristy5c4e2582011-09-11 19:21:03 +00004816 case FilterInterpolatePixel:
4817 {
cristy50e64b82012-06-22 17:46:19 +00004818 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004819 {
4820 CacheView
4821 *filter_view;
4822
4823 Image
4824 *excerpt_source,
4825 *filter_source;
4826
4827 RectangleInfo
4828 geometry;
4829
cristycf1296e2012-08-26 23:40:49 +00004830 channel=GetPixelChannelChannel(source,i);
4831 traits=GetPixelChannelTraits(source,channel);
4832 destination_traits=GetPixelChannelTraits(destination,channel);
cristy5c4e2582011-09-11 19:21:03 +00004833 if ((traits == UndefinedPixelTrait) ||
4834 (destination_traits == UndefinedPixelTrait))
4835 continue;
4836 geometry.width=4L;
4837 geometry.height=4L;
4838 geometry.x=x_offset-1;
4839 geometry.y=y_offset-1;
4840 excerpt_source=ExcerptImage(source,&geometry,exception);
4841 if (excerpt_source == (Image *) NULL)
4842 {
4843 status=MagickFalse;
4844 continue;
4845 }
cristyaa2c16c2012-03-25 22:21:35 +00004846 filter_source=ResizeImage(excerpt_source,1,1,source->filter,exception);
cristy5c4e2582011-09-11 19:21:03 +00004847 excerpt_source=DestroyImage(excerpt_source);
4848 if (filter_source == (Image *) NULL)
4849 continue;
cristydb070952012-04-20 14:33:00 +00004850 filter_view=AcquireVirtualCacheView(filter_source,exception);
cristy5c4e2582011-09-11 19:21:03 +00004851 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4852 if (p == (const Quantum *) NULL)
4853 status=MagickFalse;
4854 else
cristy1861c902011-12-14 02:30:00 +00004855 {
cristy4a7ae692011-12-14 12:24:11 +00004856 SetPixelChannel(destination,channel,p[i],pixel);
cristy1861c902011-12-14 02:30:00 +00004857 }
cristy5c4e2582011-09-11 19:21:03 +00004858 filter_view=DestroyCacheView(filter_view);
4859 filter_source=DestroyImage(filter_source);
4860 }
4861 break;
4862 }
anthonycf4e33d2012-06-08 07:33:23 +00004863#endif
cristy5c4e2582011-09-11 19:21:03 +00004864 case IntegerInterpolatePixel:
4865 {
4866 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
4867 if (p == (const Quantum *) NULL)
4868 {
4869 status=MagickFalse;
4870 break;
4871 }
cristy50e64b82012-06-22 17:46:19 +00004872 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004873 {
cristycf1296e2012-08-26 23:40:49 +00004874 channel=GetPixelChannelChannel(source,i);
4875 traits=GetPixelChannelTraits(source,channel);
4876 destination_traits=GetPixelChannelTraits(destination,channel);
cristy5c4e2582011-09-11 19:21:03 +00004877 if ((traits == UndefinedPixelTrait) ||
4878 (destination_traits == UndefinedPixelTrait))
4879 continue;
cristy4a7ae692011-12-14 12:24:11 +00004880 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004881 }
4882 break;
4883 }
anthonycf4e33d2012-06-08 07:33:23 +00004884 case NearestInterpolatePixel:
cristy5c4e2582011-09-11 19:21:03 +00004885 {
anthonycf4e33d2012-06-08 07:33:23 +00004886 x_offset=(ssize_t) floor(x+0.5);
4887 y_offset=(ssize_t) floor(y+0.5);
4888 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
cristy5c4e2582011-09-11 19:21:03 +00004889 if (p == (const Quantum *) NULL)
4890 {
4891 status=MagickFalse;
4892 break;
4893 }
cristy50e64b82012-06-22 17:46:19 +00004894 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004895 {
cristycf1296e2012-08-26 23:40:49 +00004896 channel=GetPixelChannelChannel(source,i);
4897 traits=GetPixelChannelTraits(source,channel);
4898 destination_traits=GetPixelChannelTraits(destination,channel);
cristy5c4e2582011-09-11 19:21:03 +00004899 if ((traits == UndefinedPixelTrait) ||
4900 (destination_traits == UndefinedPixelTrait))
4901 continue;
cristy4a7ae692011-12-14 12:24:11 +00004902 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004903 }
4904 break;
4905 }
4906 case MeshInterpolatePixel:
4907 {
4908 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4909 if (p == (const Quantum *) NULL)
4910 {
4911 status=MagickFalse;
4912 break;
4913 }
cristy50e64b82012-06-22 17:46:19 +00004914 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004915 {
4916 PointInfo
4917 delta,
4918 luminance;
4919
cristycf1296e2012-08-26 23:40:49 +00004920 channel=GetPixelChannelChannel(source,i);
4921 traits=GetPixelChannelTraits(source,channel);
4922 destination_traits=GetPixelChannelTraits(destination,channel);
cristy5c4e2582011-09-11 19:21:03 +00004923 if ((traits == UndefinedPixelTrait) ||
4924 (destination_traits == UndefinedPixelTrait))
4925 continue;
cristya19f1d72012-08-07 18:24:38 +00004926 pixels[0]=(double) p[i];
4927 pixels[1]=(double) p[GetPixelChannels(source)+i];
4928 pixels[2]=(double) p[2*GetPixelChannels(source)+i];
4929 pixels[3]=(double) p[3*GetPixelChannels(source)+i];
cristy1861c902011-12-14 02:30:00 +00004930 if ((traits & BlendPixelTrait) == 0)
4931 {
4932 alpha[0]=1.0;
4933 alpha[1]=1.0;
4934 alpha[2]=1.0;
4935 alpha[3]=1.0;
4936 }
4937 else
4938 {
4939 alpha[0]=QuantumScale*GetPixelAlpha(source,p);
4940 alpha[1]=QuantumScale*GetPixelAlpha(source,p+
4941 GetPixelChannels(source));
4942 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
4943 GetPixelChannels(source));
4944 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
4945 GetPixelChannels(source));
4946 }
4947 delta.x=x-x_offset;
4948 delta.y=y-y_offset;
cristyfb122372012-10-17 23:31:21 +00004949 luminance.x=fabs((double) (GetPixelLuminance(source,p)-
4950 GetPixelLuminance(source,p+3*GetPixelChannels(source))));
4951 luminance.y=fabs((double) (GetPixelLuminance(source,p+
4952 GetPixelChannels(source))-GetPixelLuminance(source,p+2*
4953 GetPixelChannels(source))));
anthonycf4e33d2012-06-08 07:33:23 +00004954 if (luminance.x < luminance.y)
cristy1861c902011-12-14 02:30:00 +00004955 {
4956 /*
4957 Diagonal 0-3 NW-SE.
4958 */
4959 if (delta.x <= delta.y)
4960 {
4961 /*
4962 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4963 */
4964 delta.y=1.0-delta.y;
4965 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
cristy3e3ec3a2012-11-03 23:11:06 +00004966 gamma=PerceptibleReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00004967 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4968 MeshInterpolate(&delta,pixels[2],pixels[3],pixels[0])),pixel);
cristy1861c902011-12-14 02:30:00 +00004969 }
4970 else
4971 {
4972 /*
4973 Top-right triangle (pixel: 1, diagonal: 0-3).
4974 */
4975 delta.x=1.0-delta.x;
4976 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
cristy3e3ec3a2012-11-03 23:11:06 +00004977 gamma=PerceptibleReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00004978 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4979 MeshInterpolate(&delta,pixels[1],pixels[0],pixels[3])),pixel);
cristy1861c902011-12-14 02:30:00 +00004980 }
4981 }
4982 else
4983 {
4984 /*
4985 Diagonal 1-2 NE-SW.
4986 */
4987 if (delta.x <= (1.0-delta.y))
4988 {
4989 /*
4990 Top-left triangle (pixel: 0, diagonal: 1-2).
4991 */
4992 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
cristy3e3ec3a2012-11-03 23:11:06 +00004993 gamma=PerceptibleReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00004994 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4995 MeshInterpolate(&delta,pixels[0],pixels[1],pixels[2])),pixel);
cristy1861c902011-12-14 02:30:00 +00004996 }
4997 else
4998 {
4999 /*
5000 Bottom-right triangle (pixel: 3, diagonal: 1-2).
5001 */
5002 delta.x=1.0-delta.x;
5003 delta.y=1.0-delta.y;
5004 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
cristy3e3ec3a2012-11-03 23:11:06 +00005005 gamma=PerceptibleReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00005006 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5007 MeshInterpolate(&delta,pixels[3],pixels[2],pixels[1])),pixel);
cristy1861c902011-12-14 02:30:00 +00005008 }
5009 }
cristy5c4e2582011-09-11 19:21:03 +00005010 }
5011 break;
5012 }
5013 case SplineInterpolatePixel:
5014 {
cristya19f1d72012-08-07 18:24:38 +00005015 double
nicolasd32d5e52012-06-12 15:34:10 +00005016 cx[4],
5017 cy[4];
5018
cristy5c4e2582011-09-11 19:21:03 +00005019 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
5020 exception);
5021 if (p == (const Quantum *) NULL)
5022 {
5023 status=MagickFalse;
5024 break;
5025 }
cristy50e64b82012-06-22 17:46:19 +00005026 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00005027 {
cristy5c4e2582011-09-11 19:21:03 +00005028 register ssize_t
5029 j;
5030
cristycf1296e2012-08-26 23:40:49 +00005031 channel=GetPixelChannelChannel(source,i);
5032 traits=GetPixelChannelTraits(source,channel);
5033 destination_traits=GetPixelChannelTraits(destination,channel);
cristy5c4e2582011-09-11 19:21:03 +00005034 if ((traits == UndefinedPixelTrait) ||
5035 (destination_traits == UndefinedPixelTrait))
5036 continue;
5037 if ((traits & BlendPixelTrait) == 0)
5038 for (j=0; j < 16; j++)
5039 {
5040 alpha[j]=1.0;
cristya19f1d72012-08-07 18:24:38 +00005041 pixels[j]=(double) p[j*GetPixelChannels(source)+i];
cristy5c4e2582011-09-11 19:21:03 +00005042 }
5043 else
5044 for (j=0; j < 16; j++)
5045 {
5046 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
5047 GetPixelChannels(source));
5048 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
5049 }
cristya19f1d72012-08-07 18:24:38 +00005050 SplineWeights((double) (x-x_offset),&cx);
5051 SplineWeights((double) (y-y_offset),&cy);
5052 gamma=((traits & BlendPixelTrait) ? (double) (1.0) :
cristy3e3ec3a2012-11-03 23:11:06 +00005053 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
nicolasd32d5e52012-06-12 15:34:10 +00005054 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
5055 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
5056 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
5057 cx[2]*alpha[14]+cx[3]*alpha[15])));
5058 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]*
5059 pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]*
5060 (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+
5061 cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*
5062 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*
5063 pixels[14]+cx[3]*pixels[15]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00005064 }
5065 break;
5066 }
5067 }
5068 return(status);
5069}
5070
5071/*
5072%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5073% %
5074% %
5075% %
cristy9075cdb2011-07-30 01:06:23 +00005076% 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 +00005077% %
5078% %
5079% %
5080%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5081%
cristy884f6002011-07-31 00:51:45 +00005082% InterpolatePixelInfo() applies a pixel interpolation method between a
5083% floating point coordinate and the pixels surrounding that coordinate. No
5084% pixel area resampling, or scaling of the result is performed.
cristy4c08aed2011-07-01 19:47:50 +00005085%
anthonycf4e33d2012-06-08 07:33:23 +00005086% Interpolation is restricted to just RGBKA channels.
5087%
cristy4c08aed2011-07-01 19:47:50 +00005088% The format of the InterpolatePixelInfo method is:
5089%
5090% MagickBooleanType InterpolatePixelInfo(const Image *image,
cristy5c4e2582011-09-11 19:21:03 +00005091% const CacheView *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00005092% const double x,const double y,PixelInfo *pixel,
5093% ExceptionInfo *exception)
5094%
5095% A description of each parameter follows:
5096%
5097% o image: the image.
5098%
5099% o image_view: the image view.
5100%
5101% o method: the pixel color interpolation method.
5102%
5103% o x,y: A double representing the current (x,y) position of the pixel.
5104%
5105% o pixel: return the interpolated pixel here.
5106%
5107% o exception: return any errors or warnings in this structure.
5108%
5109*/
5110
5111static inline void AlphaBlendPixelInfo(const Image *image,
cristya19f1d72012-08-07 18:24:38 +00005112 const Quantum *pixel,PixelInfo *pixel_info,double *alpha)
cristy4c08aed2011-07-01 19:47:50 +00005113{
cristy8a46d822012-08-28 23:32:39 +00005114 if (image->alpha_trait != BlendPixelTrait)
cristy4c08aed2011-07-01 19:47:50 +00005115 {
5116 *alpha=1.0;
cristya19f1d72012-08-07 18:24:38 +00005117 pixel_info->red=(double) GetPixelRed(image,pixel);
5118 pixel_info->green=(double) GetPixelGreen(image,pixel);
5119 pixel_info->blue=(double) GetPixelBlue(image,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005120 pixel_info->black=0.0;
5121 if (image->colorspace == CMYKColorspace)
cristya19f1d72012-08-07 18:24:38 +00005122 pixel_info->black=(double) GetPixelBlack(image,pixel);
5123 pixel_info->alpha=(double) GetPixelAlpha(image,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005124 return;
5125 }
5126 *alpha=QuantumScale*GetPixelAlpha(image,pixel);
5127 pixel_info->red=(*alpha*GetPixelRed(image,pixel));
5128 pixel_info->green=(*alpha*GetPixelGreen(image,pixel));
5129 pixel_info->blue=(*alpha*GetPixelBlue(image,pixel));
5130 pixel_info->black=0.0;
5131 if (image->colorspace == CMYKColorspace)
5132 pixel_info->black=(*alpha*GetPixelBlack(image,pixel));
cristya19f1d72012-08-07 18:24:38 +00005133 pixel_info->alpha=(double) GetPixelAlpha(image,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005134}
5135
cristy4c08aed2011-07-01 19:47:50 +00005136MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
cristy5c4e2582011-09-11 19:21:03 +00005137 const CacheView *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00005138 const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception)
5139{
5140 MagickBooleanType
5141 status;
5142
cristya19f1d72012-08-07 18:24:38 +00005143 double
cristy4c08aed2011-07-01 19:47:50 +00005144 alpha[16],
5145 gamma;
5146
cristy865d58d2011-07-09 00:44:52 +00005147 PixelInfo
5148 pixels[16];
5149
cristy4c08aed2011-07-01 19:47:50 +00005150 register const Quantum
5151 *p;
5152
cristy50e64b82012-06-22 17:46:19 +00005153 register ssize_t
cristy4c08aed2011-07-01 19:47:50 +00005154 i;
5155
5156 ssize_t
5157 x_offset,
5158 y_offset;
5159
anthonycf4e33d2012-06-08 07:33:23 +00005160 PixelInterpolateMethod
5161 interpolate;
5162
cristy4c08aed2011-07-01 19:47:50 +00005163 assert(image != (Image *) NULL);
5164 assert(image->signature == MagickSignature);
5165 assert(image_view != (CacheView *) NULL);
5166 status=MagickTrue;
5167 x_offset=(ssize_t) floor(x);
5168 y_offset=(ssize_t) floor(y);
anthonycf4e33d2012-06-08 07:33:23 +00005169 interpolate = method;
5170 if ( interpolate == UndefinedInterpolatePixel )
5171 interpolate = image->interpolate;
5172 switch (interpolate)
cristy4c08aed2011-07-01 19:47:50 +00005173 {
anthonycf4e33d2012-06-08 07:33:23 +00005174 case AverageInterpolatePixel: /* nearest 4 neighbours */
5175 case Average9InterpolatePixel: /* nearest 9 neighbours */
5176 case Average16InterpolatePixel: /* nearest 16 neighbours */
cristy4c08aed2011-07-01 19:47:50 +00005177 {
cristyfb122372012-10-17 23:31:21 +00005178 ssize_t
5179 count;
anthonycf4e33d2012-06-08 07:33:23 +00005180
cristyfb122372012-10-17 23:31:21 +00005181 count=2; /* size of the area to average - default nearest 4 */
anthonycf4e33d2012-06-08 07:33:23 +00005182 if (interpolate == Average9InterpolatePixel)
5183 {
5184 count=3;
5185 x_offset=(ssize_t) (floor(x+0.5)-1);
5186 y_offset=(ssize_t) (floor(y+0.5)-1);
5187 }
5188 else if (interpolate == Average16InterpolatePixel)
5189 {
5190 count=4;
5191 x_offset--;
5192 y_offset--;
5193 }
5194 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,count,count,
cristy4c08aed2011-07-01 19:47:50 +00005195 exception);
5196 if (p == (const Quantum *) NULL)
5197 {
5198 status=MagickFalse;
5199 break;
5200 }
cristy4c08aed2011-07-01 19:47:50 +00005201 pixel->red=0.0;
5202 pixel->green=0.0;
5203 pixel->blue=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005204 pixel->black=0.0;
cristy865d58d2011-07-09 00:44:52 +00005205 pixel->alpha=0.0;
anthonycf4e33d2012-06-08 07:33:23 +00005206 count*=count; /* number of pixels - square of size */
cristy50e64b82012-06-22 17:46:19 +00005207 for (i=0; i < (ssize_t) count; i++)
cristy4c08aed2011-07-01 19:47:50 +00005208 {
anthonycf4e33d2012-06-08 07:33:23 +00005209 AlphaBlendPixelInfo(image,p,pixels,alpha);
cristy3e3ec3a2012-11-03 23:11:06 +00005210 gamma=PerceptibleReciprocal(alpha[0]);
cristyfb122372012-10-17 23:31:21 +00005211 pixel->red+=gamma*pixels[0].red;
5212 pixel->green+=gamma*pixels[0].green;
5213 pixel->blue+=gamma*pixels[0].blue;
5214 pixel->black+=gamma*pixels[0].black;
5215 pixel->alpha+=pixels[0].alpha;
anthonycf4e33d2012-06-08 07:33:23 +00005216 p += GetPixelChannels(image);
cristy4c08aed2011-07-01 19:47:50 +00005217 }
anthonycf4e33d2012-06-08 07:33:23 +00005218 gamma=1.0/count; /* average weighting of each pixel in area */
cristyfb122372012-10-17 23:31:21 +00005219 pixel->red*=gamma;
5220 pixel->green*=gamma;
5221 pixel->blue*=gamma;
5222 pixel->black*=gamma;
5223 pixel->alpha*=gamma;
cristy4c08aed2011-07-01 19:47:50 +00005224 break;
5225 }
anthonycf4e33d2012-06-08 07:33:23 +00005226 case BackgroundInterpolatePixel:
5227 {
cristyfb122372012-10-17 23:31:21 +00005228 *pixel=image->background_color; /* Copy PixelInfo Structure */
anthonycf4e33d2012-06-08 07:33:23 +00005229 break;
5230 }
5231 case BilinearInterpolatePixel:
5232 default:
5233 {
5234 PointInfo
5235 delta,
5236 epsilon;
5237
5238 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5239 if (p == (const Quantum *) NULL)
5240 {
5241 status=MagickFalse;
5242 break;
5243 }
5244 for (i=0; i < 4L; i++)
5245 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
5246 delta.x=x-x_offset;
5247 delta.y=y-y_offset;
5248 epsilon.x=1.0-delta.x;
5249 epsilon.y=1.0-delta.y;
5250 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
5251 (epsilon.x*alpha[2]+delta.x*alpha[3])));
cristy3e3ec3a2012-11-03 23:11:06 +00005252 gamma=PerceptibleReciprocal(gamma);
anthonycf4e33d2012-06-08 07:33:23 +00005253 pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x*
5254 pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red));
5255 pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x*
5256 pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x*
5257 pixels[3].green));
5258 pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x*
5259 pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x*
5260 pixels[3].blue));
5261 if (image->colorspace == CMYKColorspace)
5262 pixel->black=gamma*(epsilon.y*(epsilon.x*pixels[0].black+delta.x*
5263 pixels[1].black)+delta.y*(epsilon.x*pixels[2].black+delta.x*
5264 pixels[3].black));
5265 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
cristy3e3ec3a2012-11-03 23:11:06 +00005266 gamma=PerceptibleReciprocal(gamma);
anthonycf4e33d2012-06-08 07:33:23 +00005267 pixel->alpha=(epsilon.y*(epsilon.x*pixels[0].alpha+delta.x*
5268 pixels[1].alpha)+delta.y*(epsilon.x*pixels[2].alpha+delta.x*
5269 pixels[3].alpha));
5270 break;
5271 }
5272 case BlendInterpolatePixel:
5273 {
5274 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5275 if (p == (const Quantum *) NULL)
5276 {
5277 status=MagickFalse;
5278 break;
5279 }
5280 for (i=0; i < 4L; i++)
5281 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
cristyfb122372012-10-17 23:31:21 +00005282 gamma=1.0; /* number of pixels blended together (its variable) */
5283 for (i=0; i <= 1L; i++)
5284 {
5285 if ((y-y_offset) >= 0.75)
5286 {
5287 alpha[i]=alpha[i+2]; /* take right pixels */
5288 pixels[i]=pixels[i+2];
5289 }
5290 else
5291 if ((y-y_offset) > 0.25)
5292 {
5293 gamma=2.0; /* blend both pixels in row */
5294 alpha[i]+=alpha[i+2]; /* add up alpha weights */
5295 pixels[i].red+=pixels[i+2].red;
5296 pixels[i].green+=pixels[i+2].green;
5297 pixels[i].blue+=pixels[i+2].blue;
5298 pixels[i].black+=pixels[i+2].black;
5299 pixels[i].alpha+=pixels[i+2].alpha;
5300 }
5301 }
5302 if ((x-x_offset) >= 0.75)
5303 {
5304 alpha[0]=alpha[1];
5305 pixels[0]=pixels[1];
anthonycf4e33d2012-06-08 07:33:23 +00005306 }
cristyfb122372012-10-17 23:31:21 +00005307 else
5308 if ((x-x_offset) > 0.25)
5309 {
5310 gamma*=2.0; /* blend both rows */
5311 alpha[0]+= alpha[1]; /* add up alpha weights */
5312 pixels[0].red+=pixels[1].red;
5313 pixels[0].green+=pixels[1].green;
5314 pixels[0].blue+=pixels[1].blue;
5315 pixels[0].black+=pixels[1].black;
5316 pixels[0].alpha+=pixels[1].alpha;
5317 }
5318 gamma=1.0/gamma;
cristy3e3ec3a2012-11-03 23:11:06 +00005319 alpha[0]=PerceptibleReciprocal(alpha[0]);
cristyfb122372012-10-17 23:31:21 +00005320 pixel->red=alpha[0]*pixels[0].red;
5321 pixel->green=alpha[0]*pixels[0].green; /* divide by sum of alpha */
5322 pixel->blue=alpha[0]*pixels[0].blue;
5323 pixel->black=alpha[0]*pixels[0].black;
5324 pixel->alpha=gamma*pixels[0].alpha; /* divide by number of pixels */
anthonycf4e33d2012-06-08 07:33:23 +00005325 break;
5326 }
5327 case CatromInterpolatePixel:
cristy4c08aed2011-07-01 19:47:50 +00005328 {
cristya19f1d72012-08-07 18:24:38 +00005329 double
cristy380a11c2012-06-02 15:15:22 +00005330 cx[4],
5331 cy[4];
cristy4c08aed2011-07-01 19:47:50 +00005332
cristy4c08aed2011-07-01 19:47:50 +00005333 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5334 exception);
5335 if (p == (const Quantum *) NULL)
5336 {
5337 status=MagickFalse;
5338 break;
5339 }
anthonycf4e33d2012-06-08 07:33:23 +00005340 for (i=0; i < 16L; i++)
5341 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
cristya19f1d72012-08-07 18:24:38 +00005342 CatromWeights((double) (x-x_offset),&cx);
5343 CatromWeights((double) (y-y_offset),&cy);
cristyfb122372012-10-17 23:31:21 +00005344 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*pixels[1].red+cx[2]*
5345 pixels[2].red+cx[3]*pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
5346 pixels[5].red+cx[2]*pixels[6].red+cx[3]*pixels[7].red)+cy[2]*(cx[0]*
5347 pixels[8].red+cx[1]*pixels[9].red+cx[2]*pixels[10].red+cx[3]*
5348 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*pixels[13].red+cx[2]*
5349 pixels[14].red+cx[3]*pixels[15].red));
5350 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*pixels[1].green+cx[2]*
5351 pixels[2].green+cx[3]*pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+
5352 cx[1]*pixels[5].green+cx[2]*pixels[6].green+cx[3]*pixels[7].green)+
5353 cy[2]*(cx[0]*pixels[8].green+cx[1]*pixels[9].green+cx[2]*
5354 pixels[10].green+cx[3]*pixels[11].green)+cy[3]*(cx[0]*
5355 pixels[12].green+cx[1]*pixels[13].green+cx[2]*pixels[14].green+cx[3]*
5356 pixels[15].green));
5357 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*pixels[1].blue+cx[2]*
5358 pixels[2].blue+cx[3]*pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]*
5359 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*pixels[7].blue)+cy[2]*(cx[0]*
5360 pixels[8].blue+cx[1]*pixels[9].blue+cx[2]*pixels[10].blue+cx[3]*
5361 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*pixels[13].blue+
5362 cx[2]*pixels[14].blue+cx[3]*pixels[15].blue));
cristy380a11c2012-06-02 15:15:22 +00005363 if (image->colorspace == CMYKColorspace)
cristyfb122372012-10-17 23:31:21 +00005364 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*pixels[1].black+cx[2]*
5365 pixels[2].black+cx[3]*pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+
5366 cx[1]*pixels[5].black+cx[2]*pixels[6].black+cx[3]*pixels[7].black)+
5367 cy[2]*(cx[0]*pixels[8].black+cx[1]*pixels[9].black+cx[2]*
5368 pixels[10].black+cx[3]*pixels[11].black)+cy[3]*(cx[0]*
5369 pixels[12].black+cx[1]*pixels[13].black+cx[2]*pixels[14].black+cx[3]*
5370 pixels[15].black));
5371 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*pixels[1].alpha+cx[2]*
5372 pixels[2].alpha+cx[3]*pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+
5373 cx[1]*pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*pixels[7].alpha)+
5374 cy[2]*(cx[0]*pixels[8].alpha+cx[1]*pixels[9].alpha+cx[2]*
5375 pixels[10].alpha+cx[3]*pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+
5376 cx[1]*pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha));
cristy4c08aed2011-07-01 19:47:50 +00005377 break;
5378 }
anthonycf4e33d2012-06-08 07:33:23 +00005379#if 0
nicolas20075dc2012-06-12 20:47:38 +00005380 /* deprecated useless and very slow interpolator */
cristy4c08aed2011-07-01 19:47:50 +00005381 case FilterInterpolatePixel:
5382 {
5383 CacheView
5384 *filter_view;
5385
5386 Image
5387 *excerpt_image,
5388 *filter_image;
5389
5390 RectangleInfo
5391 geometry;
5392
5393 geometry.width=4L;
5394 geometry.height=4L;
5395 geometry.x=x_offset-1;
5396 geometry.y=y_offset-1;
5397 excerpt_image=ExcerptImage(image,&geometry,exception);
5398 if (excerpt_image == (Image *) NULL)
5399 {
5400 status=MagickFalse;
5401 break;
5402 }
cristyaa2c16c2012-03-25 22:21:35 +00005403 filter_image=ResizeImage(excerpt_image,1,1,image->filter,exception);
cristy4c08aed2011-07-01 19:47:50 +00005404 excerpt_image=DestroyImage(excerpt_image);
5405 if (filter_image == (Image *) NULL)
5406 break;
cristydb070952012-04-20 14:33:00 +00005407 filter_view=AcquireVirtualCacheView(filter_image,exception);
cristy4c08aed2011-07-01 19:47:50 +00005408 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
5409 if (p != (const Quantum *) NULL)
cristy803640d2011-11-17 02:11:32 +00005410 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005411 filter_view=DestroyCacheView(filter_view);
5412 filter_image=DestroyImage(filter_image);
5413 break;
5414 }
anthonycf4e33d2012-06-08 07:33:23 +00005415#endif
cristy4c08aed2011-07-01 19:47:50 +00005416 case IntegerInterpolatePixel:
5417 {
5418 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
5419 if (p == (const Quantum *) NULL)
5420 {
5421 status=MagickFalse;
5422 break;
5423 }
cristy803640d2011-11-17 02:11:32 +00005424 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005425 break;
5426 }
5427 case MeshInterpolatePixel:
5428 {
5429 PointInfo
5430 delta,
5431 luminance;
5432
cristy94ea1632011-07-30 20:40:25 +00005433 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
cristy4c08aed2011-07-01 19:47:50 +00005434 if (p == (const Quantum *) NULL)
5435 {
5436 status=MagickFalse;
5437 break;
5438 }
cristy94ea1632011-07-30 20:40:25 +00005439 delta.x=x-x_offset;
5440 delta.y=y-y_offset;
cristy884f6002011-07-31 00:51:45 +00005441 luminance.x=GetPixelLuminance(image,p)-(double)
cristy94ea1632011-07-30 20:40:25 +00005442 GetPixelLuminance(image,p+3*GetPixelChannels(image));
cristy28474bf2011-09-11 23:32:52 +00005443 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
cristy94ea1632011-07-30 20:40:25 +00005444 GetPixelLuminance(image,p+2*GetPixelChannels(image));
cristy5ce8df82011-07-07 14:52:23 +00005445 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005446 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005447 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5448 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
cristy4c08aed2011-07-01 19:47:50 +00005449 if (fabs(luminance.x) < fabs(luminance.y))
5450 {
5451 /*
5452 Diagonal 0-3 NW-SE.
5453 */
5454 if (delta.x <= delta.y)
5455 {
5456 /*
cristy94ea1632011-07-30 20:40:25 +00005457 Bottom-left triangle (pixel: 2, diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005458 */
5459 delta.y=1.0-delta.y;
5460 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
cristy3e3ec3a2012-11-03 23:11:06 +00005461 gamma=PerceptibleReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005462 pixel->red=gamma*MeshInterpolate(&delta,pixels[2].red,
5463 pixels[3].red,pixels[0].red);
5464 pixel->green=gamma*MeshInterpolate(&delta,pixels[2].green,
5465 pixels[3].green,pixels[0].green);
5466 pixel->blue=gamma*MeshInterpolate(&delta,pixels[2].blue,
5467 pixels[3].blue,pixels[0].blue);
cristy4c08aed2011-07-01 19:47:50 +00005468 if (image->colorspace == CMYKColorspace)
5469 pixel->black=gamma*MeshInterpolate(&delta,pixels[2].black,
5470 pixels[3].black,pixels[0].black);
cristy94ea1632011-07-30 20:40:25 +00005471 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005472 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[2].alpha,
5473 pixels[3].alpha,pixels[0].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005474 }
5475 else
5476 {
5477 /*
cristy94ea1632011-07-30 20:40:25 +00005478 Top-right triangle (pixel:1 , diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005479 */
5480 delta.x=1.0-delta.x;
5481 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
cristy3e3ec3a2012-11-03 23:11:06 +00005482 gamma=PerceptibleReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005483 pixel->red=gamma*MeshInterpolate(&delta,pixels[1].red,
5484 pixels[0].red,pixels[3].red);
5485 pixel->green=gamma*MeshInterpolate(&delta,pixels[1].green,
5486 pixels[0].green,pixels[3].green);
5487 pixel->blue=gamma*MeshInterpolate(&delta,pixels[1].blue,
5488 pixels[0].blue,pixels[3].blue);
cristy4c08aed2011-07-01 19:47:50 +00005489 if (image->colorspace == CMYKColorspace)
5490 pixel->black=gamma*MeshInterpolate(&delta,pixels[1].black,
5491 pixels[0].black,pixels[3].black);
cristy94ea1632011-07-30 20:40:25 +00005492 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005493 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[1].alpha,
5494 pixels[0].alpha,pixels[3].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005495 }
5496 }
5497 else
5498 {
5499 /*
5500 Diagonal 1-2 NE-SW.
5501 */
5502 if (delta.x <= (1.0-delta.y))
5503 {
5504 /*
cristy94ea1632011-07-30 20:40:25 +00005505 Top-left triangle (pixel: 0, diagonal: 1-2).
cristy4c08aed2011-07-01 19:47:50 +00005506 */
5507 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
cristy3e3ec3a2012-11-03 23:11:06 +00005508 gamma=PerceptibleReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005509 pixel->red=gamma*MeshInterpolate(&delta,pixels[0].red,
5510 pixels[1].red,pixels[2].red);
5511 pixel->green=gamma*MeshInterpolate(&delta,pixels[0].green,
5512 pixels[1].green,pixels[2].green);
5513 pixel->blue=gamma*MeshInterpolate(&delta,pixels[0].blue,
5514 pixels[1].blue,pixels[2].blue);
cristy4c08aed2011-07-01 19:47:50 +00005515 if (image->colorspace == CMYKColorspace)
5516 pixel->black=gamma*MeshInterpolate(&delta,pixels[0].black,
5517 pixels[1].black,pixels[2].black);
cristy94ea1632011-07-30 20:40:25 +00005518 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005519 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[0].alpha,
5520 pixels[1].alpha,pixels[2].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005521 }
5522 else
5523 {
5524 /*
5525 Bottom-right triangle (pixel: 3, diagonal: 1-2).
5526 */
5527 delta.x=1.0-delta.x;
5528 delta.y=1.0-delta.y;
5529 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
cristy3e3ec3a2012-11-03 23:11:06 +00005530 gamma=PerceptibleReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005531 pixel->red=gamma*MeshInterpolate(&delta,pixels[3].red,
5532 pixels[2].red,pixels[1].red);
5533 pixel->green=gamma*MeshInterpolate(&delta,pixels[3].green,
5534 pixels[2].green,pixels[1].green);
5535 pixel->blue=gamma*MeshInterpolate(&delta,pixels[3].blue,
5536 pixels[2].blue,pixels[1].blue);
cristy4c08aed2011-07-01 19:47:50 +00005537 if (image->colorspace == CMYKColorspace)
5538 pixel->black=gamma*MeshInterpolate(&delta,pixels[3].black,
5539 pixels[2].black,pixels[1].black);
cristy94ea1632011-07-30 20:40:25 +00005540 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005541 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[3].alpha,
5542 pixels[2].alpha,pixels[1].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005543 }
5544 }
5545 break;
5546 }
anthonycf4e33d2012-06-08 07:33:23 +00005547 case NearestInterpolatePixel:
cristy4c08aed2011-07-01 19:47:50 +00005548 {
anthonycf4e33d2012-06-08 07:33:23 +00005549 x_offset=(ssize_t) floor(x+0.5);
5550 y_offset=(ssize_t) floor(y+0.5);
5551 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00005552 if (p == (const Quantum *) NULL)
5553 {
5554 status=MagickFalse;
5555 break;
5556 }
cristy803640d2011-11-17 02:11:32 +00005557 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005558 break;
5559 }
5560 case SplineInterpolatePixel:
5561 {
cristya19f1d72012-08-07 18:24:38 +00005562 double
nicolasd32d5e52012-06-12 15:34:10 +00005563 cx[4],
5564 cy[4];
cristy4c08aed2011-07-01 19:47:50 +00005565
5566 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5567 exception);
5568 if (p == (const Quantum *) NULL)
5569 {
5570 status=MagickFalse;
5571 break;
5572 }
anthonycf4e33d2012-06-08 07:33:23 +00005573 for (i=0; i < 16L; i++)
5574 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
cristya19f1d72012-08-07 18:24:38 +00005575 SplineWeights((double) (x-x_offset),&cx);
5576 SplineWeights((double) (y-y_offset),&cy);
cristyfb122372012-10-17 23:31:21 +00005577 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*pixels[1].red+cx[2]*
5578 pixels[2].red+cx[3]*pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
5579 pixels[5].red+cx[2]*pixels[6].red+cx[3]*pixels[7].red)+cy[2]*(cx[0]*
5580 pixels[8].red+cx[1]*pixels[9].red+cx[2]*pixels[10].red+cx[3]*
5581 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*pixels[13].red+cx[2]*
5582 pixels[14].red+cx[3]*pixels[15].red));
5583 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*pixels[1].green+cx[2]*
5584 pixels[2].green+cx[3]*pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+
5585 cx[1]*pixels[5].green+cx[2]*pixels[6].green+cx[3]*pixels[7].green)+
5586 cy[2]*(cx[0]*pixels[8].green+cx[1]*pixels[9].green+cx[2]*
5587 pixels[10].green+cx[3]*pixels[11].green)+cy[3]*(cx[0]*pixels[12].green+
5588 cx[1]*pixels[13].green+cx[2]*pixels[14].green+cx[3]*pixels[15].green));
5589 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*pixels[1].blue+cx[2]*
5590 pixels[2].blue+cx[3]*pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]*
5591 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*pixels[7].blue)+cy[2]*(cx[0]*
5592 pixels[8].blue+cx[1]*pixels[9].blue+cx[2]*pixels[10].blue+cx[3]*
5593 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*pixels[13].blue+
5594 cx[2]*pixels[14].blue+cx[3]*pixels[15].blue));
nicolasd32d5e52012-06-12 15:34:10 +00005595 if (image->colorspace == CMYKColorspace)
cristyfb122372012-10-17 23:31:21 +00005596 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*pixels[1].black+cx[2]*
5597 pixels[2].black+cx[3]*pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+
5598 cx[1]*pixels[5].black+cx[2]*pixels[6].black+cx[3]*pixels[7].black)+
5599 cy[2]*(cx[0]*pixels[8].black+cx[1]*pixels[9].black+cx[2]*
5600 pixels[10].black+cx[3]*pixels[11].black)+cy[3]*(cx[0]*
5601 pixels[12].black+cx[1]*pixels[13].black+cx[2]*pixels[14].black+cx[3]*
5602 pixels[15].black));
5603 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*pixels[1].alpha+cx[2]*
5604 pixels[2].alpha+cx[3]*pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+
5605 cx[1]*pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*pixels[7].alpha)+
5606 cy[2]*(cx[0]*pixels[8].alpha+cx[1]*pixels[9].alpha+cx[2]*
5607 pixels[10].alpha+cx[3]*pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+
5608 cx[1]*pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha));
cristy4c08aed2011-07-01 19:47:50 +00005609 break;
5610 }
5611 }
5612 return(status);
5613}
5614
5615/*
5616%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5617% %
5618% %
5619% %
5620+ I s F u z z y E q u i v a l e n c e P i x e l %
5621% %
5622% %
5623% %
5624%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5625%
5626% IsFuzzyEquivalencePixel() returns MagickTrue if the distance between two
5627% pixels is less than the specified distance in a linear three (or four)u
5628% dimensional color space.
5629%
5630% The format of the IsFuzzyEquivalencePixel method is:
5631%
cristye4a40472011-12-22 02:56:19 +00005632% void IsFuzzyEquivalencePixel(const Image *source,const Quantum *p,
5633% const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005634%
5635% A description of each parameter follows:
5636%
cristye4a40472011-12-22 02:56:19 +00005637% o source: the source image.
cristy4c08aed2011-07-01 19:47:50 +00005638%
5639% o p: Pixel p.
5640%
cristye4a40472011-12-22 02:56:19 +00005641% o destination: the destination image.
5642%
cristy4c08aed2011-07-01 19:47:50 +00005643% o q: Pixel q.
5644%
5645*/
cristye4a40472011-12-22 02:56:19 +00005646MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source,
5647 const Quantum *p,const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005648{
cristya19f1d72012-08-07 18:24:38 +00005649 double
cristy4c08aed2011-07-01 19:47:50 +00005650 fuzz,
5651 pixel;
5652
cristya19f1d72012-08-07 18:24:38 +00005653 register double
cristy4c08aed2011-07-01 19:47:50 +00005654 distance,
5655 scale;
5656
cristya19f1d72012-08-07 18:24:38 +00005657 fuzz=MagickMax(source->fuzz,(double) MagickSQ1_2)*MagickMax(
5658 destination->fuzz,(double) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005659 scale=1.0;
5660 distance=0.0;
cristy8a46d822012-08-28 23:32:39 +00005661 if (source->alpha_trait == BlendPixelTrait)
cristy4c08aed2011-07-01 19:47:50 +00005662 {
5663 /*
5664 Transparencies are involved - set alpha distance
5665 */
cristya19f1d72012-08-07 18:24:38 +00005666 pixel=GetPixelAlpha(source,p)-(double)
cristy99abff32011-12-24 20:45:16 +00005667 GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005668 distance=pixel*pixel;
5669 if (distance > fuzz)
5670 return(MagickFalse);
5671 /*
5672 Generate a alpha scaling factor to generate a 4D cone on colorspace
5673 Note that if one color is transparent, distance has no color component.
5674 */
cristye4a40472011-12-22 02:56:19 +00005675 scale=QuantumScale*GetPixelAlpha(source,p);
5676 scale*=QuantumScale*GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005677 if (scale <= MagickEpsilon)
5678 return(MagickTrue);
5679 }
5680 /*
5681 RGB or CMY color cube
5682 */
5683 distance*=3.0; /* rescale appropriately */
5684 fuzz*=3.0;
cristya19f1d72012-08-07 18:24:38 +00005685 pixel=GetPixelRed(source,p)-(double) GetPixelRed(destination,q);
cristye4a40472011-12-22 02:56:19 +00005686 if ((source->colorspace == HSLColorspace) ||
5687 (source->colorspace == HSBColorspace) ||
5688 (source->colorspace == HWBColorspace))
cristy4c08aed2011-07-01 19:47:50 +00005689 {
5690 /*
5691 Compute an arc distance for hue. It should be a vector angle of
5692 'S'/'W' length with 'L'/'B' forming appropriate cones.
5693 */
5694 if (fabs((double) pixel) > (QuantumRange/2))
5695 pixel-=QuantumRange;
5696 pixel*=2;
5697 }
5698 distance+=scale*pixel*pixel;
5699 if (distance > fuzz)
5700 return(MagickFalse);
cristya19f1d72012-08-07 18:24:38 +00005701 pixel=GetPixelGreen(source,p)-(double) GetPixelGreen(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005702 distance+=scale*pixel*pixel;
5703 if (distance > fuzz)
5704 return(MagickFalse);
cristya19f1d72012-08-07 18:24:38 +00005705 pixel=GetPixelBlue(source,p)-(double) GetPixelBlue(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005706 distance+=scale*pixel*pixel;
5707 if (distance > fuzz)
5708 return(MagickFalse);
5709 return(MagickTrue);
5710}
5711
5712/*
5713%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5714% %
5715% %
5716% %
5717+ 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 %
5718% %
5719% %
5720% %
5721%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5722%
5723% IsFuzzyEquivalencePixelInfo() returns true if the distance between two
5724% colors is less than the specified distance in a linear three (or four)
5725% dimensional color space.
5726%
cristy5f95f4f2011-10-23 01:01:01 +00005727% This implements the equivalent of:
5728% fuzz < sqrt(color_distance^2 * u.a*v.a + alpha_distance^2)
cristy4c08aed2011-07-01 19:47:50 +00005729%
5730% Which produces a multi-dimensional cone for that colorspace along the
5731% transparency vector.
5732%
cristy5f95f4f2011-10-23 01:01:01 +00005733% For example for an RGB:
cristy4c08aed2011-07-01 19:47:50 +00005734% color_distance^2 = ( (u.r-v.r)^2 + (u.g-v.g)^2 + (u.b-v.b)^2 ) / 3
5735%
5736% See http://www.imagemagick.org/Usage/bugs/fuzz_distance/
5737%
5738% Hue colorspace distances need more work. Hue is not a distance, it is an
5739% angle!
5740%
5741% A check that q is in the same color space as p should be made and the
5742% appropriate mapping made. -- Anthony Thyssen 8 December 2010
5743%
5744% The format of the IsFuzzyEquivalencePixelInfo method is:
5745%
5746% MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5747% const PixelInfo *q)
5748%
5749% A description of each parameter follows:
5750%
5751% o p: Pixel p.
5752%
5753% o q: Pixel q.
5754%
5755*/
5756MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5757 const PixelInfo *q)
5758{
cristya19f1d72012-08-07 18:24:38 +00005759 double
cristy4c08aed2011-07-01 19:47:50 +00005760 fuzz,
5761 pixel;
5762
cristya19f1d72012-08-07 18:24:38 +00005763 register double
cristy4c08aed2011-07-01 19:47:50 +00005764 scale,
5765 distance;
5766
5767 if ((p->fuzz == 0.0) && (q->fuzz == 0.0))
5768 return(IsPixelInfoEquivalent(p,q));
5769 if (p->fuzz == 0.0)
cristya19f1d72012-08-07 18:24:38 +00005770 fuzz=MagickMax(q->fuzz,(double) MagickSQ1_2)*MagickMax(q->fuzz,
5771 (double) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005772 else if (q->fuzz == 0.0)
cristya19f1d72012-08-07 18:24:38 +00005773 fuzz=MagickMax(p->fuzz,(double) MagickSQ1_2)*MagickMax(p->fuzz,
5774 (double) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005775 else
cristya19f1d72012-08-07 18:24:38 +00005776 fuzz=MagickMax(p->fuzz,(double) MagickSQ1_2)*MagickMax(q->fuzz,
5777 (double) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005778 scale=1.0;
5779 distance=0.0;
cristy8a46d822012-08-28 23:32:39 +00005780 if ((p->alpha_trait == BlendPixelTrait) || (q->alpha_trait == BlendPixelTrait))
cristy4c08aed2011-07-01 19:47:50 +00005781 {
5782 /*
5783 Transparencies are involved - set alpha distance.
5784 */
cristy8a46d822012-08-28 23:32:39 +00005785 pixel=(p->alpha_trait == BlendPixelTrait ? p->alpha : OpaqueAlpha)-
5786 (q->alpha_trait == BlendPixelTrait ? q->alpha : OpaqueAlpha);
cristy4c08aed2011-07-01 19:47:50 +00005787 distance=pixel*pixel;
5788 if (distance > fuzz)
5789 return(MagickFalse);
5790 /*
5791 Generate a alpha scaling factor to generate a 4D cone on colorspace.
cristy5f95f4f2011-10-23 01:01:01 +00005792 If one color is transparent, distance has no color component.
cristy4c08aed2011-07-01 19:47:50 +00005793 */
cristy8a46d822012-08-28 23:32:39 +00005794 if (p->alpha_trait == BlendPixelTrait)
cristy4c08aed2011-07-01 19:47:50 +00005795 scale=(QuantumScale*p->alpha);
cristy8a46d822012-08-28 23:32:39 +00005796 if (q->alpha_trait == BlendPixelTrait)
cristy4c08aed2011-07-01 19:47:50 +00005797 scale*=(QuantumScale*q->alpha);
5798 if (scale <= MagickEpsilon )
5799 return(MagickTrue);
5800 }
5801 /*
5802 CMYK create a CMY cube with a multi-dimensional cone toward black.
5803 */
5804 if (p->colorspace == CMYKColorspace)
5805 {
5806 pixel=p->black-q->black;
5807 distance+=pixel*pixel*scale;
5808 if (distance > fuzz)
5809 return(MagickFalse);
cristya19f1d72012-08-07 18:24:38 +00005810 scale*=(double) (QuantumScale*(QuantumRange-p->black));
5811 scale*=(double) (QuantumScale*(QuantumRange-q->black));
cristy4c08aed2011-07-01 19:47:50 +00005812 }
5813 /*
5814 RGB or CMY color cube.
5815 */
5816 distance*=3.0; /* rescale appropriately */
5817 fuzz*=3.0;
5818 pixel=p->red-q->red;
5819 if ((p->colorspace == HSLColorspace) || (p->colorspace == HSBColorspace) ||
5820 (p->colorspace == HWBColorspace))
5821 {
cristy5f95f4f2011-10-23 01:01:01 +00005822 /*
5823 This calculates a arc distance for hue-- it should be a vector angle
5824 of 'S'/'W' length with 'L'/'B' forming appropriate cones. In other
5825 words this is a hack - Anthony.
cristy4c08aed2011-07-01 19:47:50 +00005826 */
5827 if (fabs((double) pixel) > (QuantumRange/2))
5828 pixel-=QuantumRange;
5829 pixel*=2;
5830 }
5831 distance+=pixel*pixel*scale;
5832 if (distance > fuzz)
5833 return(MagickFalse);
5834 pixel=p->green-q->green;
5835 distance+=pixel*pixel*scale;
5836 if (distance > fuzz)
5837 return(MagickFalse);
5838 pixel=p->blue-q->blue;
5839 distance+=pixel*pixel*scale;
5840 if (distance > fuzz)
5841 return(MagickFalse);
5842 return(MagickTrue);
5843}
5844
5845/*
5846%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5847% %
5848% %
5849% %
cristye2a912b2011-12-05 20:02:07 +00005850% 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 +00005851% %
5852% %
5853% %
5854%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5855%
cristycf1296e2012-08-26 23:40:49 +00005856% SetPixelChannelMask() sets the pixel channel map from the specified
cristye2a912b2011-12-05 20:02:07 +00005857% channel mask.
cristy2b9582a2011-07-04 17:38:56 +00005858%
cristycf1296e2012-08-26 23:40:49 +00005859% The format of the SetPixelChannelMask method is:
cristy2b9582a2011-07-04 17:38:56 +00005860%
cristycf1296e2012-08-26 23:40:49 +00005861% void SetPixelChannelMask(Image *image,const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005862%
5863% A description of each parameter follows:
5864%
5865% o image: the image.
5866%
cristydfdb19e2012-03-21 22:22:24 +00005867% o channel_mask: the channel mask.
cristy2b9582a2011-07-04 17:38:56 +00005868%
5869*/
cristycf1296e2012-08-26 23:40:49 +00005870MagickExport void SetPixelChannelMask(Image *image,
cristy07a67852011-08-26 13:25:03 +00005871 const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005872{
cristy6a917d62011-08-24 17:31:30 +00005873#define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01)
cristydafd2872011-07-24 22:06:13 +00005874
cristy2b9582a2011-07-04 17:38:56 +00005875 register ssize_t
5876 i;
5877
cristy177e41c2012-04-15 15:08:25 +00005878 if (image->debug != MagickFalse)
5879 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%08x]", \
5880 image->filename,channel_mask); \
cristy3c309812011-11-08 02:40:43 +00005881 image->channel_mask=channel_mask;
cristydafd2872011-07-24 22:06:13 +00005882 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
cristye2a912b2011-12-05 20:02:07 +00005883 {
5884 PixelChannel
5885 channel;
5886
cristycf1296e2012-08-26 23:40:49 +00005887 channel=GetPixelChannelChannel(image,i);
cristy297e3a42012-08-26 21:27:29 +00005888 SetPixelChannelTraits(image,channel,
cristye2a912b2011-12-05 20:02:07 +00005889 GetChannelBit(channel_mask,channel) == 0 ? CopyPixelTrait :
cristy8a46d822012-08-28 23:32:39 +00005890 image->alpha_trait != BlendPixelTrait || (channel == AlphaPixelChannel) ?
5891 UpdatePixelTrait : (PixelTrait) (UpdatePixelTrait | image->alpha_trait));
cristye2a912b2011-12-05 20:02:07 +00005892 }
cristy1685e722011-09-06 00:04:19 +00005893 if (image->storage_class == PseudoClass)
cristy297e3a42012-08-26 21:27:29 +00005894 SetPixelChannelTraits(image,IndexPixelChannel,CopyPixelTrait);
cristy183a5c72012-01-30 01:40:35 +00005895 if (image->mask != MagickFalse)
cristy297e3a42012-08-26 21:27:29 +00005896 SetPixelChannelTraits(image,MaskPixelChannel,CopyPixelTrait);
cristy6dcb9b82011-10-23 23:21:25 +00005897 if (image->debug != MagickFalse)
5898 LogPixelChannels(image);
cristy2b9582a2011-07-04 17:38:56 +00005899}
5900
5901/*
5902%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5903% %
5904% %
5905% %
cristy322d07d2012-03-18 21:17:23 +00005906% S e t P i x e l M e t a C h a n n e l s %
5907% %
5908% %
5909% %
5910%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5911%
5912% SetPixelMetaChannels() sets the image meta channels.
5913%
5914% The format of the SetPixelMetaChannels method is:
5915%
5916% MagickBooleanType SetPixelMetaChannels(Image *image,
5917% const size_t number_meta_channels,ExceptionInfo *exception)
5918%
5919% A description of each parameter follows:
5920%
5921% o image: the image.
5922%
5923% o number_meta_channels: the number of meta channels.
5924%
5925% o exception: return any errors or warnings in this structure.
5926%
5927*/
5928MagickExport MagickBooleanType SetPixelMetaChannels(Image *image,
5929 const size_t number_meta_channels,ExceptionInfo *exception)
5930{
5931 image->number_meta_channels=number_meta_channels;
5932 return(SyncImagePixelCache(image,exception));
5933}