blob: 4f32a82816be1b6c6b44caf3225ec721772dfa1e [file] [log] [blame]
cristy4c08aed2011-07-01 19:47:50 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% PPPP IIIII X X EEEEE L %
7% P P I X X E L %
8% PPPP I X EEE L %
9% P I X X E L %
10% P IIIII X X EEEEE LLLLL %
11% %
12% MagickCore Methods to Import/Export Pixels %
13% %
14% Software Design %
15% John Cristy %
16% October 1998 %
17% %
18% %
cristy1454be72011-12-19 01:52:48 +000019% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
cristy4c08aed2011-07-01 19:47:50 +000020% dedicated to making software imaging solutions freely available. %
21% %
22% You may not use this file except in compliance with the License. You may %
23% obtain a copy of the License at %
24% %
25% http://www.imagemagick.org/script/license.php %
26% %
27% Unless required by applicable law or agreed to in writing, software %
28% distributed under the License is distributed on an "AS IS" BASIS, %
29% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30% See the License for the specific language governing permissions and %
31% limitations under the License. %
32% %
33%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34%
35%
36*/
37
38/*
39 Include declarations.
40*/
41#include "MagickCore/studio.h"
42#include "MagickCore/property.h"
43#include "MagickCore/blob.h"
44#include "MagickCore/blob-private.h"
cristy322d07d2012-03-18 21:17:23 +000045#include "MagickCore/cache-private.h"
cristy4c08aed2011-07-01 19:47:50 +000046#include "MagickCore/color-private.h"
47#include "MagickCore/draw.h"
48#include "MagickCore/exception.h"
49#include "MagickCore/exception-private.h"
50#include "MagickCore/cache.h"
51#include "MagickCore/constitute.h"
52#include "MagickCore/delegate.h"
53#include "MagickCore/geometry.h"
54#include "MagickCore/image-private.h"
55#include "MagickCore/list.h"
56#include "MagickCore/magick.h"
57#include "MagickCore/memory_.h"
58#include "MagickCore/monitor.h"
59#include "MagickCore/option.h"
60#include "MagickCore/pixel.h"
61#include "MagickCore/pixel-accessor.h"
cristy380a11c2012-06-02 15:15:22 +000062#include "MagickCore/pixel-private.h"
cristy4c08aed2011-07-01 19:47:50 +000063#include "MagickCore/quantum.h"
64#include "MagickCore/quantum-private.h"
65#include "MagickCore/resource_.h"
66#include "MagickCore/semaphore.h"
67#include "MagickCore/statistic.h"
68#include "MagickCore/stream.h"
69#include "MagickCore/string_.h"
70#include "MagickCore/transform.h"
71#include "MagickCore/utility.h"
72
cristy146a62b2011-10-23 23:40:46 +000073#define LogPixelChannels(image) \
74{ \
75 register ssize_t \
76 i; \
77 \
78 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%.20g]", \
79 image->filename,(double) image->number_channels); \
80 for (i=0; i < (ssize_t) image->number_channels; i++) \
81 { \
82 char \
83 traits[MaxTextExtent]; \
84 \
85 const char \
cristy46795722011-12-10 23:56:57 +000086 *name; \
87 \
88 PixelChannel \
89 channel; \
cristy146a62b2011-10-23 23:40:46 +000090 \
cristye2a912b2011-12-05 20:02:07 +000091 switch (GetPixelChannelMapChannel(image,i)) \
cristy146a62b2011-10-23 23:40:46 +000092 { \
93 case RedPixelChannel: \
94 { \
cristy46795722011-12-10 23:56:57 +000095 name="red"; \
cristy146a62b2011-10-23 23:40:46 +000096 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +000097 name="cyan"; \
cristy146a62b2011-10-23 23:40:46 +000098 if (image->colorspace == GRAYColorspace) \
cristy46795722011-12-10 23:56:57 +000099 name="gray"; \
cristy146a62b2011-10-23 23:40:46 +0000100 break; \
101 } \
102 case GreenPixelChannel: \
103 { \
cristy46795722011-12-10 23:56:57 +0000104 name="green"; \
cristy146a62b2011-10-23 23:40:46 +0000105 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +0000106 name="magenta"; \
cristy146a62b2011-10-23 23:40:46 +0000107 break; \
108 } \
109 case BluePixelChannel: \
110 { \
cristy46795722011-12-10 23:56:57 +0000111 name="blue"; \
cristy146a62b2011-10-23 23:40:46 +0000112 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +0000113 name="yellow"; \
cristy146a62b2011-10-23 23:40:46 +0000114 break; \
115 } \
116 case BlackPixelChannel: \
117 { \
cristy46795722011-12-10 23:56:57 +0000118 name="black"; \
cristy146a62b2011-10-23 23:40:46 +0000119 if (image->storage_class == PseudoClass) \
cristy46795722011-12-10 23:56:57 +0000120 name="index"; \
cristy146a62b2011-10-23 23:40:46 +0000121 break; \
122 } \
cristye2a912b2011-12-05 20:02:07 +0000123 case IndexPixelChannel: \
124 { \
cristy46795722011-12-10 23:56:57 +0000125 name="index"; \
cristye2a912b2011-12-05 20:02:07 +0000126 break; \
127 } \
cristy146a62b2011-10-23 23:40:46 +0000128 case AlphaPixelChannel: \
129 { \
cristy46795722011-12-10 23:56:57 +0000130 name="alpha"; \
cristy146a62b2011-10-23 23:40:46 +0000131 break; \
132 } \
133 case MaskPixelChannel: \
134 { \
cristy46795722011-12-10 23:56:57 +0000135 name="mask"; \
cristy146a62b2011-10-23 23:40:46 +0000136 break; \
137 } \
cristye2a912b2011-12-05 20:02:07 +0000138 case MetaPixelChannel: \
cristy146a62b2011-10-23 23:40:46 +0000139 { \
cristy46795722011-12-10 23:56:57 +0000140 name="meta"; \
cristye2a912b2011-12-05 20:02:07 +0000141 break; \
cristy146a62b2011-10-23 23:40:46 +0000142 } \
cristye2a912b2011-12-05 20:02:07 +0000143 default: \
cristy46795722011-12-10 23:56:57 +0000144 name="undefined"; \
cristy146a62b2011-10-23 23:40:46 +0000145 } \
cristy46795722011-12-10 23:56:57 +0000146 channel=GetPixelChannelMapChannel(image,i); \
cristy146a62b2011-10-23 23:40:46 +0000147 *traits='\0'; \
cristy46795722011-12-10 23:56:57 +0000148 if ((GetPixelChannelMapTraits(image,channel) & UpdatePixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000149 (void) ConcatenateMagickString(traits,"update,",MaxTextExtent); \
cristy46795722011-12-10 23:56:57 +0000150 if ((GetPixelChannelMapTraits(image,channel) & BlendPixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000151 (void) ConcatenateMagickString(traits,"blend,",MaxTextExtent); \
cristy46795722011-12-10 23:56:57 +0000152 if ((GetPixelChannelMapTraits(image,channel) & CopyPixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000153 (void) ConcatenateMagickString(traits,"copy,",MaxTextExtent); \
154 if (*traits == '\0') \
155 (void) ConcatenateMagickString(traits,"undefined,",MaxTextExtent); \
156 traits[strlen(traits)-1]='\0'; \
157 (void) LogMagickEvent(PixelEvent,GetMagickModule()," %.20g: %s (%s)", \
cristy46795722011-12-10 23:56:57 +0000158 (double) i,name,traits); \
cristy146a62b2011-10-23 23:40:46 +0000159 } \
160}
161
162/*
cristy4c08aed2011-07-01 19:47:50 +0000163%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164% %
165% %
166% %
cristyed231572011-07-14 02:18:59 +0000167+ A c q u i r e P i x e l C h a n n e l M a p %
cristy4c08aed2011-07-01 19:47:50 +0000168% %
169% %
170% %
171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172%
cristyed231572011-07-14 02:18:59 +0000173% AcquirePixelChannelMap() acquires a pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000174%
cristyed231572011-07-14 02:18:59 +0000175% The format of the AcquirePixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000176%
cristybd5a96c2011-08-21 00:04:26 +0000177% PixelChannelMap *AcquirePixelChannelMap(void)
cristy4c08aed2011-07-01 19:47:50 +0000178%
179*/
cristybd5a96c2011-08-21 00:04:26 +0000180MagickExport PixelChannelMap *AcquirePixelChannelMap(void)
cristy4c08aed2011-07-01 19:47:50 +0000181{
cristyed231572011-07-14 02:18:59 +0000182 PixelChannelMap
cristybd5a96c2011-08-21 00:04:26 +0000183 *channel_map;
cristy4c08aed2011-07-01 19:47:50 +0000184
185 register ssize_t
186 i;
187
cristybd5a96c2011-08-21 00:04:26 +0000188 channel_map=(PixelChannelMap *) AcquireQuantumMemory(MaxPixelChannels,
189 sizeof(*channel_map));
190 if (channel_map == (PixelChannelMap *) NULL)
cristy4c08aed2011-07-01 19:47:50 +0000191 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristybd5a96c2011-08-21 00:04:26 +0000192 (void) ResetMagickMemory(channel_map,0,MaxPixelChannels*sizeof(*channel_map));
193 for (i=0; i < MaxPixelChannels; i++)
194 channel_map[i].channel=(PixelChannel) i;
cristyed231572011-07-14 02:18:59 +0000195 return(channel_map);
cristy4c08aed2011-07-01 19:47:50 +0000196}
197
198/*
199%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
200% %
201% %
202% %
cristyed231572011-07-14 02:18:59 +0000203+ C l o n e P i x e l C h a n n e l M a p %
cristy4c08aed2011-07-01 19:47:50 +0000204% %
205% %
206% %
207%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
208%
cristyed231572011-07-14 02:18:59 +0000209% ClonePixelChannelMap() clones a pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000210%
cristyed231572011-07-14 02:18:59 +0000211% The format of the ClonePixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000212%
cristybd5a96c2011-08-21 00:04:26 +0000213% PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000214%
215% A description of each parameter follows:
216%
cristyed231572011-07-14 02:18:59 +0000217% o channel_map: the pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000218%
219*/
cristybd5a96c2011-08-21 00:04:26 +0000220MagickExport PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000221{
cristyed231572011-07-14 02:18:59 +0000222 PixelChannelMap
cristybd5a96c2011-08-21 00:04:26 +0000223 *clone_map;
cristy4c08aed2011-07-01 19:47:50 +0000224
cristybd5a96c2011-08-21 00:04:26 +0000225 assert(channel_map != (PixelChannelMap *) NULL);
cristyed231572011-07-14 02:18:59 +0000226 clone_map=AcquirePixelChannelMap();
cristybd5a96c2011-08-21 00:04:26 +0000227 if (clone_map == (PixelChannelMap *) NULL)
228 return((PixelChannelMap *) NULL);
229 (void) CopyMagickMemory(clone_map,channel_map,MaxPixelChannels*
230 sizeof(*channel_map));
cristy4c08aed2011-07-01 19:47:50 +0000231 return(clone_map);
232}
233
234/*
235%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
236% %
237% %
238% %
239+ C l o n e P i x e l I n f o %
240% %
241% %
242% %
243%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244%
245% ClonePixelInfo() makes a duplicate of the given pixel info structure, or if
246% pixel info is NULL, a new one.
247%
248% The format of the ClonePixelInfo method is:
249%
250% PixelInfo *ClonePixelInfo(const PixelInfo *pixel_info)
251%
252% A description of each parameter follows:
253%
254% o pixel_info: the pixel info.
255%
256*/
257MagickExport PixelInfo *ClonePixelInfo(const PixelInfo *pixel)
258{
259 PixelInfo
260 *pixel_info;
261
cristya64b85d2011-09-14 01:02:31 +0000262 pixel_info=(PixelInfo *) AcquireQuantumMemory(1,sizeof(*pixel_info));
cristy4c08aed2011-07-01 19:47:50 +0000263 if (pixel_info == (PixelInfo *) NULL)
264 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
265 *pixel_info=(*pixel);
266 return(pixel_info);
267}
268
269/*
270%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271% %
272% %
273% %
cristyed231572011-07-14 02:18:59 +0000274+ D e s t r o y P i x e l C h a n n e l M a p %
cristy4c08aed2011-07-01 19:47:50 +0000275% %
276% %
277% %
278%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279%
cristyed231572011-07-14 02:18:59 +0000280% DestroyPixelChannelMap() deallocates memory associated with the pixel
281% channel map.
cristy4c08aed2011-07-01 19:47:50 +0000282%
cristyed231572011-07-14 02:18:59 +0000283% The format of the DestroyPixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000284%
cristybd5a96c2011-08-21 00:04:26 +0000285% PixelChannelMap *DestroyPixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000286%
287% A description of each parameter follows:
288%
cristyed231572011-07-14 02:18:59 +0000289% o channel_map: the pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000290%
291*/
cristybd5a96c2011-08-21 00:04:26 +0000292MagickExport PixelChannelMap *DestroyPixelChannelMap(
293 PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000294{
cristybd5a96c2011-08-21 00:04:26 +0000295 assert(channel_map != (PixelChannelMap *) NULL);
296 channel_map=(PixelChannelMap *) RelinquishMagickMemory(channel_map);
297 return((PixelChannelMap *) RelinquishMagickMemory(channel_map));
cristy4c08aed2011-07-01 19:47:50 +0000298}
299
300/*
301%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
302% %
303% %
304% %
305% E x p o r t I m a g e P i x e l s %
306% %
307% %
308% %
309%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
310%
311% ExportImagePixels() extracts pixel data from an image and returns it to you.
312% The method returns MagickTrue on success otherwise MagickFalse if an error is
cristyb5a45a32012-01-10 13:31:13 +0000313% encountered. The data is returned as char, short int, Quantum, unsigned int,
cristycafe0412012-01-10 13:29:58 +0000314% unsigned long long, float, or double in the order specified by map.
cristy4c08aed2011-07-01 19:47:50 +0000315%
316% Suppose you want to extract the first scanline of a 640x480 image as
317% character data in red-green-blue order:
318%
319% ExportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels,exception);
320%
321% The format of the ExportImagePixels method is:
322%
cristycafe0412012-01-10 13:29:58 +0000323% MagickBooleanType ExportImagePixels(const Image *image,const ssize_t x,
324% const ssize_t y,const size_t width,const size_t height,
325% const char *map,const StorageType type,void *pixels,
cristy46f4be22012-01-07 00:26:39 +0000326% ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +0000327%
328% A description of each parameter follows:
329%
330% o image: the image.
331%
cristycafe0412012-01-10 13:29:58 +0000332% o x,y,width,height: These values define the perimeter
cristy4c08aed2011-07-01 19:47:50 +0000333% of a region of pixels you want to extract.
334%
335% o map: This string reflects the expected ordering of the pixel array.
336% It can be any combination or order of R = red, G = green, B = blue,
337% A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
338% Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
339% P = pad.
340%
341% o type: Define the data type of the pixels. Float and double types are
342% normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
cristy6c9e1682012-01-07 21:37:44 +0000343% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
cristyff6834e2012-01-10 03:00:25 +0000344% LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
cristy6c9e1682012-01-07 21:37:44 +0000345% QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
cristy4c08aed2011-07-01 19:47:50 +0000346%
347% o pixels: This array of values contain the pixel components as defined by
348% map and type. You must preallocate this array where the expected
349% length varies depending on the values of width, height, map, and type.
350%
351% o exception: return any errors or warnings in this structure.
352%
353*/
cristye5370942012-01-06 03:49:31 +0000354
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 {
cristy2dc655d2012-07-05 13:16:28 +0000430 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristycafe0412012-01-10 13:29:58 +0000431 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000432 {
cristycafe0412012-01-10 13:29:58 +0000433 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000434 if (p == (const Quantum *) NULL)
435 break;
cristycafe0412012-01-10 13:29:58 +0000436 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000437 {
438 *q++=ScaleQuantumToChar(GetPixelIntensity(image,p));
439 p+=GetPixelChannels(image);
440 }
441 }
442 return;
443 }
444 if (LocaleCompare(map,"RGB") == 0)
445 {
cristycafe0412012-01-10 13:29:58 +0000446 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000447 {
cristycafe0412012-01-10 13:29:58 +0000448 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000449 if (p == (const Quantum *) NULL)
450 break;
cristycafe0412012-01-10 13:29:58 +0000451 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000452 {
453 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
454 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
455 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
456 p+=GetPixelChannels(image);
457 }
458 }
459 return;
460 }
461 if (LocaleCompare(map,"RGBA") == 0)
462 {
cristycafe0412012-01-10 13:29:58 +0000463 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000464 {
cristycafe0412012-01-10 13:29:58 +0000465 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000466 if (p == (const Quantum *) NULL)
467 break;
cristycafe0412012-01-10 13:29:58 +0000468 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000469 {
470 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
471 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
472 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
473 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
474 p+=GetPixelChannels(image);
475 }
476 }
477 return;
478 }
479 if (LocaleCompare(map,"RGBP") == 0)
480 {
cristycafe0412012-01-10 13:29:58 +0000481 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000482 {
cristycafe0412012-01-10 13:29:58 +0000483 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000484 if (p == (const Quantum *) NULL)
485 break;
cristycafe0412012-01-10 13:29:58 +0000486 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000487 {
488 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
489 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
490 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
491 *q++=ScaleQuantumToChar((Quantum) 0);
492 p+=GetPixelChannels(image);
493 }
494 }
495 return;
496 }
cristy14d71292012-05-20 16:48:13 +0000497 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +0000498 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000499 {
cristycafe0412012-01-10 13:29:58 +0000500 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000501 if (p == (const Quantum *) NULL)
502 break;
cristycafe0412012-01-10 13:29:58 +0000503 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000504 {
505 register ssize_t
506 i;
507
cristy14d71292012-05-20 16:48:13 +0000508 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +0000509 {
510 *q=0;
511 switch (quantum_map[i])
512 {
513 case RedQuantum:
514 case CyanQuantum:
515 {
516 *q=ScaleQuantumToChar(GetPixelRed(image,p));
517 break;
518 }
519 case GreenQuantum:
520 case MagentaQuantum:
521 {
522 *q=ScaleQuantumToChar(GetPixelGreen(image,p));
523 break;
524 }
525 case BlueQuantum:
526 case YellowQuantum:
527 {
528 *q=ScaleQuantumToChar(GetPixelBlue(image,p));
529 break;
530 }
531 case AlphaQuantum:
532 {
533 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
534 break;
535 }
536 case OpacityQuantum:
537 {
538 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
539 break;
540 }
541 case BlackQuantum:
542 {
543 if (image->colorspace == CMYKColorspace)
544 *q=ScaleQuantumToChar(GetPixelBlack(image,p));
545 break;
546 }
547 case IndexQuantum:
548 {
549 *q=ScaleQuantumToChar(GetPixelIntensity(image,p));
550 break;
551 }
552 default:
553 break;
554 }
555 q++;
556 }
557 p+=GetPixelChannels(image);
558 }
559 }
560}
561
cristy2dc655d2012-07-05 13:16:28 +0000562static void ExportDoublePixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000563 const char *restrict map,const QuantumType *quantum_map,void *pixels,
564 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000565{
566 register const Quantum
567 *restrict p;
568
569 register double
cristy3fe11452012-01-09 01:27:42 +0000570 *restrict q;
cristye5370942012-01-06 03:49:31 +0000571
572 register ssize_t
573 x;
574
cristy14d71292012-05-20 16:48:13 +0000575 size_t
576 length;
577
cristye5370942012-01-06 03:49:31 +0000578 ssize_t
579 y;
580
581 q=(double *) pixels;
582 if (LocaleCompare(map,"BGR") == 0)
583 {
cristycafe0412012-01-10 13:29:58 +0000584 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000585 {
cristycafe0412012-01-10 13:29:58 +0000586 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000587 if (p == (const Quantum *) NULL)
588 break;
cristycafe0412012-01-10 13:29:58 +0000589 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000590 {
591 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
592 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
593 *q++=(double) (QuantumScale*GetPixelRed(image,p));
594 p+=GetPixelChannels(image);
595 }
596 }
597 return;
598 }
599 if (LocaleCompare(map,"BGRA") == 0)
600 {
cristycafe0412012-01-10 13:29:58 +0000601 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000602 {
cristycafe0412012-01-10 13:29:58 +0000603 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000604 if (p == (const Quantum *) NULL)
605 break;
cristycafe0412012-01-10 13:29:58 +0000606 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000607 {
608 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
609 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
610 *q++=(double) (QuantumScale*GetPixelRed(image,p));
611 *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
612 p+=GetPixelChannels(image);
613 }
614 }
615 return;
616 }
617 if (LocaleCompare(map,"BGRP") == 0)
618 {
cristycafe0412012-01-10 13:29:58 +0000619 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000620 {
cristycafe0412012-01-10 13:29:58 +0000621 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000622 if (p == (const Quantum *) NULL)
623 break;
cristycafe0412012-01-10 13:29:58 +0000624 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000625 {
626 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
627 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
628 *q++=(double) (QuantumScale*GetPixelRed(image,p));
629 *q++=0.0;
630 p+=GetPixelChannels(image);
631 }
632 }
633 return;
634 }
635 if (LocaleCompare(map,"I") == 0)
636 {
cristy2dc655d2012-07-05 13:16:28 +0000637 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristycafe0412012-01-10 13:29:58 +0000638 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000639 {
cristycafe0412012-01-10 13:29:58 +0000640 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000641 if (p == (const Quantum *) NULL)
642 break;
cristycafe0412012-01-10 13:29:58 +0000643 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000644 {
645 *q++=(double) (QuantumScale*GetPixelIntensity(image,p));
646 p+=GetPixelChannels(image);
647 }
648 }
649 return;
650 }
651 if (LocaleCompare(map,"RGB") == 0)
652 {
cristycafe0412012-01-10 13:29:58 +0000653 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000654 {
cristycafe0412012-01-10 13:29:58 +0000655 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000656 if (p == (const Quantum *) NULL)
657 break;
cristycafe0412012-01-10 13:29:58 +0000658 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000659 {
660 *q++=(double) (QuantumScale*GetPixelRed(image,p));
661 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
662 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
663 p+=GetPixelChannels(image);
664 }
665 }
666 return;
667 }
668 if (LocaleCompare(map,"RGBA") == 0)
669 {
cristycafe0412012-01-10 13:29:58 +0000670 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000671 {
cristycafe0412012-01-10 13:29:58 +0000672 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000673 if (p == (const Quantum *) NULL)
674 break;
cristycafe0412012-01-10 13:29:58 +0000675 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000676 {
677 *q++=(double) (QuantumScale*GetPixelRed(image,p));
678 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
679 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
680 *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
681 p+=GetPixelChannels(image);
682 }
683 }
684 return;
685 }
686 if (LocaleCompare(map,"RGBP") == 0)
687 {
cristycafe0412012-01-10 13:29:58 +0000688 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000689 {
cristycafe0412012-01-10 13:29:58 +0000690 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000691 if (p == (const Quantum *) NULL)
692 break;
cristycafe0412012-01-10 13:29:58 +0000693 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000694 {
695 *q++=(double) (QuantumScale*GetPixelRed(image,p));
696 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
697 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
698 *q++=0.0;
699 p+=GetPixelChannels(image);
700 }
701 }
702 return;
703 }
cristy14d71292012-05-20 16:48:13 +0000704 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +0000705 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000706 {
cristycafe0412012-01-10 13:29:58 +0000707 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000708 if (p == (const Quantum *) NULL)
709 break;
cristycafe0412012-01-10 13:29:58 +0000710 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000711 {
712 register ssize_t
713 i;
714
cristy14d71292012-05-20 16:48:13 +0000715 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +0000716 {
717 *q=0;
718 switch (quantum_map[i])
719 {
720 case RedQuantum:
721 case CyanQuantum:
722 {
723 *q=(double) (QuantumScale*GetPixelRed(image,p));
724 break;
725 }
726 case GreenQuantum:
727 case MagentaQuantum:
728 {
729 *q=(double) (QuantumScale*GetPixelGreen(image,p));
730 break;
731 }
732 case BlueQuantum:
733 case YellowQuantum:
734 {
735 *q=(double) (QuantumScale*GetPixelBlue(image,p));
736 break;
737 }
738 case AlphaQuantum:
739 {
740 *q=(double) (QuantumScale*GetPixelAlpha(image,p));
741 break;
742 }
743 case OpacityQuantum:
744 {
745 *q=(double) (QuantumScale*GetPixelAlpha(image,p));
746 break;
747 }
748 case BlackQuantum:
749 {
750 if (image->colorspace == CMYKColorspace)
751 *q=(double) (QuantumScale*
752 GetPixelBlack(image,p));
753 break;
754 }
755 case IndexQuantum:
756 {
757 *q=(double) (QuantumScale*GetPixelIntensity(image,p));
758 break;
759 }
760 default:
761 *q=0;
762 }
763 q++;
764 }
765 p+=GetPixelChannels(image);
766 }
767 }
768}
769
cristy2dc655d2012-07-05 13:16:28 +0000770static void ExportFloatPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000771 const char *restrict map,const QuantumType *quantum_map,void *pixels,
772 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000773{
774 register const Quantum
775 *restrict p;
776
777 register float
cristy3fe11452012-01-09 01:27:42 +0000778 *restrict q;
cristye5370942012-01-06 03:49:31 +0000779
780 register ssize_t
781 x;
782
cristy14d71292012-05-20 16:48:13 +0000783 size_t
784 length;
785
cristye5370942012-01-06 03:49:31 +0000786 ssize_t
787 y;
788
789 q=(float *) pixels;
790 if (LocaleCompare(map,"BGR") == 0)
791 {
cristycafe0412012-01-10 13:29:58 +0000792 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000793 {
cristycafe0412012-01-10 13:29:58 +0000794 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000795 if (p == (const Quantum *) NULL)
796 break;
cristycafe0412012-01-10 13:29:58 +0000797 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000798 {
799 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
800 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
801 *q++=(float) (QuantumScale*GetPixelRed(image,p));
802 p+=GetPixelChannels(image);
803 }
804 }
805 return;
806 }
807 if (LocaleCompare(map,"BGRA") == 0)
808 {
cristycafe0412012-01-10 13:29:58 +0000809 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000810 {
cristycafe0412012-01-10 13:29:58 +0000811 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000812 if (p == (const Quantum *) NULL)
813 break;
cristycafe0412012-01-10 13:29:58 +0000814 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000815 {
816 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
817 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
818 *q++=(float) (QuantumScale*GetPixelRed(image,p));
819 *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
820 p+=GetPixelChannels(image);
821 }
822 }
823 return;
824 }
825 if (LocaleCompare(map,"BGRP") == 0)
826 {
cristycafe0412012-01-10 13:29:58 +0000827 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000828 {
cristycafe0412012-01-10 13:29:58 +0000829 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000830 if (p == (const Quantum *) NULL)
831 break;
cristycafe0412012-01-10 13:29:58 +0000832 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000833 {
834 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
835 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
836 *q++=(float) (QuantumScale*GetPixelRed(image,p));
837 *q++=0.0;
838 p+=GetPixelChannels(image);
839 }
840 }
841 return;
842 }
843 if (LocaleCompare(map,"I") == 0)
844 {
cristy2dc655d2012-07-05 13:16:28 +0000845 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristycafe0412012-01-10 13:29:58 +0000846 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000847 {
cristycafe0412012-01-10 13:29:58 +0000848 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000849 if (p == (const Quantum *) NULL)
850 break;
cristycafe0412012-01-10 13:29:58 +0000851 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000852 {
853 *q++=(float) (QuantumScale*GetPixelIntensity(image,p));
854 p+=GetPixelChannels(image);
855 }
856 }
857 return;
858 }
859 if (LocaleCompare(map,"RGB") == 0)
860 {
cristycafe0412012-01-10 13:29:58 +0000861 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000862 {
cristycafe0412012-01-10 13:29:58 +0000863 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000864 if (p == (const Quantum *) NULL)
865 break;
cristycafe0412012-01-10 13:29:58 +0000866 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000867 {
868 *q++=(float) (QuantumScale*GetPixelRed(image,p));
869 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
870 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
871 p+=GetPixelChannels(image);
872 }
873 }
874 return;
875 }
876 if (LocaleCompare(map,"RGBA") == 0)
877 {
cristycafe0412012-01-10 13:29:58 +0000878 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000879 {
cristycafe0412012-01-10 13:29:58 +0000880 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000881 if (p == (const Quantum *) NULL)
882 break;
cristycafe0412012-01-10 13:29:58 +0000883 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000884 {
885 *q++=(float) (QuantumScale*GetPixelRed(image,p));
886 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
887 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
888 *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
889 p+=GetPixelChannels(image);
890 }
891 }
892 return;
893 }
894 if (LocaleCompare(map,"RGBP") == 0)
895 {
cristycafe0412012-01-10 13:29:58 +0000896 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000897 {
cristycafe0412012-01-10 13:29:58 +0000898 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000899 if (p == (const Quantum *) NULL)
900 break;
cristycafe0412012-01-10 13:29:58 +0000901 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000902 {
903 *q++=(float) (QuantumScale*GetPixelRed(image,p));
904 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
905 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
906 *q++=0.0;
907 p+=GetPixelChannels(image);
908 }
909 }
910 return;
911 }
cristy14d71292012-05-20 16:48:13 +0000912 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +0000913 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000914 {
cristycafe0412012-01-10 13:29:58 +0000915 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000916 if (p == (const Quantum *) NULL)
917 break;
cristycafe0412012-01-10 13:29:58 +0000918 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000919 {
920 register ssize_t
921 i;
922
cristy14d71292012-05-20 16:48:13 +0000923 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +0000924 {
925 *q=0;
926 switch (quantum_map[i])
927 {
928 case RedQuantum:
929 case CyanQuantum:
930 {
931 *q=(float) (QuantumScale*GetPixelRed(image,p));
932 break;
933 }
934 case GreenQuantum:
935 case MagentaQuantum:
936 {
937 *q=(float) (QuantumScale*GetPixelGreen(image,p));
938 break;
939 }
940 case BlueQuantum:
941 case YellowQuantum:
942 {
943 *q=(float) (QuantumScale*GetPixelBlue(image,p));
944 break;
945 }
946 case AlphaQuantum:
947 {
948 *q=(float) (QuantumScale*((Quantum) (GetPixelAlpha(image,p))));
949 break;
950 }
951 case OpacityQuantum:
952 {
953 *q=(float) (QuantumScale*GetPixelAlpha(image,p));
954 break;
955 }
956 case BlackQuantum:
957 {
958 if (image->colorspace == CMYKColorspace)
959 *q=(float) (QuantumScale* GetPixelBlack(image,p));
960 break;
961 }
962 case IndexQuantum:
963 {
964 *q=(float) (QuantumScale*GetPixelIntensity(image,p));
965 break;
966 }
967 default:
968 *q=0;
969 }
970 q++;
971 }
972 p+=GetPixelChannels(image);
973 }
974 }
975}
976
cristy2dc655d2012-07-05 13:16:28 +0000977static void ExportLongPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000978 const char *restrict map,const QuantumType *quantum_map,void *pixels,
979 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000980{
981 register const Quantum
982 *restrict p;
983
984 register ssize_t
985 x;
986
987 register unsigned int
cristy3fe11452012-01-09 01:27:42 +0000988 *restrict q;
cristye5370942012-01-06 03:49:31 +0000989
cristy14d71292012-05-20 16:48:13 +0000990 size_t
991 length;
992
cristye5370942012-01-06 03:49:31 +0000993 ssize_t
994 y;
995
996 q=(unsigned int *) pixels;
997 if (LocaleCompare(map,"BGR") == 0)
998 {
cristycafe0412012-01-10 13:29:58 +0000999 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001000 {
cristycafe0412012-01-10 13:29:58 +00001001 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001002 if (p == (const Quantum *) NULL)
1003 break;
cristycafe0412012-01-10 13:29:58 +00001004 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001005 {
cristy6c9e1682012-01-07 21:37:44 +00001006 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1007 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1008 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001009 p+=GetPixelChannels(image);
1010 }
1011 }
1012 return;
1013 }
1014 if (LocaleCompare(map,"BGRA") == 0)
1015 {
cristycafe0412012-01-10 13:29:58 +00001016 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001017 {
cristycafe0412012-01-10 13:29:58 +00001018 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001019 if (p == (const Quantum *) NULL)
1020 break;
cristycafe0412012-01-10 13:29:58 +00001021 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001022 {
cristy6c9e1682012-01-07 21:37:44 +00001023 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1024 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1025 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1026 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001027 p+=GetPixelChannels(image);
1028 }
1029 }
1030 return;
1031 }
1032 if (LocaleCompare(map,"BGRP") == 0)
1033 {
cristycafe0412012-01-10 13:29:58 +00001034 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001035 {
cristycafe0412012-01-10 13:29:58 +00001036 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001037 if (p == (const Quantum *) NULL)
1038 break;
cristycafe0412012-01-10 13:29:58 +00001039 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001040 {
cristy6c9e1682012-01-07 21:37:44 +00001041 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1042 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1043 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1044 *q++=0;
cristye5370942012-01-06 03:49:31 +00001045 p+=GetPixelChannels(image);
1046 }
1047 }
1048 return;
1049 }
1050 if (LocaleCompare(map,"I") == 0)
1051 {
cristy2dc655d2012-07-05 13:16:28 +00001052 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristycafe0412012-01-10 13:29:58 +00001053 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001054 {
cristycafe0412012-01-10 13:29:58 +00001055 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001056 if (p == (const Quantum *) NULL)
1057 break;
cristycafe0412012-01-10 13:29:58 +00001058 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001059 {
cristy6c9e1682012-01-07 21:37:44 +00001060 *q++=ScaleQuantumToLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001061 p+=GetPixelChannels(image);
1062 }
1063 }
1064 return;
1065 }
1066 if (LocaleCompare(map,"RGB") == 0)
1067 {
cristycafe0412012-01-10 13:29:58 +00001068 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001069 {
cristycafe0412012-01-10 13:29:58 +00001070 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001071 if (p == (const Quantum *) NULL)
1072 break;
cristycafe0412012-01-10 13:29:58 +00001073 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001074 {
cristy6c9e1682012-01-07 21:37:44 +00001075 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1076 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1077 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001078 p+=GetPixelChannels(image);
1079 }
1080 }
1081 return;
1082 }
1083 if (LocaleCompare(map,"RGBA") == 0)
1084 {
cristycafe0412012-01-10 13:29:58 +00001085 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001086 {
cristycafe0412012-01-10 13:29:58 +00001087 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001088 if (p == (const Quantum *) NULL)
1089 break;
cristycafe0412012-01-10 13:29:58 +00001090 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001091 {
cristy6c9e1682012-01-07 21:37:44 +00001092 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1093 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1094 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1095 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001096 p+=GetPixelChannels(image);
1097 }
1098 }
1099 return;
1100 }
1101 if (LocaleCompare(map,"RGBP") == 0)
1102 {
cristycafe0412012-01-10 13:29:58 +00001103 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001104 {
cristycafe0412012-01-10 13:29:58 +00001105 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001106 if (p == (const Quantum *) NULL)
1107 break;
cristycafe0412012-01-10 13:29:58 +00001108 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001109 {
cristy6c9e1682012-01-07 21:37:44 +00001110 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1111 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1112 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1113 *q++=0;
cristye5370942012-01-06 03:49:31 +00001114 p+=GetPixelChannels(image);
1115 }
1116 }
1117 return;
1118 }
cristy14d71292012-05-20 16:48:13 +00001119 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00001120 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001121 {
cristycafe0412012-01-10 13:29:58 +00001122 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001123 if (p == (const Quantum *) NULL)
1124 break;
cristycafe0412012-01-10 13:29:58 +00001125 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001126 {
1127 register ssize_t
1128 i;
1129
cristy14d71292012-05-20 16:48:13 +00001130 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00001131 {
1132 *q=0;
1133 switch (quantum_map[i])
1134 {
1135 case RedQuantum:
1136 case CyanQuantum:
1137 {
cristy6c9e1682012-01-07 21:37:44 +00001138 *q=ScaleQuantumToLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001139 break;
1140 }
1141 case GreenQuantum:
1142 case MagentaQuantum:
1143 {
cristy6c9e1682012-01-07 21:37:44 +00001144 *q=ScaleQuantumToLong(GetPixelGreen(image,p));
cristye5370942012-01-06 03:49:31 +00001145 break;
1146 }
1147 case BlueQuantum:
1148 case YellowQuantum:
1149 {
cristy6c9e1682012-01-07 21:37:44 +00001150 *q=ScaleQuantumToLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001151 break;
1152 }
1153 case AlphaQuantum:
1154 {
cristy6c9e1682012-01-07 21:37:44 +00001155 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001156 break;
1157 }
1158 case OpacityQuantum:
1159 {
cristy6c9e1682012-01-07 21:37:44 +00001160 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001161 break;
1162 }
1163 case BlackQuantum:
1164 {
1165 if (image->colorspace == CMYKColorspace)
cristy6c9e1682012-01-07 21:37:44 +00001166 *q=ScaleQuantumToLong(GetPixelBlack(image,p));
cristye5370942012-01-06 03:49:31 +00001167 break;
1168 }
1169 case IndexQuantum:
1170 {
cristy6c9e1682012-01-07 21:37:44 +00001171 *q=ScaleQuantumToLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001172 break;
1173 }
1174 default:
cristy6c9e1682012-01-07 21:37:44 +00001175 break;
cristye5370942012-01-06 03:49:31 +00001176 }
1177 q++;
1178 }
1179 p+=GetPixelChannels(image);
1180 }
1181 }
1182}
1183
cristy2dc655d2012-07-05 13:16:28 +00001184static void ExportLongLongPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00001185 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1186 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001187{
1188 register const Quantum
1189 *restrict p;
1190
1191 register ssize_t
1192 x;
1193
cristyb13e12a2012-01-06 21:48:27 +00001194 register MagickSizeType
cristy3fe11452012-01-09 01:27:42 +00001195 *restrict q;
cristye5370942012-01-06 03:49:31 +00001196
cristy14d71292012-05-20 16:48:13 +00001197 size_t
1198 length;
1199
cristye5370942012-01-06 03:49:31 +00001200 ssize_t
1201 y;
1202
cristyb13e12a2012-01-06 21:48:27 +00001203 q=(MagickSizeType *) pixels;
cristye5370942012-01-06 03:49:31 +00001204 if (LocaleCompare(map,"BGR") == 0)
1205 {
cristycafe0412012-01-10 13:29:58 +00001206 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001207 {
cristycafe0412012-01-10 13:29:58 +00001208 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001209 if (p == (const Quantum *) NULL)
1210 break;
cristycafe0412012-01-10 13:29:58 +00001211 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001212 {
cristyb13e12a2012-01-06 21:48:27 +00001213 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1214 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1215 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001216 p+=GetPixelChannels(image);
1217 }
1218 }
1219 return;
1220 }
1221 if (LocaleCompare(map,"BGRA") == 0)
1222 {
cristycafe0412012-01-10 13:29:58 +00001223 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001224 {
cristycafe0412012-01-10 13:29:58 +00001225 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001226 if (p == (const Quantum *) NULL)
1227 break;
cristycafe0412012-01-10 13:29:58 +00001228 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001229 {
cristyb13e12a2012-01-06 21:48:27 +00001230 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1231 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1232 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1233 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001234 p+=GetPixelChannels(image);
1235 }
1236 }
1237 return;
1238 }
1239 if (LocaleCompare(map,"BGRP") == 0)
1240 {
cristycafe0412012-01-10 13:29:58 +00001241 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001242 {
cristycafe0412012-01-10 13:29:58 +00001243 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001244 if (p == (const Quantum *) NULL)
1245 break;
cristycafe0412012-01-10 13:29:58 +00001246 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001247 {
cristyb13e12a2012-01-06 21:48:27 +00001248 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1249 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1250 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001251 *q++=0;
1252 p+=GetPixelChannels(image);
1253 }
1254 }
1255 return;
1256 }
1257 if (LocaleCompare(map,"I") == 0)
1258 {
cristy2dc655d2012-07-05 13:16:28 +00001259 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristycafe0412012-01-10 13:29:58 +00001260 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001261 {
cristycafe0412012-01-10 13:29:58 +00001262 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001263 if (p == (const Quantum *) NULL)
1264 break;
cristycafe0412012-01-10 13:29:58 +00001265 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001266 {
cristyb13e12a2012-01-06 21:48:27 +00001267 *q++=ScaleQuantumToLongLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001268 p+=GetPixelChannels(image);
1269 }
1270 }
1271 return;
1272 }
1273 if (LocaleCompare(map,"RGB") == 0)
1274 {
cristycafe0412012-01-10 13:29:58 +00001275 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001276 {
cristycafe0412012-01-10 13:29:58 +00001277 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001278 if (p == (const Quantum *) NULL)
1279 break;
cristycafe0412012-01-10 13:29:58 +00001280 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001281 {
cristyb13e12a2012-01-06 21:48:27 +00001282 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1283 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1284 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001285 p+=GetPixelChannels(image);
1286 }
1287 }
1288 return;
1289 }
1290 if (LocaleCompare(map,"RGBA") == 0)
1291 {
cristycafe0412012-01-10 13:29:58 +00001292 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001293 {
cristycafe0412012-01-10 13:29:58 +00001294 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001295 if (p == (const Quantum *) NULL)
1296 break;
cristycafe0412012-01-10 13:29:58 +00001297 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001298 {
cristyb13e12a2012-01-06 21:48:27 +00001299 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1300 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1301 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1302 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001303 p+=GetPixelChannels(image);
1304 }
1305 }
1306 return;
1307 }
1308 if (LocaleCompare(map,"RGBP") == 0)
1309 {
cristycafe0412012-01-10 13:29:58 +00001310 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001311 {
cristycafe0412012-01-10 13:29:58 +00001312 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001313 if (p == (const Quantum *) NULL)
1314 break;
cristycafe0412012-01-10 13:29:58 +00001315 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001316 {
cristyb13e12a2012-01-06 21:48:27 +00001317 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1318 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1319 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001320 *q++=0;
1321 p+=GetPixelChannels(image);
1322 }
1323 }
1324 return;
1325 }
cristy14d71292012-05-20 16:48:13 +00001326 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00001327 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001328 {
cristycafe0412012-01-10 13:29:58 +00001329 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001330 if (p == (const Quantum *) NULL)
1331 break;
cristycafe0412012-01-10 13:29:58 +00001332 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001333 {
1334 register ssize_t
1335 i;
1336
cristy14d71292012-05-20 16:48:13 +00001337 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00001338 {
1339 *q=0;
1340 switch (quantum_map[i])
1341 {
1342 case RedQuantum:
1343 case CyanQuantum:
1344 {
cristyb13e12a2012-01-06 21:48:27 +00001345 *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001346 break;
1347 }
1348 case GreenQuantum:
1349 case MagentaQuantum:
1350 {
cristyb13e12a2012-01-06 21:48:27 +00001351 *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
cristye5370942012-01-06 03:49:31 +00001352 break;
1353 }
1354 case BlueQuantum:
1355 case YellowQuantum:
1356 {
cristyb13e12a2012-01-06 21:48:27 +00001357 *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001358 break;
1359 }
1360 case AlphaQuantum:
1361 {
cristyb13e12a2012-01-06 21:48:27 +00001362 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001363 break;
1364 }
1365 case OpacityQuantum:
1366 {
cristyb13e12a2012-01-06 21:48:27 +00001367 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001368 break;
1369 }
1370 case BlackQuantum:
1371 {
1372 if (image->colorspace == CMYKColorspace)
cristyb13e12a2012-01-06 21:48:27 +00001373 *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
cristye5370942012-01-06 03:49:31 +00001374 break;
1375 }
1376 case IndexQuantum:
1377 {
cristyb13e12a2012-01-06 21:48:27 +00001378 *q=ScaleQuantumToLongLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001379 break;
1380 }
1381 default:
1382 break;
1383 }
1384 q++;
1385 }
1386 p+=GetPixelChannels(image);
1387 }
1388 }
1389}
1390
cristy2dc655d2012-07-05 13:16:28 +00001391static void ExportQuantumPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00001392 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1393 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001394{
1395 register const Quantum
1396 *restrict p;
1397
1398 register Quantum
cristy3fe11452012-01-09 01:27:42 +00001399 *restrict q;
cristye5370942012-01-06 03:49:31 +00001400
1401 register ssize_t
1402 x;
1403
cristy14d71292012-05-20 16:48:13 +00001404 size_t
1405 length;
1406
cristye5370942012-01-06 03:49:31 +00001407 ssize_t
1408 y;
1409
1410 q=(Quantum *) pixels;
1411 if (LocaleCompare(map,"BGR") == 0)
1412 {
cristycafe0412012-01-10 13:29:58 +00001413 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001414 {
cristycafe0412012-01-10 13:29:58 +00001415 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001416 if (p == (const Quantum *) NULL)
1417 break;
cristycafe0412012-01-10 13:29:58 +00001418 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001419 {
1420 *q++=GetPixelBlue(image,p);
1421 *q++=GetPixelGreen(image,p);
1422 *q++=GetPixelRed(image,p);
1423 p+=GetPixelChannels(image);
1424 }
1425 }
1426 return;
1427 }
1428 if (LocaleCompare(map,"BGRA") == 0)
1429 {
cristycafe0412012-01-10 13:29:58 +00001430 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001431 {
cristycafe0412012-01-10 13:29:58 +00001432 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001433 if (p == (const Quantum *) NULL)
1434 break;
cristycafe0412012-01-10 13:29:58 +00001435 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001436 {
1437 *q++=GetPixelBlue(image,p);
1438 *q++=GetPixelGreen(image,p);
1439 *q++=GetPixelRed(image,p);
1440 *q++=(Quantum) (GetPixelAlpha(image,p));
1441 p+=GetPixelChannels(image);
1442 }
1443 }
1444 return;
1445 }
1446 if (LocaleCompare(map,"BGRP") == 0)
1447 {
cristycafe0412012-01-10 13:29:58 +00001448 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001449 {
cristycafe0412012-01-10 13:29:58 +00001450 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001451 if (p == (const Quantum *) NULL)
1452 break;
cristycafe0412012-01-10 13:29:58 +00001453 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001454 {
1455 *q++=GetPixelBlue(image,p);
1456 *q++=GetPixelGreen(image,p);
1457 *q++=GetPixelRed(image,p);
1458 *q++=(Quantum) 0;
1459 p+=GetPixelChannels(image);
1460 }
1461 }
1462 return;
1463 }
1464 if (LocaleCompare(map,"I") == 0)
1465 {
cristy2dc655d2012-07-05 13:16:28 +00001466 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristycafe0412012-01-10 13:29:58 +00001467 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001468 {
cristycafe0412012-01-10 13:29:58 +00001469 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001470 if (p == (const Quantum *) NULL)
1471 break;
cristycafe0412012-01-10 13:29:58 +00001472 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001473 {
1474 *q++=GetPixelIntensity(image,p);
1475 p+=GetPixelChannels(image);
1476 }
1477 }
1478 return;
1479 }
1480 if (LocaleCompare(map,"RGB") == 0)
1481 {
cristycafe0412012-01-10 13:29:58 +00001482 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001483 {
cristycafe0412012-01-10 13:29:58 +00001484 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001485 if (p == (const Quantum *) NULL)
1486 break;
cristycafe0412012-01-10 13:29:58 +00001487 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001488 {
1489 *q++=GetPixelRed(image,p);
1490 *q++=GetPixelGreen(image,p);
1491 *q++=GetPixelBlue(image,p);
1492 p+=GetPixelChannels(image);
1493 }
1494 }
1495 return;
1496 }
1497 if (LocaleCompare(map,"RGBA") == 0)
1498 {
cristycafe0412012-01-10 13:29:58 +00001499 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001500 {
cristycafe0412012-01-10 13:29:58 +00001501 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001502 if (p == (const Quantum *) NULL)
1503 break;
cristycafe0412012-01-10 13:29:58 +00001504 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001505 {
1506 *q++=GetPixelRed(image,p);
1507 *q++=GetPixelGreen(image,p);
1508 *q++=GetPixelBlue(image,p);
1509 *q++=(Quantum) (GetPixelAlpha(image,p));
1510 p+=GetPixelChannels(image);
1511 }
1512 }
1513 return;
1514 }
1515 if (LocaleCompare(map,"RGBP") == 0)
1516 {
cristycafe0412012-01-10 13:29:58 +00001517 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001518 {
cristycafe0412012-01-10 13:29:58 +00001519 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001520 if (p == (const Quantum *) NULL)
1521 break;
cristycafe0412012-01-10 13:29:58 +00001522 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001523 {
1524 *q++=GetPixelRed(image,p);
1525 *q++=GetPixelGreen(image,p);
1526 *q++=GetPixelBlue(image,p);
1527 *q++=(Quantum) 0;
1528 p+=GetPixelChannels(image);
1529 }
1530 }
1531 return;
1532 }
cristy14d71292012-05-20 16:48:13 +00001533 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00001534 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001535 {
cristycafe0412012-01-10 13:29:58 +00001536 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001537 if (p == (const Quantum *) NULL)
1538 break;
cristycafe0412012-01-10 13:29:58 +00001539 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001540 {
1541 register ssize_t
1542 i;
1543
cristy14d71292012-05-20 16:48:13 +00001544 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00001545 {
1546 *q=(Quantum) 0;
1547 switch (quantum_map[i])
1548 {
1549 case RedQuantum:
1550 case CyanQuantum:
1551 {
1552 *q=GetPixelRed(image,p);
1553 break;
1554 }
1555 case GreenQuantum:
1556 case MagentaQuantum:
1557 {
1558 *q=GetPixelGreen(image,p);
1559 break;
1560 }
1561 case BlueQuantum:
1562 case YellowQuantum:
1563 {
1564 *q=GetPixelBlue(image,p);
1565 break;
1566 }
1567 case AlphaQuantum:
1568 {
1569 *q=GetPixelAlpha(image,p);
1570 break;
1571 }
1572 case OpacityQuantum:
1573 {
1574 *q=GetPixelAlpha(image,p);
1575 break;
1576 }
1577 case BlackQuantum:
1578 {
1579 if (image->colorspace == CMYKColorspace)
1580 *q=GetPixelBlack(image,p);
1581 break;
1582 }
1583 case IndexQuantum:
1584 {
1585 *q=(GetPixelIntensity(image,p));
1586 break;
1587 }
1588 default:
1589 {
1590 *q=(Quantum) 0;
1591 break;
1592 }
1593 }
1594 q++;
1595 }
1596 p+=GetPixelChannels(image);
1597 }
1598 }
1599}
1600
cristy2dc655d2012-07-05 13:16:28 +00001601static void ExportShortPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00001602 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1603 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001604{
1605 register const Quantum
1606 *restrict p;
1607
1608 register ssize_t
1609 x;
1610
cristye5370942012-01-06 03:49:31 +00001611 register unsigned short
cristy3fe11452012-01-09 01:27:42 +00001612 *restrict q;
cristye5370942012-01-06 03:49:31 +00001613
cristy14d71292012-05-20 16:48:13 +00001614 size_t
1615 length;
1616
1617 ssize_t
1618 y;
1619
cristye5370942012-01-06 03:49:31 +00001620 q=(unsigned short *) pixels;
1621 if (LocaleCompare(map,"BGR") == 0)
1622 {
cristycafe0412012-01-10 13:29:58 +00001623 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001624 {
cristycafe0412012-01-10 13:29:58 +00001625 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001626 if (p == (const Quantum *) NULL)
1627 break;
cristycafe0412012-01-10 13:29:58 +00001628 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001629 {
1630 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1631 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1632 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1633 p+=GetPixelChannels(image);
1634 }
1635 }
1636 return;
1637 }
1638 if (LocaleCompare(map,"BGRA") == 0)
1639 {
cristycafe0412012-01-10 13:29:58 +00001640 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001641 {
cristycafe0412012-01-10 13:29:58 +00001642 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001643 if (p == (const Quantum *) NULL)
1644 break;
cristycafe0412012-01-10 13:29:58 +00001645 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001646 {
1647 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1648 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1649 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1650 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1651 p+=GetPixelChannels(image);
1652 }
1653 }
1654 return;
1655 }
1656 if (LocaleCompare(map,"BGRP") == 0)
1657 {
cristycafe0412012-01-10 13:29:58 +00001658 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001659 {
cristycafe0412012-01-10 13:29:58 +00001660 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001661 if (p == (const Quantum *) NULL)
1662 break;
cristycafe0412012-01-10 13:29:58 +00001663 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001664 {
1665 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1666 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1667 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1668 *q++=0;
1669 p+=GetPixelChannels(image);
1670 }
1671 }
1672 return;
1673 }
1674 if (LocaleCompare(map,"I") == 0)
1675 {
cristy2dc655d2012-07-05 13:16:28 +00001676 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristycafe0412012-01-10 13:29:58 +00001677 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001678 {
cristycafe0412012-01-10 13:29:58 +00001679 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001680 if (p == (const Quantum *) NULL)
1681 break;
cristycafe0412012-01-10 13:29:58 +00001682 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001683 {
1684 *q++=ScaleQuantumToShort(GetPixelIntensity(image,p));
1685 p+=GetPixelChannels(image);
1686 }
1687 }
1688 return;
1689 }
1690 if (LocaleCompare(map,"RGB") == 0)
1691 {
cristycafe0412012-01-10 13:29:58 +00001692 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001693 {
cristycafe0412012-01-10 13:29:58 +00001694 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001695 if (p == (const Quantum *) NULL)
1696 break;
cristycafe0412012-01-10 13:29:58 +00001697 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001698 {
1699 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1700 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1701 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1702 p+=GetPixelChannels(image);
1703 }
1704 }
1705 return;
1706 }
1707 if (LocaleCompare(map,"RGBA") == 0)
1708 {
cristycafe0412012-01-10 13:29:58 +00001709 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001710 {
cristycafe0412012-01-10 13:29:58 +00001711 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001712 if (p == (const Quantum *) NULL)
1713 break;
cristycafe0412012-01-10 13:29:58 +00001714 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001715 {
1716 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1717 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1718 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1719 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1720 p+=GetPixelChannels(image);
1721 }
1722 }
1723 return;
1724 }
1725 if (LocaleCompare(map,"RGBP") == 0)
1726 {
cristycafe0412012-01-10 13:29:58 +00001727 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001728 {
cristycafe0412012-01-10 13:29:58 +00001729 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001730 if (p == (const Quantum *) NULL)
1731 break;
cristycafe0412012-01-10 13:29:58 +00001732 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001733 {
1734 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1735 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1736 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1737 *q++=0;
1738 p+=GetPixelChannels(image);
1739 }
1740 }
1741 return;
1742 }
cristy14d71292012-05-20 16:48:13 +00001743 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00001744 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001745 {
cristycafe0412012-01-10 13:29:58 +00001746 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001747 if (p == (const Quantum *) NULL)
1748 break;
cristycafe0412012-01-10 13:29:58 +00001749 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001750 {
1751 register ssize_t
1752 i;
1753
cristy14d71292012-05-20 16:48:13 +00001754 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00001755 {
1756 *q=0;
1757 switch (quantum_map[i])
1758 {
1759 case RedQuantum:
1760 case CyanQuantum:
1761 {
1762 *q=ScaleQuantumToShort(GetPixelRed(image,p));
1763 break;
1764 }
1765 case GreenQuantum:
1766 case MagentaQuantum:
1767 {
1768 *q=ScaleQuantumToShort(GetPixelGreen(image,p));
1769 break;
1770 }
1771 case BlueQuantum:
1772 case YellowQuantum:
1773 {
1774 *q=ScaleQuantumToShort(GetPixelBlue(image,p));
1775 break;
1776 }
1777 case AlphaQuantum:
1778 {
1779 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1780 break;
1781 }
1782 case OpacityQuantum:
1783 {
1784 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1785 break;
1786 }
1787 case BlackQuantum:
1788 {
1789 if (image->colorspace == CMYKColorspace)
1790 *q=ScaleQuantumToShort(GetPixelBlack(image,p));
1791 break;
1792 }
1793 case IndexQuantum:
1794 {
1795 *q=ScaleQuantumToShort(GetPixelIntensity(image,p));
1796 break;
1797 }
1798 default:
1799 break;
1800 }
1801 q++;
1802 }
1803 p+=GetPixelChannels(image);
1804 }
1805 }
1806}
1807
cristy2dc655d2012-07-05 13:16:28 +00001808MagickExport MagickBooleanType ExportImagePixels(Image *image,
cristycafe0412012-01-10 13:29:58 +00001809 const ssize_t x,const ssize_t y,const size_t width,const size_t height,
1810 const char *map,const StorageType type,void *pixels,ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00001811{
1812 QuantumType
1813 *quantum_map;
1814
cristycafe0412012-01-10 13:29:58 +00001815 RectangleInfo
1816 roi;
1817
cristy4c08aed2011-07-01 19:47:50 +00001818 register ssize_t
cristye5370942012-01-06 03:49:31 +00001819 i;
cristy4c08aed2011-07-01 19:47:50 +00001820
cristy14d71292012-05-20 16:48:13 +00001821 size_t
1822 length;
1823
cristy4c08aed2011-07-01 19:47:50 +00001824 assert(image != (Image *) NULL);
1825 assert(image->signature == MagickSignature);
1826 if (image->debug != MagickFalse)
1827 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristy14d71292012-05-20 16:48:13 +00001828 length=strlen(map);
1829 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
cristy4c08aed2011-07-01 19:47:50 +00001830 if (quantum_map == (QuantumType *) NULL)
1831 {
1832 (void) ThrowMagickException(exception,GetMagickModule(),
anthonye5b39652012-04-21 05:37:29 +00001833 ResourceLimitError,"MemoryAllocationFailed","'%s'",image->filename);
cristy4c08aed2011-07-01 19:47:50 +00001834 return(MagickFalse);
1835 }
cristy14d71292012-05-20 16:48:13 +00001836 for (i=0; i < (ssize_t) length; i++)
cristy4c08aed2011-07-01 19:47:50 +00001837 {
1838 switch (map[i])
1839 {
1840 case 'A':
1841 case 'a':
1842 {
1843 quantum_map[i]=AlphaQuantum;
1844 break;
1845 }
1846 case 'B':
1847 case 'b':
1848 {
1849 quantum_map[i]=BlueQuantum;
1850 break;
1851 }
1852 case 'C':
1853 case 'c':
1854 {
1855 quantum_map[i]=CyanQuantum;
1856 if (image->colorspace == CMYKColorspace)
1857 break;
1858 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1859 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
anthonye5b39652012-04-21 05:37:29 +00001860 "ColorSeparatedImageRequired","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001861 return(MagickFalse);
1862 }
1863 case 'g':
1864 case 'G':
1865 {
1866 quantum_map[i]=GreenQuantum;
1867 break;
1868 }
1869 case 'I':
1870 case 'i':
1871 {
1872 quantum_map[i]=IndexQuantum;
1873 break;
1874 }
1875 case 'K':
1876 case 'k':
1877 {
1878 quantum_map[i]=BlackQuantum;
1879 if (image->colorspace == CMYKColorspace)
1880 break;
1881 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1882 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
anthonye5b39652012-04-21 05:37:29 +00001883 "ColorSeparatedImageRequired","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001884 return(MagickFalse);
1885 }
1886 case 'M':
1887 case 'm':
1888 {
1889 quantum_map[i]=MagentaQuantum;
1890 if (image->colorspace == CMYKColorspace)
1891 break;
1892 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1893 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
anthonye5b39652012-04-21 05:37:29 +00001894 "ColorSeparatedImageRequired","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001895 return(MagickFalse);
1896 }
1897 case 'o':
1898 case 'O':
1899 {
1900 quantum_map[i]=OpacityQuantum;
1901 break;
1902 }
1903 case 'P':
1904 case 'p':
1905 {
1906 quantum_map[i]=UndefinedQuantum;
1907 break;
1908 }
1909 case 'R':
1910 case 'r':
1911 {
1912 quantum_map[i]=RedQuantum;
1913 break;
1914 }
1915 case 'Y':
1916 case 'y':
1917 {
1918 quantum_map[i]=YellowQuantum;
1919 if (image->colorspace == CMYKColorspace)
1920 break;
1921 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1922 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
anthonye5b39652012-04-21 05:37:29 +00001923 "ColorSeparatedImageRequired","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001924 return(MagickFalse);
1925 }
1926 default:
1927 {
1928 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1929 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthonye5b39652012-04-21 05:37:29 +00001930 "UnrecognizedPixelMap","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001931 return(MagickFalse);
1932 }
1933 }
1934 }
cristycafe0412012-01-10 13:29:58 +00001935 roi.width=width;
1936 roi.height=height;
1937 roi.x=x;
1938 roi.y=y;
cristy4c08aed2011-07-01 19:47:50 +00001939 switch (type)
1940 {
1941 case CharPixel:
1942 {
cristycafe0412012-01-10 13:29:58 +00001943 ExportCharPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001944 break;
1945 }
1946 case DoublePixel:
1947 {
cristycafe0412012-01-10 13:29:58 +00001948 ExportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001949 break;
1950 }
1951 case FloatPixel:
1952 {
cristycafe0412012-01-10 13:29:58 +00001953 ExportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001954 break;
1955 }
cristy4c08aed2011-07-01 19:47:50 +00001956 case LongPixel:
1957 {
cristycafe0412012-01-10 13:29:58 +00001958 ExportLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001959 break;
1960 }
cristy6c9e1682012-01-07 21:37:44 +00001961 case LongLongPixel:
1962 {
cristycafe0412012-01-10 13:29:58 +00001963 ExportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy6c9e1682012-01-07 21:37:44 +00001964 break;
1965 }
cristy4c08aed2011-07-01 19:47:50 +00001966 case QuantumPixel:
1967 {
cristycafe0412012-01-10 13:29:58 +00001968 ExportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001969 break;
1970 }
1971 case ShortPixel:
1972 {
cristycafe0412012-01-10 13:29:58 +00001973 ExportShortPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001974 break;
1975 }
1976 default:
1977 {
1978 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1979 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthonye5b39652012-04-21 05:37:29 +00001980 "UnrecognizedPixelMap","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00001981 break;
1982 }
1983 }
1984 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1985 return(MagickTrue);
1986}
1987
1988/*
1989%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1990% %
1991% %
1992% %
cristyaa8634f2011-10-01 13:25:12 +00001993% G e t P i x e l I n f o %
cristy4c08aed2011-07-01 19:47:50 +00001994% %
1995% %
1996% %
1997%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1998%
1999% GetPixelInfo() initializes the PixelInfo structure.
2000%
2001% The format of the GetPixelInfo method is:
2002%
2003% GetPixelInfo(const Image *image,PixelInfo *pixel)
2004%
2005% A description of each parameter follows:
2006%
2007% o image: the image.
2008%
cristy101ab702011-10-13 13:06:32 +00002009% o pixel: Specifies a pointer to a PixelInfo structure.
cristy4c08aed2011-07-01 19:47:50 +00002010%
2011*/
cristyaa8634f2011-10-01 13:25:12 +00002012MagickExport void GetPixelInfo(const Image *image,PixelInfo *pixel)
cristy4c08aed2011-07-01 19:47:50 +00002013{
2014 pixel->storage_class=DirectClass;
cristy7020ae62012-04-18 12:58:34 +00002015 pixel->colorspace=sRGBColorspace;
cristy4c08aed2011-07-01 19:47:50 +00002016 pixel->matte=MagickFalse;
2017 pixel->fuzz=0.0;
2018 pixel->depth=MAGICKCORE_QUANTUM_DEPTH;
2019 pixel->red=0.0;
2020 pixel->green=0.0;
2021 pixel->blue=0.0;
2022 pixel->black=0.0;
2023 pixel->alpha=(MagickRealType) OpaqueAlpha;
2024 pixel->index=0.0;
2025 if (image == (const Image *) NULL)
2026 return;
2027 pixel->storage_class=image->storage_class;
2028 pixel->colorspace=image->colorspace;
2029 pixel->matte=image->matte;
2030 pixel->depth=image->depth;
2031 pixel->fuzz=image->fuzz;
2032}
2033
2034/*
2035%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2036% %
2037% %
2038% %
2039% I m p o r t I m a g e P i x e l s %
2040% %
2041% %
2042% %
2043%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2044%
2045% ImportImagePixels() accepts pixel data and stores in the image at the
2046% location you specify. The method returns MagickTrue on success otherwise
2047% MagickFalse if an error is encountered. The pixel data can be either char,
cristyb5a45a32012-01-10 13:31:13 +00002048% Quantum, short int, unsigned int, unsigned long long, float, or double in
2049% the order specified by map.
cristy4c08aed2011-07-01 19:47:50 +00002050%
2051% Suppose your want to upload the first scanline of a 640x480 image from
2052% character data in red-green-blue order:
2053%
2054% ImportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels);
2055%
2056% The format of the ImportImagePixels method is:
2057%
cristycafe0412012-01-10 13:29:58 +00002058% MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
2059% const ssize_t y,const size_t width,const size_t height,
2060% const char *map,const StorageType type,const void *pixels,
2061% ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00002062%
2063% A description of each parameter follows:
2064%
2065% o image: the image.
2066%
cristycafe0412012-01-10 13:29:58 +00002067% o x,y,width,height: These values define the perimeter
cristy4c08aed2011-07-01 19:47:50 +00002068% of a region of pixels you want to define.
2069%
2070% o map: This string reflects the expected ordering of the pixel array.
2071% It can be any combination or order of R = red, G = green, B = blue,
2072% A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
2073% Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
2074% P = pad.
2075%
2076% o type: Define the data type of the pixels. Float and double types are
2077% normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
cristy6c9e1682012-01-07 21:37:44 +00002078% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
cristyff6834e2012-01-10 03:00:25 +00002079% LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
cristy6c9e1682012-01-07 21:37:44 +00002080% QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
cristy4c08aed2011-07-01 19:47:50 +00002081%
2082% o pixels: This array of values contain the pixel components as defined by
2083% map and type. You must preallocate this array where the expected
2084% length varies depending on the values of width, height, map, and type.
2085%
cristy018f07f2011-09-04 21:15:19 +00002086% o exception: return any errors or warnings in this structure.
2087%
cristy4c08aed2011-07-01 19:47:50 +00002088*/
cristye5370942012-01-06 03:49:31 +00002089
cristycafe0412012-01-10 13:29:58 +00002090static void ImportCharPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002091 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2092 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002093{
2094 register const unsigned char
2095 *restrict p;
2096
2097 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002098 *restrict q;
cristye5370942012-01-06 03:49:31 +00002099
2100 register ssize_t
2101 x;
2102
cristy14d71292012-05-20 16:48:13 +00002103 size_t
2104 length;
2105
cristye5370942012-01-06 03:49:31 +00002106 ssize_t
2107 y;
2108
2109 p=(const unsigned char *) pixels;
2110 if (LocaleCompare(map,"BGR") == 0)
2111 {
cristycafe0412012-01-10 13:29:58 +00002112 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002113 {
cristycafe0412012-01-10 13:29:58 +00002114 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002115 if (q == (Quantum *) NULL)
2116 break;
cristycafe0412012-01-10 13:29:58 +00002117 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002118 {
2119 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2120 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2121 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2122 q+=GetPixelChannels(image);
2123 }
2124 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2125 break;
2126 }
2127 return;
2128 }
2129 if (LocaleCompare(map,"BGRA") == 0)
2130 {
cristycafe0412012-01-10 13:29:58 +00002131 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002132 {
cristycafe0412012-01-10 13:29:58 +00002133 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002134 if (q == (Quantum *) NULL)
2135 break;
cristycafe0412012-01-10 13:29:58 +00002136 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002137 {
2138 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2139 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2140 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2141 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2142 q+=GetPixelChannels(image);
2143 }
2144 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2145 break;
2146 }
2147 return;
2148 }
2149 if (LocaleCompare(map,"BGRO") == 0)
2150 {
cristycafe0412012-01-10 13:29:58 +00002151 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002152 {
cristycafe0412012-01-10 13:29:58 +00002153 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002154 if (q == (Quantum *) NULL)
2155 break;
cristycafe0412012-01-10 13:29:58 +00002156 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002157 {
2158 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2159 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2160 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2161 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2162 q+=GetPixelChannels(image);
2163 }
2164 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2165 break;
2166 }
2167 return;
2168 }
2169 if (LocaleCompare(map,"BGRP") == 0)
2170 {
cristycafe0412012-01-10 13:29:58 +00002171 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002172 {
cristycafe0412012-01-10 13:29:58 +00002173 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002174 if (q == (Quantum *) NULL)
2175 break;
cristycafe0412012-01-10 13:29:58 +00002176 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002177 {
2178 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2179 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2180 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2181 p++;
2182 q+=GetPixelChannels(image);
2183 }
2184 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2185 break;
2186 }
2187 return;
2188 }
2189 if (LocaleCompare(map,"I") == 0)
2190 {
cristy2dc655d2012-07-05 13:16:28 +00002191 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristycafe0412012-01-10 13:29:58 +00002192 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002193 {
cristycafe0412012-01-10 13:29:58 +00002194 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002195 if (q == (Quantum *) NULL)
2196 break;
cristycafe0412012-01-10 13:29:58 +00002197 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002198 {
2199 SetPixelGray(image,ScaleCharToQuantum(*p++),q);
2200 q+=GetPixelChannels(image);
2201 }
2202 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2203 break;
2204 }
2205 return;
2206 }
2207 if (LocaleCompare(map,"RGB") == 0)
2208 {
cristycafe0412012-01-10 13:29:58 +00002209 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002210 {
cristycafe0412012-01-10 13:29:58 +00002211 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002212 if (q == (Quantum *) NULL)
2213 break;
cristycafe0412012-01-10 13:29:58 +00002214 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002215 {
2216 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2217 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2218 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2219 q+=GetPixelChannels(image);
2220 }
2221 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2222 break;
2223 }
2224 return;
2225 }
2226 if (LocaleCompare(map,"RGBA") == 0)
2227 {
cristycafe0412012-01-10 13:29:58 +00002228 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002229 {
cristycafe0412012-01-10 13:29:58 +00002230 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002231 if (q == (Quantum *) NULL)
2232 break;
cristycafe0412012-01-10 13:29:58 +00002233 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002234 {
2235 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2236 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2237 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2238 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2239 q+=GetPixelChannels(image);
2240 }
2241 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2242 break;
2243 }
2244 return;
2245 }
2246 if (LocaleCompare(map,"RGBO") == 0)
2247 {
cristycafe0412012-01-10 13:29:58 +00002248 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002249 {
cristycafe0412012-01-10 13:29:58 +00002250 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002251 if (q == (Quantum *) NULL)
2252 break;
cristycafe0412012-01-10 13:29:58 +00002253 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002254 {
2255 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2256 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2257 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2258 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2259 q+=GetPixelChannels(image);
2260 }
2261 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2262 break;
2263 }
2264 return;
2265 }
2266 if (LocaleCompare(map,"RGBP") == 0)
2267 {
cristycafe0412012-01-10 13:29:58 +00002268 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002269 {
cristycafe0412012-01-10 13:29:58 +00002270 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002271 if (q == (Quantum *) NULL)
2272 break;
cristycafe0412012-01-10 13:29:58 +00002273 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002274 {
2275 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2276 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2277 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2278 p++;
2279 q+=GetPixelChannels(image);
2280 }
2281 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2282 break;
2283 }
2284 return;
2285 }
cristy14d71292012-05-20 16:48:13 +00002286 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00002287 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002288 {
cristycafe0412012-01-10 13:29:58 +00002289 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002290 if (q == (Quantum *) NULL)
2291 break;
cristycafe0412012-01-10 13:29:58 +00002292 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002293 {
2294 register ssize_t
2295 i;
2296
cristy14d71292012-05-20 16:48:13 +00002297 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00002298 {
2299 switch (quantum_map[i])
2300 {
2301 case RedQuantum:
2302 case CyanQuantum:
2303 {
2304 SetPixelRed(image,ScaleCharToQuantum(*p),q);
2305 break;
2306 }
2307 case GreenQuantum:
2308 case MagentaQuantum:
2309 {
2310 SetPixelGreen(image,ScaleCharToQuantum(*p),q);
2311 break;
2312 }
2313 case BlueQuantum:
2314 case YellowQuantum:
2315 {
2316 SetPixelBlue(image,ScaleCharToQuantum(*p),q);
2317 break;
2318 }
2319 case AlphaQuantum:
2320 {
2321 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2322 break;
2323 }
2324 case OpacityQuantum:
2325 {
2326 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2327 break;
2328 }
2329 case BlackQuantum:
2330 {
2331 SetPixelBlack(image,ScaleCharToQuantum(*p),q);
2332 break;
2333 }
2334 case IndexQuantum:
2335 {
2336 SetPixelGray(image,ScaleCharToQuantum(*p),q);
2337 break;
2338 }
2339 default:
2340 break;
2341 }
2342 p++;
2343 }
2344 q+=GetPixelChannels(image);
2345 }
2346 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2347 break;
2348 }
2349}
2350
cristycafe0412012-01-10 13:29:58 +00002351static void ImportDoublePixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002352 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2353 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002354{
2355 register const double
2356 *restrict p;
2357
2358 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002359 *restrict q;
cristye5370942012-01-06 03:49:31 +00002360
2361 register ssize_t
2362 x;
2363
cristy14d71292012-05-20 16:48:13 +00002364 size_t
2365 length;
2366
cristye5370942012-01-06 03:49:31 +00002367 ssize_t
2368 y;
2369
2370 p=(const double *) pixels;
2371 if (LocaleCompare(map,"BGR") == 0)
2372 {
cristycafe0412012-01-10 13:29:58 +00002373 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002374 {
cristycafe0412012-01-10 13:29:58 +00002375 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002376 if (q == (Quantum *) NULL)
2377 break;
cristycafe0412012-01-10 13:29:58 +00002378 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002379 {
2380 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2381 (*p)),q);
2382 p++;
2383 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2384 (*p)),q);
2385 p++;
2386 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2387 (*p)),q);
2388 p++;
2389 q+=GetPixelChannels(image);
2390 }
2391 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2392 break;
2393 }
2394 return;
2395 }
2396 if (LocaleCompare(map,"BGRA") == 0)
2397 {
cristycafe0412012-01-10 13:29:58 +00002398 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002399 {
cristycafe0412012-01-10 13:29:58 +00002400 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002401 if (q == (Quantum *) NULL)
2402 break;
cristycafe0412012-01-10 13:29:58 +00002403 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002404 {
2405 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2406 (*p)),q);
2407 p++;
2408 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2409 (*p)),q);
2410 p++;
2411 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2412 (*p)),q);
2413 p++;
2414 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2415 (*p)),q);
2416 p++;
2417 q+=GetPixelChannels(image);
2418 }
2419 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2420 break;
2421 }
2422 return;
2423 }
2424 if (LocaleCompare(map,"BGRP") == 0)
2425 {
cristycafe0412012-01-10 13:29:58 +00002426 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002427 {
cristycafe0412012-01-10 13:29:58 +00002428 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002429 if (q == (Quantum *) NULL)
2430 break;
cristycafe0412012-01-10 13:29:58 +00002431 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002432 {
2433 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2434 (*p)),q);
2435 p++;
2436 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2437 (*p)),q);
2438 p++;
2439 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2440 (*p)),q);
2441 p++;
2442 p++;
2443 q+=GetPixelChannels(image);
2444 }
2445 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2446 break;
2447 }
2448 return;
2449 }
2450 if (LocaleCompare(map,"I") == 0)
2451 {
cristy2dc655d2012-07-05 13:16:28 +00002452 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristycafe0412012-01-10 13:29:58 +00002453 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002454 {
cristycafe0412012-01-10 13:29:58 +00002455 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002456 if (q == (Quantum *) NULL)
2457 break;
cristycafe0412012-01-10 13:29:58 +00002458 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002459 {
2460 SetPixelGray(image,ClampToQuantum((MagickRealType) QuantumRange*
2461 (*p)),q);
2462 p++;
2463 q+=GetPixelChannels(image);
2464 }
2465 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2466 break;
2467 }
2468 return;
2469 }
2470 if (LocaleCompare(map,"RGB") == 0)
2471 {
cristycafe0412012-01-10 13:29:58 +00002472 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002473 {
cristycafe0412012-01-10 13:29:58 +00002474 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002475 if (q == (Quantum *) NULL)
2476 break;
cristycafe0412012-01-10 13:29:58 +00002477 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002478 {
2479 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2480 (*p)),q);
2481 p++;
2482 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2483 (*p)),q);
2484 p++;
2485 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2486 (*p)),q);
2487 p++;
2488 q+=GetPixelChannels(image);
2489 }
2490 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2491 break;
2492 }
2493 return;
2494 }
2495 if (LocaleCompare(map,"RGBA") == 0)
2496 {
cristycafe0412012-01-10 13:29:58 +00002497 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002498 {
cristycafe0412012-01-10 13:29:58 +00002499 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002500 if (q == (Quantum *) NULL)
2501 break;
cristycafe0412012-01-10 13:29:58 +00002502 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002503 {
2504 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2505 (*p)),q);
2506 p++;
2507 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2508 (*p)),q);
2509 p++;
2510 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2511 (*p)),q);
2512 p++;
2513 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2514 (*p)),q);
2515 p++;
2516 q+=GetPixelChannels(image);
2517 }
2518 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2519 break;
2520 }
2521 return;
2522 }
2523 if (LocaleCompare(map,"RGBP") == 0)
2524 {
cristycafe0412012-01-10 13:29:58 +00002525 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002526 {
cristycafe0412012-01-10 13:29:58 +00002527 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002528 if (q == (Quantum *) NULL)
2529 break;
cristycafe0412012-01-10 13:29:58 +00002530 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002531 {
2532 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2533 (*p)),q);
2534 p++;
2535 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2536 (*p)),q);
2537 p++;
2538 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2539 (*p)),q);
2540 p++;
2541 q+=GetPixelChannels(image);
2542 }
2543 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2544 break;
2545 }
2546 return;
2547 }
cristy14d71292012-05-20 16:48:13 +00002548 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00002549 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002550 {
cristycafe0412012-01-10 13:29:58 +00002551 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002552 if (q == (Quantum *) NULL)
2553 break;
cristycafe0412012-01-10 13:29:58 +00002554 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002555 {
2556 register ssize_t
2557 i;
2558
cristy14d71292012-05-20 16:48:13 +00002559 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00002560 {
2561 switch (quantum_map[i])
2562 {
2563 case RedQuantum:
2564 case CyanQuantum:
2565 {
2566 SetPixelRed(image,ClampToQuantum((MagickRealType)
2567 QuantumRange*(*p)),q);
2568 break;
2569 }
2570 case GreenQuantum:
2571 case MagentaQuantum:
2572 {
2573 SetPixelGreen(image,ClampToQuantum((MagickRealType)
2574 QuantumRange*(*p)),q);
2575 break;
2576 }
2577 case BlueQuantum:
2578 case YellowQuantum:
2579 {
2580 SetPixelBlue(image,ClampToQuantum((MagickRealType)
2581 QuantumRange*(*p)),q);
2582 break;
2583 }
2584 case AlphaQuantum:
2585 {
2586 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2587 QuantumRange*(*p)),q);
2588 break;
2589 }
2590 case OpacityQuantum:
2591 {
2592 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2593 QuantumRange*(*p)),q);
2594 break;
2595 }
2596 case BlackQuantum:
2597 {
2598 SetPixelBlack(image,ClampToQuantum((MagickRealType)
2599 QuantumRange*(*p)),q);
2600 break;
2601 }
2602 case IndexQuantum:
2603 {
2604 SetPixelGray(image,ClampToQuantum((MagickRealType)
2605 QuantumRange*(*p)),q);
2606 break;
2607 }
2608 default:
2609 break;
2610 }
2611 p++;
2612 }
2613 q+=GetPixelChannels(image);
2614 }
2615 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2616 break;
2617 }
2618}
2619
cristycafe0412012-01-10 13:29:58 +00002620static void ImportFloatPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002621 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2622 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002623{
2624 register const float
2625 *restrict p;
2626
2627 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002628 *restrict q;
cristye5370942012-01-06 03:49:31 +00002629
2630 register ssize_t
2631 x;
2632
cristy14d71292012-05-20 16:48:13 +00002633 size_t
2634 length;
2635
cristye5370942012-01-06 03:49:31 +00002636 ssize_t
2637 y;
2638
2639 p=(const float *) pixels;
2640 if (LocaleCompare(map,"BGR") == 0)
2641 {
cristycafe0412012-01-10 13:29:58 +00002642 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002643 {
cristycafe0412012-01-10 13:29:58 +00002644 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002645 if (q == (Quantum *) NULL)
2646 break;
cristycafe0412012-01-10 13:29:58 +00002647 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002648 {
2649 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2650 (*p)),q);
2651 p++;
2652 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2653 (*p)),q);
2654 p++;
2655 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2656 (*p)),q);
2657 p++;
2658 q+=GetPixelChannels(image);
2659 }
2660 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2661 break;
2662 }
2663 return;
2664 }
2665 if (LocaleCompare(map,"BGRA") == 0)
2666 {
cristycafe0412012-01-10 13:29:58 +00002667 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002668 {
cristycafe0412012-01-10 13:29:58 +00002669 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002670 if (q == (Quantum *) NULL)
2671 break;
cristycafe0412012-01-10 13:29:58 +00002672 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002673 {
2674 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2675 (*p)),q);
2676 p++;
2677 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2678 (*p)),q);
2679 p++;
2680 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2681 (*p)),q);
2682 p++;
2683 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2684 (*p)),q);
2685 p++;
2686 q+=GetPixelChannels(image);
2687 }
2688 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2689 break;
2690 }
2691 return;
2692 }
2693 if (LocaleCompare(map,"BGRP") == 0)
2694 {
cristycafe0412012-01-10 13:29:58 +00002695 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002696 {
cristycafe0412012-01-10 13:29:58 +00002697 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002698 if (q == (Quantum *) NULL)
2699 break;
cristycafe0412012-01-10 13:29:58 +00002700 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002701 {
2702 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2703 (*p)),q);
2704 p++;
2705 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2706 (*p)),q);
2707 p++;
2708 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2709 (*p)),q);
2710 p++;
2711 p++;
2712 q+=GetPixelChannels(image);
2713 }
2714 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2715 break;
2716 }
2717 return;
2718 }
2719 if (LocaleCompare(map,"I") == 0)
2720 {
cristy2dc655d2012-07-05 13:16:28 +00002721 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristycafe0412012-01-10 13:29:58 +00002722 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002723 {
cristycafe0412012-01-10 13:29:58 +00002724 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002725 if (q == (Quantum *) NULL)
2726 break;
cristycafe0412012-01-10 13:29:58 +00002727 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002728 {
2729 SetPixelGray(image,ClampToQuantum((MagickRealType) QuantumRange*
2730 (*p)),q);
2731 p++;
2732 q+=GetPixelChannels(image);
2733 }
2734 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2735 break;
2736 }
2737 return;
2738 }
2739 if (LocaleCompare(map,"RGB") == 0)
2740 {
cristycafe0412012-01-10 13:29:58 +00002741 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002742 {
cristycafe0412012-01-10 13:29:58 +00002743 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002744 if (q == (Quantum *) NULL)
2745 break;
cristycafe0412012-01-10 13:29:58 +00002746 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002747 {
2748 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2749 (*p)),q);
2750 p++;
2751 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2752 (*p)),q);
2753 p++;
2754 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2755 (*p)),q);
2756 p++;
2757 q+=GetPixelChannels(image);
2758 }
2759 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2760 break;
2761 }
2762 return;
2763 }
2764 if (LocaleCompare(map,"RGBA") == 0)
2765 {
cristycafe0412012-01-10 13:29:58 +00002766 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002767 {
cristycafe0412012-01-10 13:29:58 +00002768 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002769 if (q == (Quantum *) NULL)
2770 break;
cristycafe0412012-01-10 13:29:58 +00002771 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002772 {
2773 SetPixelRed(image,ClampToQuantum((MagickRealType)
2774 QuantumRange*(*p)),q);
2775 p++;
2776 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2777 (*p)),q);
2778 p++;
2779 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2780 (*p)),q);
2781 p++;
2782 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2783 (*p)),q);
2784 p++;
2785 q+=GetPixelChannels(image);
2786 }
2787 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2788 break;
2789 }
2790 return;
2791 }
2792 if (LocaleCompare(map,"RGBP") == 0)
2793 {
cristycafe0412012-01-10 13:29:58 +00002794 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002795 {
cristycafe0412012-01-10 13:29:58 +00002796 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002797 if (q == (Quantum *) NULL)
2798 break;
cristycafe0412012-01-10 13:29:58 +00002799 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002800 {
2801 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2802 (*p)),q);
2803 p++;
2804 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2805 (*p)),q);
2806 p++;
2807 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2808 (*p)),q);
2809 p++;
2810 q+=GetPixelChannels(image);
2811 }
2812 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2813 break;
2814 }
2815 return;
2816 }
cristy14d71292012-05-20 16:48:13 +00002817 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00002818 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002819 {
cristycafe0412012-01-10 13:29:58 +00002820 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002821 if (q == (Quantum *) NULL)
2822 break;
cristycafe0412012-01-10 13:29:58 +00002823 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002824 {
2825 register ssize_t
2826 i;
2827
cristy14d71292012-05-20 16:48:13 +00002828 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00002829 {
2830 switch (quantum_map[i])
2831 {
2832 case RedQuantum:
2833 case CyanQuantum:
2834 {
2835 SetPixelRed(image,ClampToQuantum((MagickRealType)
2836 QuantumRange*(*p)),q);
2837 break;
2838 }
2839 case GreenQuantum:
2840 case MagentaQuantum:
2841 {
2842 SetPixelGreen(image,ClampToQuantum((MagickRealType)
2843 QuantumRange*(*p)),q);
2844 break;
2845 }
2846 case BlueQuantum:
2847 case YellowQuantum:
2848 {
2849 SetPixelBlue(image,ClampToQuantum((MagickRealType)
2850 QuantumRange*(*p)),q);
2851 break;
2852 }
2853 case AlphaQuantum:
2854 {
2855 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2856 QuantumRange*(*p)),q);
2857 break;
2858 }
2859 case OpacityQuantum:
2860 {
2861 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2862 QuantumRange*(*p)),q);
2863 break;
2864 }
2865 case BlackQuantum:
2866 {
2867 SetPixelBlack(image,ClampToQuantum((MagickRealType)
2868 QuantumRange*(*p)),q);
2869 break;
2870 }
2871 case IndexQuantum:
2872 {
2873 SetPixelGray(image,ClampToQuantum((MagickRealType)
2874 QuantumRange*(*p)),q);
2875 break;
2876 }
2877 default:
2878 break;
2879 }
2880 p++;
2881 }
2882 q+=GetPixelChannels(image);
2883 }
2884 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2885 break;
2886 }
2887}
2888
cristycafe0412012-01-10 13:29:58 +00002889static void ImportLongPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002890 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2891 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002892{
2893 register const unsigned int
2894 *restrict p;
2895
2896 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002897 *restrict q;
cristye5370942012-01-06 03:49:31 +00002898
2899 register ssize_t
2900 x;
2901
cristy14d71292012-05-20 16:48:13 +00002902 size_t
2903 length;
2904
cristye5370942012-01-06 03:49:31 +00002905 ssize_t
2906 y;
2907
2908 p=(const unsigned int *) pixels;
2909 if (LocaleCompare(map,"BGR") == 0)
2910 {
cristycafe0412012-01-10 13:29:58 +00002911 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002912 {
cristycafe0412012-01-10 13:29:58 +00002913 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002914 if (q == (Quantum *) NULL)
2915 break;
cristycafe0412012-01-10 13:29:58 +00002916 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002917 {
2918 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2919 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2920 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2921 q+=GetPixelChannels(image);
2922 }
2923 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2924 break;
2925 }
2926 return;
2927 }
2928 if (LocaleCompare(map,"BGRA") == 0)
2929 {
cristycafe0412012-01-10 13:29:58 +00002930 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002931 {
cristycafe0412012-01-10 13:29:58 +00002932 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002933 if (q == (Quantum *) NULL)
2934 break;
cristycafe0412012-01-10 13:29:58 +00002935 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002936 {
2937 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2938 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2939 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2940 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
2941 q+=GetPixelChannels(image);
2942 }
2943 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2944 break;
2945 }
2946 return;
2947 }
2948 if (LocaleCompare(map,"BGRP") == 0)
2949 {
cristycafe0412012-01-10 13:29:58 +00002950 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002951 {
cristycafe0412012-01-10 13:29:58 +00002952 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002953 if (q == (Quantum *) NULL)
2954 break;
cristycafe0412012-01-10 13:29:58 +00002955 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002956 {
2957 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2958 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2959 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2960 p++;
2961 q+=GetPixelChannels(image);
2962 }
2963 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2964 break;
2965 }
2966 return;
2967 }
2968 if (LocaleCompare(map,"I") == 0)
2969 {
cristy2dc655d2012-07-05 13:16:28 +00002970 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristycafe0412012-01-10 13:29:58 +00002971 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002972 {
cristycafe0412012-01-10 13:29:58 +00002973 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002974 if (q == (Quantum *) NULL)
2975 break;
cristycafe0412012-01-10 13:29:58 +00002976 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002977 {
2978 SetPixelGray(image,ScaleLongToQuantum(*p++),q);
2979 q+=GetPixelChannels(image);
2980 }
2981 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2982 break;
2983 }
2984 return;
2985 }
2986 if (LocaleCompare(map,"RGB") == 0)
2987 {
cristycafe0412012-01-10 13:29:58 +00002988 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002989 {
cristycafe0412012-01-10 13:29:58 +00002990 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002991 if (q == (Quantum *) NULL)
2992 break;
cristycafe0412012-01-10 13:29:58 +00002993 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002994 {
2995 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2996 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2997 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2998 q+=GetPixelChannels(image);
2999 }
3000 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3001 break;
3002 }
3003 return;
3004 }
3005 if (LocaleCompare(map,"RGBA") == 0)
3006 {
cristycafe0412012-01-10 13:29:58 +00003007 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003008 {
cristycafe0412012-01-10 13:29:58 +00003009 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003010 if (q == (Quantum *) NULL)
3011 break;
cristycafe0412012-01-10 13:29:58 +00003012 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003013 {
3014 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3015 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3016 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3017 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
3018 q+=GetPixelChannels(image);
3019 }
3020 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3021 break;
3022 }
3023 return;
3024 }
3025 if (LocaleCompare(map,"RGBP") == 0)
3026 {
cristycafe0412012-01-10 13:29:58 +00003027 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003028 {
cristycafe0412012-01-10 13:29:58 +00003029 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003030 if (q == (Quantum *) NULL)
3031 break;
cristycafe0412012-01-10 13:29:58 +00003032 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003033 {
3034 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3035 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3036 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3037 p++;
3038 q+=GetPixelChannels(image);
3039 }
3040 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3041 break;
3042 }
3043 return;
3044 }
cristy14d71292012-05-20 16:48:13 +00003045 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003046 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003047 {
cristycafe0412012-01-10 13:29:58 +00003048 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003049 if (q == (Quantum *) NULL)
3050 break;
cristycafe0412012-01-10 13:29:58 +00003051 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003052 {
3053 register ssize_t
3054 i;
3055
cristy14d71292012-05-20 16:48:13 +00003056 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003057 {
3058 switch (quantum_map[i])
3059 {
3060 case RedQuantum:
3061 case CyanQuantum:
3062 {
3063 SetPixelRed(image,ScaleLongToQuantum(*p),q);
3064 break;
3065 }
3066 case GreenQuantum:
3067 case MagentaQuantum:
3068 {
3069 SetPixelGreen(image,ScaleLongToQuantum(*p),q);
3070 break;
3071 }
3072 case BlueQuantum:
3073 case YellowQuantum:
3074 {
3075 SetPixelBlue(image,ScaleLongToQuantum(*p),q);
3076 break;
3077 }
3078 case AlphaQuantum:
3079 {
3080 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3081 break;
3082 }
3083 case OpacityQuantum:
3084 {
3085 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3086 break;
3087 }
3088 case BlackQuantum:
3089 {
3090 SetPixelBlack(image,ScaleLongToQuantum(*p),q);
3091 break;
3092 }
3093 case IndexQuantum:
3094 {
3095 SetPixelGray(image,ScaleLongToQuantum(*p),q);
3096 break;
3097 }
3098 default:
3099 break;
3100 }
3101 p++;
3102 }
3103 q+=GetPixelChannels(image);
3104 }
3105 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3106 break;
3107 }
3108}
3109
cristycafe0412012-01-10 13:29:58 +00003110static void ImportLongLongPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003111 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3112 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003113{
cristyb13e12a2012-01-06 21:48:27 +00003114 register const MagickSizeType
cristye5370942012-01-06 03:49:31 +00003115 *restrict p;
3116
3117 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003118 *restrict q;
cristye5370942012-01-06 03:49:31 +00003119
3120 register ssize_t
3121 x;
3122
cristy14d71292012-05-20 16:48:13 +00003123 size_t
3124 length;
3125
cristye5370942012-01-06 03:49:31 +00003126 ssize_t
3127 y;
3128
cristyb13e12a2012-01-06 21:48:27 +00003129 p=(const MagickSizeType *) pixels;
cristye5370942012-01-06 03:49:31 +00003130 if (LocaleCompare(map,"BGR") == 0)
3131 {
cristycafe0412012-01-10 13:29:58 +00003132 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003133 {
cristycafe0412012-01-10 13:29:58 +00003134 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003135 if (q == (Quantum *) NULL)
3136 break;
cristycafe0412012-01-10 13:29:58 +00003137 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003138 {
cristyb13e12a2012-01-06 21:48:27 +00003139 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3140 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3141 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003142 q+=GetPixelChannels(image);
3143 }
3144 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3145 break;
3146 }
3147 return;
3148 }
3149 if (LocaleCompare(map,"BGRA") == 0)
3150 {
cristycafe0412012-01-10 13:29:58 +00003151 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003152 {
cristycafe0412012-01-10 13:29:58 +00003153 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003154 if (q == (Quantum *) NULL)
3155 break;
cristycafe0412012-01-10 13:29:58 +00003156 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003157 {
cristyb13e12a2012-01-06 21:48:27 +00003158 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3159 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3160 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3161 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003162 q+=GetPixelChannels(image);
3163 }
3164 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3165 break;
3166 }
3167 return;
3168 }
3169 if (LocaleCompare(map,"BGRP") == 0)
3170 {
cristycafe0412012-01-10 13:29:58 +00003171 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003172 {
cristycafe0412012-01-10 13:29:58 +00003173 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003174 if (q == (Quantum *) NULL)
3175 break;
cristycafe0412012-01-10 13:29:58 +00003176 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003177 {
cristyb13e12a2012-01-06 21:48:27 +00003178 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3179 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3180 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003181 p++;
3182 q+=GetPixelChannels(image);
3183 }
3184 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3185 break;
3186 }
3187 return;
3188 }
3189 if (LocaleCompare(map,"I") == 0)
3190 {
cristy2dc655d2012-07-05 13:16:28 +00003191 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristycafe0412012-01-10 13:29:58 +00003192 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003193 {
cristycafe0412012-01-10 13:29:58 +00003194 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003195 if (q == (Quantum *) NULL)
3196 break;
cristycafe0412012-01-10 13:29:58 +00003197 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003198 {
cristyb13e12a2012-01-06 21:48:27 +00003199 SetPixelGray(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003200 q+=GetPixelChannels(image);
3201 }
3202 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3203 break;
3204 }
3205 return;
3206 }
3207 if (LocaleCompare(map,"RGB") == 0)
3208 {
cristycafe0412012-01-10 13:29:58 +00003209 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003210 {
cristycafe0412012-01-10 13:29:58 +00003211 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003212 if (q == (Quantum *) NULL)
3213 break;
cristycafe0412012-01-10 13:29:58 +00003214 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003215 {
cristyb13e12a2012-01-06 21:48:27 +00003216 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3217 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3218 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003219 q+=GetPixelChannels(image);
3220 }
3221 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3222 break;
3223 }
3224 return;
3225 }
3226 if (LocaleCompare(map,"RGBA") == 0)
3227 {
cristycafe0412012-01-10 13:29:58 +00003228 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003229 {
cristycafe0412012-01-10 13:29:58 +00003230 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003231 if (q == (Quantum *) NULL)
3232 break;
cristycafe0412012-01-10 13:29:58 +00003233 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003234 {
cristyb13e12a2012-01-06 21:48:27 +00003235 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3236 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3237 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3238 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003239 q+=GetPixelChannels(image);
3240 }
3241 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3242 break;
3243 }
3244 return;
3245 }
3246 if (LocaleCompare(map,"RGBP") == 0)
3247 {
cristycafe0412012-01-10 13:29:58 +00003248 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003249 {
cristycafe0412012-01-10 13:29:58 +00003250 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003251 if (q == (Quantum *) NULL)
3252 break;
cristycafe0412012-01-10 13:29:58 +00003253 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003254 {
cristyb13e12a2012-01-06 21:48:27 +00003255 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3256 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3257 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003258 p++;
3259 q+=GetPixelChannels(image);
3260 }
3261 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3262 break;
3263 }
3264 return;
3265 }
cristy14d71292012-05-20 16:48:13 +00003266 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003267 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003268 {
cristycafe0412012-01-10 13:29:58 +00003269 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003270 if (q == (Quantum *) NULL)
3271 break;
cristycafe0412012-01-10 13:29:58 +00003272 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003273 {
3274 register ssize_t
3275 i;
3276
cristy14d71292012-05-20 16:48:13 +00003277 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003278 {
3279 switch (quantum_map[i])
3280 {
3281 case RedQuantum:
3282 case CyanQuantum:
3283 {
cristyb13e12a2012-01-06 21:48:27 +00003284 SetPixelRed(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003285 break;
3286 }
3287 case GreenQuantum:
3288 case MagentaQuantum:
3289 {
cristyb13e12a2012-01-06 21:48:27 +00003290 SetPixelGreen(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003291 break;
3292 }
3293 case BlueQuantum:
3294 case YellowQuantum:
3295 {
cristyb13e12a2012-01-06 21:48:27 +00003296 SetPixelBlue(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003297 break;
3298 }
3299 case AlphaQuantum:
3300 {
cristyb13e12a2012-01-06 21:48:27 +00003301 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003302 break;
3303 }
3304 case OpacityQuantum:
3305 {
cristyb13e12a2012-01-06 21:48:27 +00003306 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003307 break;
3308 }
3309 case BlackQuantum:
3310 {
cristyb13e12a2012-01-06 21:48:27 +00003311 SetPixelBlack(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003312 break;
3313 }
3314 case IndexQuantum:
3315 {
cristyb13e12a2012-01-06 21:48:27 +00003316 SetPixelGray(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003317 break;
3318 }
3319 default:
3320 break;
3321 }
3322 p++;
3323 }
3324 q+=GetPixelChannels(image);
3325 }
3326 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3327 break;
3328 }
3329}
3330
cristycafe0412012-01-10 13:29:58 +00003331static void ImportQuantumPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003332 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3333 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003334{
3335 register const Quantum
3336 *restrict p;
3337
3338 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003339 *restrict q;
cristye5370942012-01-06 03:49:31 +00003340
3341 register ssize_t
3342 x;
3343
cristy14d71292012-05-20 16:48:13 +00003344 size_t
3345 length;
3346
cristye5370942012-01-06 03:49:31 +00003347 ssize_t
3348 y;
3349
3350 p=(const Quantum *) pixels;
3351 if (LocaleCompare(map,"BGR") == 0)
3352 {
cristycafe0412012-01-10 13:29:58 +00003353 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003354 {
cristycafe0412012-01-10 13:29:58 +00003355 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003356 if (q == (Quantum *) NULL)
3357 break;
cristycafe0412012-01-10 13:29:58 +00003358 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003359 {
3360 SetPixelBlue(image,*p++,q);
3361 SetPixelGreen(image,*p++,q);
3362 SetPixelRed(image,*p++,q);
3363 q+=GetPixelChannels(image);
3364 }
3365 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3366 break;
3367 }
3368 return;
3369 }
3370 if (LocaleCompare(map,"BGRA") == 0)
3371 {
cristycafe0412012-01-10 13:29:58 +00003372 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003373 {
cristycafe0412012-01-10 13:29:58 +00003374 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003375 if (q == (Quantum *) NULL)
3376 break;
cristycafe0412012-01-10 13:29:58 +00003377 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003378 {
3379 SetPixelBlue(image,*p++,q);
3380 SetPixelGreen(image,*p++,q);
3381 SetPixelRed(image,*p++,q);
3382 SetPixelAlpha(image,*p++,q);
3383 q+=GetPixelChannels(image);
3384 }
3385 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3386 break;
3387 }
3388 return;
3389 }
3390 if (LocaleCompare(map,"BGRP") == 0)
3391 {
cristycafe0412012-01-10 13:29:58 +00003392 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003393 {
cristycafe0412012-01-10 13:29:58 +00003394 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003395 if (q == (Quantum *) NULL)
3396 break;
cristycafe0412012-01-10 13:29:58 +00003397 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003398 {
3399 SetPixelBlue(image,*p++,q);
3400 SetPixelGreen(image,*p++,q);
3401 SetPixelRed(image,*p++,q);
3402 p++;
3403 q+=GetPixelChannels(image);
3404 }
3405 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3406 break;
3407 }
3408 return;
3409 }
3410 if (LocaleCompare(map,"I") == 0)
3411 {
cristy2dc655d2012-07-05 13:16:28 +00003412 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristycafe0412012-01-10 13:29:58 +00003413 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003414 {
cristycafe0412012-01-10 13:29:58 +00003415 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003416 if (q == (Quantum *) NULL)
3417 break;
cristycafe0412012-01-10 13:29:58 +00003418 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003419 {
3420 SetPixelGray(image,*p++,q);
3421 q+=GetPixelChannels(image);
3422 }
3423 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3424 break;
3425 }
3426 return;
3427 }
3428 if (LocaleCompare(map,"RGB") == 0)
3429 {
cristycafe0412012-01-10 13:29:58 +00003430 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003431 {
cristycafe0412012-01-10 13:29:58 +00003432 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003433 if (q == (Quantum *) NULL)
3434 break;
cristycafe0412012-01-10 13:29:58 +00003435 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003436 {
3437 SetPixelRed(image,*p++,q);
3438 SetPixelGreen(image,*p++,q);
3439 SetPixelBlue(image,*p++,q);
3440 q+=GetPixelChannels(image);
3441 }
3442 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3443 break;
3444 }
3445 return;
3446 }
3447 if (LocaleCompare(map,"RGBA") == 0)
3448 {
cristycafe0412012-01-10 13:29:58 +00003449 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003450 {
cristycafe0412012-01-10 13:29:58 +00003451 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003452 if (q == (Quantum *) NULL)
3453 break;
cristycafe0412012-01-10 13:29:58 +00003454 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003455 {
3456 SetPixelRed(image,*p++,q);
3457 SetPixelGreen(image,*p++,q);
3458 SetPixelBlue(image,*p++,q);
3459 SetPixelAlpha(image,*p++,q);
3460 q+=GetPixelChannels(image);
3461 }
3462 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3463 break;
3464 }
3465 return;
3466 }
3467 if (LocaleCompare(map,"RGBP") == 0)
3468 {
cristycafe0412012-01-10 13:29:58 +00003469 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003470 {
cristycafe0412012-01-10 13:29:58 +00003471 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003472 if (q == (Quantum *) NULL)
3473 break;
cristycafe0412012-01-10 13:29:58 +00003474 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003475 {
3476 SetPixelRed(image,*p++,q);
3477 SetPixelGreen(image,*p++,q);
3478 SetPixelBlue(image,*p++,q);
3479 p++;
3480 q+=GetPixelChannels(image);
3481 }
3482 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3483 break;
3484 }
3485 return;
3486 }
cristy14d71292012-05-20 16:48:13 +00003487 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003488 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003489 {
cristycafe0412012-01-10 13:29:58 +00003490 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003491 if (q == (Quantum *) NULL)
3492 break;
cristycafe0412012-01-10 13:29:58 +00003493 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003494 {
3495 register ssize_t
3496 i;
3497
cristy14d71292012-05-20 16:48:13 +00003498 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003499 {
3500 switch (quantum_map[i])
3501 {
3502 case RedQuantum:
3503 case CyanQuantum:
3504 {
3505 SetPixelRed(image,*p,q);
3506 break;
3507 }
3508 case GreenQuantum:
3509 case MagentaQuantum:
3510 {
3511 SetPixelGreen(image,*p,q);
3512 break;
3513 }
3514 case BlueQuantum:
3515 case YellowQuantum:
3516 {
3517 SetPixelBlue(image,*p,q);
3518 break;
3519 }
3520 case AlphaQuantum:
3521 {
3522 SetPixelAlpha(image,*p,q);
3523 break;
3524 }
3525 case OpacityQuantum:
3526 {
3527 SetPixelAlpha(image,*p,q);
3528 break;
3529 }
3530 case BlackQuantum:
3531 {
3532 SetPixelBlack(image,*p,q);
3533 break;
3534 }
3535 case IndexQuantum:
3536 {
3537 SetPixelGray(image,*p,q);
3538 break;
3539 }
3540 default:
3541 break;
3542 }
3543 p++;
3544 }
3545 q+=GetPixelChannels(image);
3546 }
3547 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3548 break;
3549 }
3550}
3551
cristycafe0412012-01-10 13:29:58 +00003552static void ImportShortPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003553 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3554 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003555{
3556 register const unsigned short
3557 *restrict p;
3558
3559 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003560 *restrict q;
cristye5370942012-01-06 03:49:31 +00003561
3562 register ssize_t
3563 x;
3564
cristy14d71292012-05-20 16:48:13 +00003565 size_t
3566 length;
3567
cristye5370942012-01-06 03:49:31 +00003568 ssize_t
3569 y;
3570
3571 p=(const unsigned short *) pixels;
3572 if (LocaleCompare(map,"BGR") == 0)
3573 {
cristycafe0412012-01-10 13:29:58 +00003574 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003575 {
cristycafe0412012-01-10 13:29:58 +00003576 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003577 if (q == (Quantum *) NULL)
3578 break;
cristycafe0412012-01-10 13:29:58 +00003579 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003580 {
3581 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3582 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3583 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3584 q+=GetPixelChannels(image);
3585 }
3586 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3587 break;
3588 }
3589 return;
3590 }
3591 if (LocaleCompare(map,"BGRA") == 0)
3592 {
cristycafe0412012-01-10 13:29:58 +00003593 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003594 {
cristycafe0412012-01-10 13:29:58 +00003595 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003596 if (q == (Quantum *) NULL)
3597 break;
cristycafe0412012-01-10 13:29:58 +00003598 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003599 {
3600 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3601 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3602 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3603 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3604 q+=GetPixelChannels(image);
3605 }
3606 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3607 break;
3608 }
3609 return;
3610 }
3611 if (LocaleCompare(map,"BGRP") == 0)
3612 {
cristycafe0412012-01-10 13:29:58 +00003613 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003614 {
cristycafe0412012-01-10 13:29:58 +00003615 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003616 if (q == (Quantum *) NULL)
3617 break;
cristycafe0412012-01-10 13:29:58 +00003618 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003619 {
3620 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3621 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3622 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3623 p++;
3624 q+=GetPixelChannels(image);
3625 }
3626 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3627 break;
3628 }
3629 return;
3630 }
3631 if (LocaleCompare(map,"I") == 0)
3632 {
cristy2dc655d2012-07-05 13:16:28 +00003633 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristycafe0412012-01-10 13:29:58 +00003634 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003635 {
cristycafe0412012-01-10 13:29:58 +00003636 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003637 if (q == (Quantum *) NULL)
3638 break;
cristycafe0412012-01-10 13:29:58 +00003639 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003640 {
3641 SetPixelGray(image,ScaleShortToQuantum(*p++),q);
3642 q+=GetPixelChannels(image);
3643 }
3644 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3645 break;
3646 }
3647 return;
3648 }
3649 if (LocaleCompare(map,"RGB") == 0)
3650 {
cristycafe0412012-01-10 13:29:58 +00003651 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003652 {
cristycafe0412012-01-10 13:29:58 +00003653 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003654 if (q == (Quantum *) NULL)
3655 break;
cristycafe0412012-01-10 13:29:58 +00003656 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003657 {
3658 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3659 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3660 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3661 q+=GetPixelChannels(image);
3662 }
3663 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3664 break;
3665 }
3666 return;
3667 }
3668 if (LocaleCompare(map,"RGBA") == 0)
3669 {
cristycafe0412012-01-10 13:29:58 +00003670 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003671 {
cristycafe0412012-01-10 13:29:58 +00003672 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003673 if (q == (Quantum *) NULL)
3674 break;
cristycafe0412012-01-10 13:29:58 +00003675 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003676 {
3677 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3678 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3679 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3680 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3681 q+=GetPixelChannels(image);
3682 }
3683 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3684 break;
3685 }
3686 return;
3687 }
3688 if (LocaleCompare(map,"RGBP") == 0)
3689 {
cristycafe0412012-01-10 13:29:58 +00003690 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003691 {
cristycafe0412012-01-10 13:29:58 +00003692 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003693 if (q == (Quantum *) NULL)
3694 break;
cristycafe0412012-01-10 13:29:58 +00003695 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003696 {
3697 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3698 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3699 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3700 p++;
3701 q+=GetPixelChannels(image);
3702 }
3703 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3704 break;
3705 }
3706 return;
3707 }
cristy14d71292012-05-20 16:48:13 +00003708 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003709 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003710 {
cristycafe0412012-01-10 13:29:58 +00003711 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003712 if (q == (Quantum *) NULL)
3713 break;
cristycafe0412012-01-10 13:29:58 +00003714 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003715 {
3716 register ssize_t
3717 i;
3718
cristy14d71292012-05-20 16:48:13 +00003719 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003720 {
3721 switch (quantum_map[i])
3722 {
3723 case RedQuantum:
3724 case CyanQuantum:
3725 {
3726 SetPixelRed(image,ScaleShortToQuantum(*p),q);
3727 break;
3728 }
3729 case GreenQuantum:
3730 case MagentaQuantum:
3731 {
3732 SetPixelGreen(image,ScaleShortToQuantum(*p),q);
3733 break;
3734 }
3735 case BlueQuantum:
3736 case YellowQuantum:
3737 {
3738 SetPixelBlue(image,ScaleShortToQuantum(*p),q);
3739 break;
3740 }
3741 case AlphaQuantum:
3742 {
3743 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
3744 break;
3745 }
3746 case OpacityQuantum:
3747 {
3748 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
3749 break;
3750 }
3751 case BlackQuantum:
3752 {
3753 SetPixelBlack(image,ScaleShortToQuantum(*p),q);
3754 break;
3755 }
3756 case IndexQuantum:
3757 {
3758 SetPixelGray(image,ScaleShortToQuantum(*p),q);
3759 break;
3760 }
3761 default:
3762 break;
3763 }
3764 p++;
3765 }
3766 q+=GetPixelChannels(image);
3767 }
3768 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3769 break;
3770 }
3771}
3772
cristycafe0412012-01-10 13:29:58 +00003773MagickExport MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
3774 const ssize_t y,const size_t width,const size_t height,const char *map,
3775 const StorageType type,const void *pixels,ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00003776{
cristy4c08aed2011-07-01 19:47:50 +00003777 QuantumType
3778 *quantum_map;
3779
cristycafe0412012-01-10 13:29:58 +00003780 RectangleInfo
3781 roi;
3782
cristy4c08aed2011-07-01 19:47:50 +00003783 register ssize_t
cristye5370942012-01-06 03:49:31 +00003784 i;
cristy4c08aed2011-07-01 19:47:50 +00003785
cristy14d71292012-05-20 16:48:13 +00003786 size_t
3787 length;
3788
cristy4c08aed2011-07-01 19:47:50 +00003789 /*
3790 Allocate image structure.
3791 */
3792 assert(image != (Image *) NULL);
3793 assert(image->signature == MagickSignature);
3794 if (image->debug != MagickFalse)
3795 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristy14d71292012-05-20 16:48:13 +00003796 length=strlen(map);
3797 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
cristy4c08aed2011-07-01 19:47:50 +00003798 if (quantum_map == (QuantumType *) NULL)
3799 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
3800 image->filename);
cristy14d71292012-05-20 16:48:13 +00003801 for (i=0; i < (ssize_t) length; i++)
cristy4c08aed2011-07-01 19:47:50 +00003802 {
3803 switch (map[i])
3804 {
3805 case 'a':
3806 case 'A':
3807 {
3808 quantum_map[i]=AlphaQuantum;
3809 image->matte=MagickTrue;
3810 break;
3811 }
3812 case 'B':
3813 case 'b':
3814 {
3815 quantum_map[i]=BlueQuantum;
3816 break;
3817 }
3818 case 'C':
3819 case 'c':
3820 {
3821 quantum_map[i]=CyanQuantum;
cristy63240882011-08-05 19:05:27 +00003822 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003823 break;
3824 }
3825 case 'g':
3826 case 'G':
3827 {
3828 quantum_map[i]=GreenQuantum;
3829 break;
3830 }
3831 case 'K':
3832 case 'k':
3833 {
3834 quantum_map[i]=BlackQuantum;
cristy63240882011-08-05 19:05:27 +00003835 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003836 break;
3837 }
3838 case 'I':
3839 case 'i':
3840 {
3841 quantum_map[i]=IndexQuantum;
3842 break;
3843 }
3844 case 'm':
3845 case 'M':
3846 {
3847 quantum_map[i]=MagentaQuantum;
cristy63240882011-08-05 19:05:27 +00003848 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003849 break;
3850 }
3851 case 'O':
3852 case 'o':
3853 {
3854 quantum_map[i]=OpacityQuantum;
3855 image->matte=MagickTrue;
3856 break;
3857 }
3858 case 'P':
3859 case 'p':
3860 {
3861 quantum_map[i]=UndefinedQuantum;
3862 break;
3863 }
3864 case 'R':
3865 case 'r':
3866 {
3867 quantum_map[i]=RedQuantum;
3868 break;
3869 }
3870 case 'Y':
3871 case 'y':
3872 {
3873 quantum_map[i]=YellowQuantum;
cristy63240882011-08-05 19:05:27 +00003874 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003875 break;
3876 }
3877 default:
3878 {
3879 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
cristy63240882011-08-05 19:05:27 +00003880 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthonye5b39652012-04-21 05:37:29 +00003881 "UnrecognizedPixelMap","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00003882 return(MagickFalse);
3883 }
3884 }
3885 }
cristy63240882011-08-05 19:05:27 +00003886 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
cristy4c08aed2011-07-01 19:47:50 +00003887 return(MagickFalse);
3888 /*
cristye5370942012-01-06 03:49:31 +00003889 Transfer the pixels from the pixel data to the image.
cristy4c08aed2011-07-01 19:47:50 +00003890 */
cristycafe0412012-01-10 13:29:58 +00003891 roi.width=width;
3892 roi.height=height;
3893 roi.x=x;
3894 roi.y=y;
cristy4c08aed2011-07-01 19:47:50 +00003895 switch (type)
3896 {
3897 case CharPixel:
3898 {
cristycafe0412012-01-10 13:29:58 +00003899 ImportCharPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003900 break;
3901 }
3902 case DoublePixel:
3903 {
cristycafe0412012-01-10 13:29:58 +00003904 ImportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003905 break;
3906 }
3907 case FloatPixel:
3908 {
cristycafe0412012-01-10 13:29:58 +00003909 ImportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003910 break;
3911 }
cristy4c08aed2011-07-01 19:47:50 +00003912 case LongPixel:
3913 {
cristycafe0412012-01-10 13:29:58 +00003914 ImportLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003915 break;
3916 }
cristy6c9e1682012-01-07 21:37:44 +00003917 case LongLongPixel:
3918 {
cristycafe0412012-01-10 13:29:58 +00003919 ImportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy6c9e1682012-01-07 21:37:44 +00003920 break;
3921 }
cristy4c08aed2011-07-01 19:47:50 +00003922 case QuantumPixel:
3923 {
cristycafe0412012-01-10 13:29:58 +00003924 ImportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003925 break;
3926 }
3927 case ShortPixel:
3928 {
cristycafe0412012-01-10 13:29:58 +00003929 ImportShortPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003930 break;
3931 }
3932 default:
3933 {
3934 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
cristyc82a27b2011-10-21 01:07:16 +00003935 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthonye5b39652012-04-21 05:37:29 +00003936 "UnrecognizedPixelMap","'%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00003937 break;
3938 }
3939 }
3940 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
3941 return(MagickTrue);
3942}
3943
3944/*
3945%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3946% %
3947% %
3948% %
cristybd5a96c2011-08-21 00:04:26 +00003949+ 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 %
3950% %
3951% %
3952% %
3953%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3954%
3955% InitializePixelChannelMap() defines the standard pixel component map.
3956%
3957% The format of the InitializePixelChannelMap() method is:
3958%
3959% void InitializePixelChannelMap(Image *image)
3960%
3961% A description of each parameter follows:
3962%
3963% o image: the image.
3964%
3965*/
cristye2a912b2011-12-05 20:02:07 +00003966MagickExport void InitializePixelChannelMap(Image *image)
cristy77c30f52011-10-24 18:56:57 +00003967{
cristye2a912b2011-12-05 20:02:07 +00003968 PixelTrait
3969 trait;
3970
cristy77c30f52011-10-24 18:56:57 +00003971 register ssize_t
3972 i;
3973
cristyd26338f2011-12-14 02:39:30 +00003974 ssize_t
cristy77c30f52011-10-24 18:56:57 +00003975 n;
3976
3977 assert(image != (Image *) NULL);
3978 assert(image->signature == MagickSignature);
cristye2a912b2011-12-05 20:02:07 +00003979 (void) ResetMagickMemory(image->channel_map,0,MaxPixelChannels*
3980 sizeof(*image->channel_map));
3981 trait=UpdatePixelTrait;
3982 if (image->matte != MagickFalse)
cristy61f18ad2011-12-08 21:12:37 +00003983 trait=(PixelTrait) (trait | BlendPixelTrait);
cristy77c30f52011-10-24 18:56:57 +00003984 n=0;
cristyc06c5802011-12-31 23:36:16 +00003985 if (image->colorspace == GRAYColorspace)
cristy77c30f52011-10-24 18:56:57 +00003986 {
cristy3c316282011-12-15 15:43:24 +00003987 SetPixelChannelMap(image,BluePixelChannel,trait,n);
cristye2a912b2011-12-05 20:02:07 +00003988 SetPixelChannelMap(image,GreenPixelChannel,trait,n);
cristy3c316282011-12-15 15:43:24 +00003989 SetPixelChannelMap(image,RedPixelChannel,trait,n++);
3990 }
3991 else
3992 {
3993 SetPixelChannelMap(image,RedPixelChannel,trait,n++);
3994 SetPixelChannelMap(image,GreenPixelChannel,trait,n++);
cristye2a912b2011-12-05 20:02:07 +00003995 SetPixelChannelMap(image,BluePixelChannel,trait,n++);
cristy77c30f52011-10-24 18:56:57 +00003996 }
3997 if (image->colorspace == CMYKColorspace)
cristye2a912b2011-12-05 20:02:07 +00003998 SetPixelChannelMap(image,BlackPixelChannel,trait,n++);
cristy77c30f52011-10-24 18:56:57 +00003999 if (image->matte != MagickFalse)
cristye2a912b2011-12-05 20:02:07 +00004000 SetPixelChannelMap(image,AlphaPixelChannel,CopyPixelTrait,n++);
4001 if (image->storage_class == PseudoClass)
4002 SetPixelChannelMap(image,IndexPixelChannel,CopyPixelTrait,n++);
cristy183a5c72012-01-30 01:40:35 +00004003 if (image->mask != MagickFalse)
cristy10a6c612012-01-29 21:41:05 +00004004 SetPixelChannelMap(image,MaskPixelChannel,CopyPixelTrait,n++);
cristye2a912b2011-12-05 20:02:07 +00004005 assert((n+image->number_meta_channels) < MaxPixelChannels);
4006 for (i=0; i < (ssize_t) image->number_meta_channels; i++)
cristy61f18ad2011-12-08 21:12:37 +00004007 SetPixelChannelMap(image,(PixelChannel) (MetaPixelChannel+i),CopyPixelTrait,
cristye2a912b2011-12-05 20:02:07 +00004008 n++);
cristyd26338f2011-12-14 02:39:30 +00004009 image->number_channels=(size_t) n;
cristy77c30f52011-10-24 18:56:57 +00004010 if (image->debug != MagickFalse)
4011 LogPixelChannels(image);
4012 (void) SetPixelChannelMask(image,image->channel_mask);
4013}
cristybd5a96c2011-08-21 00:04:26 +00004014
4015/*
4016%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4017% %
4018% %
4019% %
cristya085a432011-07-30 01:39:32 +00004020% I n t e r p o l a t e P i x e l C h a n n e l %
4021% %
4022% %
4023% %
4024%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4025%
cristy884f6002011-07-31 00:51:45 +00004026% InterpolatePixelChannel() applies a pixel interpolation method between a
4027% floating point coordinate and the pixels surrounding that coordinate. No
4028% pixel area resampling, or scaling of the result is performed.
cristya085a432011-07-30 01:39:32 +00004029%
anthonycf4e33d2012-06-08 07:33:23 +00004030% Interpolation is restricted to just the specified channel.
4031%
cristya085a432011-07-30 01:39:32 +00004032% The format of the InterpolatePixelChannel method is:
4033%
4034% MagickBooleanType InterpolatePixelChannel(const Image *image,
cristy444eda62011-08-10 02:07:46 +00004035% const CacheView *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00004036% const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00004037% double *pixel,ExceptionInfo *exception)
4038%
4039% A description of each parameter follows:
4040%
4041% o image: the image.
4042%
4043% o image_view: the image view.
4044%
4045% o channel: the pixel channel to interpolate.
4046%
4047% o method: the pixel color interpolation method.
4048%
4049% o x,y: A double representing the current (x,y) position of the pixel.
4050%
4051% o pixel: return the interpolated pixel here.
4052%
4053% o exception: return any errors or warnings in this structure.
4054%
4055*/
cristy94ea1632011-07-30 20:40:25 +00004056
cristy884f6002011-07-31 00:51:45 +00004057static inline double MagickMax(const MagickRealType x,const MagickRealType y)
4058{
4059 if (x > y)
4060 return(x);
4061 return(y);
4062}
4063
nicolasd32d5e52012-06-12 15:34:10 +00004064static inline void CatromWeights(const MagickRealType x,
4065 MagickRealType (*weights)[4])
cristy884f6002011-07-31 00:51:45 +00004066{
nicolasd32d5e52012-06-12 15:34:10 +00004067 /*
4068 Nicolas Robidoux' 10 flops (4* + 5- + 1+) refactoring of the
4069 computation of the standard four 1D Catmull-Rom weights. The
4070 sampling location is assumed between the second and third input
4071 pixel locations, and x is the position relative to the second
4072 input pixel location. Formulas originally derived for the VIPS
4073 (Virtual Image Processing System) library.
4074 */
cristy884f6002011-07-31 00:51:45 +00004075 MagickRealType
4076 alpha,
nicolasd32d5e52012-06-12 15:34:10 +00004077 beta,
cristy884f6002011-07-31 00:51:45 +00004078 gamma;
4079
nicolasd32d5e52012-06-12 15:34:10 +00004080 alpha=(MagickRealType) 1.0-x;
4081 beta=(MagickRealType) (-0.5)*x*alpha;
4082 (*weights)[0]=alpha*beta;
4083 (*weights)[3]=x*beta;
4084 /*
4085 The following computation of the inner weights from the outer ones
4086 works for all Keys cubics.
4087 */
4088 gamma=(*weights)[3]-(*weights)[0];
4089 (*weights)[1]=alpha-(*weights)[0]+gamma;
4090 (*weights)[2]=x-(*weights)[3]-gamma;
4091}
4092
4093static inline void SplineWeights(const MagickRealType x,
4094 MagickRealType (*weights)[4])
4095{
4096 /*
4097 Nicolas Robidoux' 12 flops (6* + 5- + 1+) refactoring of the
4098 computation of the standard four 1D cubic B-spline smoothing
4099 weights. The sampling location is assumed between the second and
4100 third input pixel locations, and x is the position relative to the
4101 second input pixel location.
4102 */
4103 MagickRealType
4104 alpha,
4105 beta;
4106
4107 alpha=(MagickRealType) 1.0-x;
4108 (*weights)[3]=(MagickRealType) (1.0/6.0)*x*x*x;
4109 (*weights)[0]=(MagickRealType) (1.0/6.0)*alpha*alpha*alpha;
4110 beta=(*weights)[3]-(*weights)[0];
4111 (*weights)[1]=alpha-(*weights)[0]+beta;
4112 (*weights)[2]=x-(*weights)[3]-beta;
cristy884f6002011-07-31 00:51:45 +00004113}
4114
cristy94ea1632011-07-30 20:40:25 +00004115static inline double MeshInterpolate(const PointInfo *delta,const double p,
4116 const double x,const double y)
4117{
4118 return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p);
4119}
4120
anthonycf4e33d2012-06-08 07:33:23 +00004121/*
cristy884f6002011-07-31 00:51:45 +00004122static inline ssize_t NearestNeighbor(const MagickRealType x)
4123{
4124 if (x >= 0.0)
4125 return((ssize_t) (x+0.5));
4126 return((ssize_t) (x-0.5));
4127}
anthonycf4e33d2012-06-08 07:33:23 +00004128*/
cristy884f6002011-07-31 00:51:45 +00004129
cristya085a432011-07-30 01:39:32 +00004130MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
4131 const CacheView *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00004132 const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00004133 double *pixel,ExceptionInfo *exception)
4134{
4135 MagickBooleanType
4136 status;
4137
cristy94ea1632011-07-30 20:40:25 +00004138 MagickRealType
4139 alpha[16],
cristy884f6002011-07-31 00:51:45 +00004140 gamma,
4141 pixels[16];
cristy94ea1632011-07-30 20:40:25 +00004142
4143 PixelTrait
4144 traits;
4145
cristy94ea1632011-07-30 20:40:25 +00004146 register const Quantum
4147 *p;
4148
cristy50e64b82012-06-22 17:46:19 +00004149 register ssize_t
cristy94ea1632011-07-30 20:40:25 +00004150 i;
4151
cristya085a432011-07-30 01:39:32 +00004152 ssize_t
4153 x_offset,
4154 y_offset;
4155
anthonycf4e33d2012-06-08 07:33:23 +00004156 PixelInterpolateMethod
4157 interpolate;
4158
cristya085a432011-07-30 01:39:32 +00004159 assert(image != (Image *) NULL);
4160 assert(image != (Image *) NULL);
4161 assert(image->signature == MagickSignature);
4162 assert(image_view != (CacheView *) NULL);
4163 status=MagickTrue;
cristy884f6002011-07-31 00:51:45 +00004164 *pixel=0.0;
cristy94ea1632011-07-30 20:40:25 +00004165 traits=GetPixelChannelMapTraits(image,channel);
cristya085a432011-07-30 01:39:32 +00004166 x_offset=(ssize_t) floor(x);
4167 y_offset=(ssize_t) floor(y);
anthonycf4e33d2012-06-08 07:33:23 +00004168 interpolate = method;
4169 if ( interpolate == UndefinedInterpolatePixel )
4170 interpolate = image->interpolate;
4171 switch (interpolate)
cristya085a432011-07-30 01:39:32 +00004172 {
anthonycf4e33d2012-06-08 07:33:23 +00004173 case AverageInterpolatePixel: /* nearest 4 neighbours */
4174 case Average9InterpolatePixel: /* nearest 9 neighbours */
4175 case Average16InterpolatePixel: /* nearest 16 neighbours */
cristy884f6002011-07-31 00:51:45 +00004176 {
anthonycf4e33d2012-06-08 07:33:23 +00004177 size_t
4178 count=2; /* size of the area to average - default nearest 4 */
4179
4180 if (interpolate == Average9InterpolatePixel)
4181 {
4182 count=3;
4183 x_offset=(ssize_t) (floor(x+0.5)-1);
4184 y_offset=(ssize_t) (floor(y+0.5)-1);
4185 }
4186 else if (interpolate == Average16InterpolatePixel)
4187 {
4188 count=4;
4189 x_offset--;
4190 y_offset--;
4191 }
4192 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,count,count,
cristy884f6002011-07-31 00:51:45 +00004193 exception);
4194 if (p == (const Quantum *) NULL)
4195 {
4196 status=MagickFalse;
4197 break;
4198 }
anthonycf4e33d2012-06-08 07:33:23 +00004199
4200 count*=count; /* Number of pixels to Average */
cristy222b19c2011-08-04 01:35:11 +00004201 if ((traits & BlendPixelTrait) == 0)
cristy50e64b82012-06-22 17:46:19 +00004202 for (i=0; i < (ssize_t) count; i++)
cristy884f6002011-07-31 00:51:45 +00004203 {
4204 alpha[i]=1.0;
4205 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4206 }
4207 else
cristy50e64b82012-06-22 17:46:19 +00004208 for (i=0; i < (ssize_t) count; i++)
cristy884f6002011-07-31 00:51:45 +00004209 {
4210 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4211 GetPixelChannels(image));
4212 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4213 }
cristy50e64b82012-06-22 17:46:19 +00004214 for (i=0; i < (ssize_t) count; i++)
cristy884f6002011-07-31 00:51:45 +00004215 {
anthonycf4e33d2012-06-08 07:33:23 +00004216 gamma=MagickEpsilonReciprocal(alpha[i])/count;
4217 *pixel+=gamma*pixels[i];
cristy884f6002011-07-31 00:51:45 +00004218 }
4219 break;
4220 }
anthonycf4e33d2012-06-08 07:33:23 +00004221 case BilinearInterpolatePixel:
4222 default:
4223 {
4224 PointInfo
4225 delta,
4226 epsilon;
4227
4228 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4229 if (p == (const Quantum *) NULL)
4230 {
4231 status=MagickFalse;
4232 break;
4233 }
4234 if ((traits & BlendPixelTrait) == 0)
4235 for (i=0; i < 4; i++)
4236 {
4237 alpha[i]=1.0;
4238 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4239 }
4240 else
4241 for (i=0; i < 4; i++)
4242 {
4243 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4244 GetPixelChannels(image));
4245 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4246 }
4247 delta.x=x-x_offset;
4248 delta.y=y-y_offset;
4249 epsilon.x=1.0-delta.x;
4250 epsilon.y=1.0-delta.y;
4251 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4252 (epsilon.x*alpha[2]+delta.x*alpha[3])));
4253 gamma=MagickEpsilonReciprocal(gamma);
4254 *pixel=gamma*(epsilon.y*(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*
4255 (epsilon.x*pixels[2]+delta.x*pixels[3]));
4256 break;
4257 }
4258 case CatromInterpolatePixel:
cristy884f6002011-07-31 00:51:45 +00004259 {
4260 MagickRealType
cristy380a11c2012-06-02 15:15:22 +00004261 cx[4],
nicolas6676f5a2012-06-12 16:01:15 +00004262 cy[4];
cristy884f6002011-07-31 00:51:45 +00004263
cristy884f6002011-07-31 00:51:45 +00004264 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4265 exception);
4266 if (p == (const Quantum *) NULL)
4267 {
4268 status=MagickFalse;
4269 break;
4270 }
cristy222b19c2011-08-04 01:35:11 +00004271 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004272 for (i=0; i < 16; i++)
4273 {
4274 alpha[i]=1.0;
4275 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4276 }
4277 else
4278 for (i=0; i < 16; i++)
4279 {
4280 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4281 GetPixelChannels(image));
4282 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4283 }
nicolasd32d5e52012-06-12 15:34:10 +00004284 CatromWeights((MagickRealType) (x-x_offset),&cx);
4285 CatromWeights((MagickRealType) (y-y_offset),&cy);
4286 gamma=(channel == AlphaPixelChannel ? (MagickRealType) 1.0 :
4287 MagickEpsilonReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
4288 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4289 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4290 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4291 cx[2]*alpha[14]+cx[3]*alpha[15])));
cristy380a11c2012-06-02 15:15:22 +00004292 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
nicolasd32d5e52012-06-12 15:34:10 +00004293 cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*
4294 pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+
4295 cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*
4296 pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15]));
cristy884f6002011-07-31 00:51:45 +00004297 break;
4298 }
anthonycf4e33d2012-06-08 07:33:23 +00004299#if 0
nicolas20075dc2012-06-12 20:47:38 +00004300 /* deprecated useless and very slow interpolator */
cristy884f6002011-07-31 00:51:45 +00004301 case FilterInterpolatePixel:
4302 {
4303 CacheView
4304 *filter_view;
4305
4306 Image
4307 *excerpt_image,
4308 *filter_image;
4309
4310 RectangleInfo
4311 geometry;
4312
4313 geometry.width=4L;
4314 geometry.height=4L;
4315 geometry.x=x_offset-1;
4316 geometry.y=y_offset-1;
4317 excerpt_image=ExcerptImage(image,&geometry,exception);
4318 if (excerpt_image == (Image *) NULL)
4319 {
4320 status=MagickFalse;
4321 break;
4322 }
cristyaa2c16c2012-03-25 22:21:35 +00004323 filter_image=ResizeImage(excerpt_image,1,1,image->filter,exception);
cristy884f6002011-07-31 00:51:45 +00004324 excerpt_image=DestroyImage(excerpt_image);
4325 if (filter_image == (Image *) NULL)
4326 break;
cristydb070952012-04-20 14:33:00 +00004327 filter_view=AcquireVirtualCacheView(filter_image,exception);
cristy884f6002011-07-31 00:51:45 +00004328 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4329 if (p == (const Quantum *) NULL)
4330 status=MagickFalse;
4331 else
cristy0beccfa2011-09-25 20:47:53 +00004332 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004333 filter_view=DestroyCacheView(filter_view);
4334 filter_image=DestroyImage(filter_image);
4335 break;
4336 }
anthonycf4e33d2012-06-08 07:33:23 +00004337#endif
cristy884f6002011-07-31 00:51:45 +00004338 case IntegerInterpolatePixel:
4339 {
4340 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
4341 if (p == (const Quantum *) NULL)
4342 {
4343 status=MagickFalse;
4344 break;
4345 }
cristy0beccfa2011-09-25 20:47:53 +00004346 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004347 break;
4348 }
anthonycf4e33d2012-06-08 07:33:23 +00004349 case NearestInterpolatePixel:
cristy884f6002011-07-31 00:51:45 +00004350 {
anthonycf4e33d2012-06-08 07:33:23 +00004351 x_offset=(ssize_t) floor(x+0.5);
4352 y_offset=(ssize_t) floor(y+0.5);
4353 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
cristy884f6002011-07-31 00:51:45 +00004354 if (p == (const Quantum *) NULL)
4355 {
4356 status=MagickFalse;
4357 break;
4358 }
cristy0beccfa2011-09-25 20:47:53 +00004359 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004360 break;
4361 }
4362 case MeshInterpolatePixel:
4363 {
4364 PointInfo
4365 delta,
cristy94ea1632011-07-30 20:40:25 +00004366 luminance;
4367
4368 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4369 if (p == (const Quantum *) NULL)
4370 {
4371 status=MagickFalse;
4372 break;
4373 }
cristy222b19c2011-08-04 01:35:11 +00004374 if ((traits & BlendPixelTrait) == 0)
cristy94ea1632011-07-30 20:40:25 +00004375 for (i=0; i < 4; i++)
4376 {
4377 alpha[i]=1.0;
cristy884f6002011-07-31 00:51:45 +00004378 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
cristy94ea1632011-07-30 20:40:25 +00004379 }
4380 else
4381 for (i=0; i < 4; i++)
4382 {
4383 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4384 GetPixelChannels(image));
4385 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4386 }
cristy884f6002011-07-31 00:51:45 +00004387 delta.x=x-x_offset;
4388 delta.y=y-y_offset;
4389 luminance.x=GetPixelLuminance(image,p)-(double)
4390 GetPixelLuminance(image,p+3*GetPixelChannels(image));
cristy28474bf2011-09-11 23:32:52 +00004391 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
cristy884f6002011-07-31 00:51:45 +00004392 GetPixelLuminance(image,p+2*GetPixelChannels(image));
cristy94ea1632011-07-30 20:40:25 +00004393 if (fabs(luminance.x) < fabs(luminance.y))
4394 {
4395 /*
4396 Diagonal 0-3 NW-SE.
4397 */
4398 if (delta.x <= delta.y)
4399 {
4400 /*
4401 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4402 */
4403 delta.y=1.0-delta.y;
4404 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
cristyc58380a2012-06-03 15:12:30 +00004405 gamma=MagickEpsilonReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004406 *pixel=gamma*MeshInterpolate(&delta,pixels[2],pixels[3],
4407 pixels[0]);
4408 }
4409 else
4410 {
4411 /*
4412 Top-right triangle (pixel: 1, diagonal: 0-3).
4413 */
4414 delta.x=1.0-delta.x;
4415 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
cristyc58380a2012-06-03 15:12:30 +00004416 gamma=MagickEpsilonReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004417 *pixel=gamma*MeshInterpolate(&delta,pixels[1],pixels[0],
4418 pixels[3]);
4419 }
4420 }
4421 else
4422 {
4423 /*
4424 Diagonal 1-2 NE-SW.
4425 */
4426 if (delta.x <= (1.0-delta.y))
4427 {
4428 /*
4429 Top-left triangle (pixel: 0, diagonal: 1-2).
4430 */
4431 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
cristyc58380a2012-06-03 15:12:30 +00004432 gamma=MagickEpsilonReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004433 *pixel=gamma*MeshInterpolate(&delta,pixels[0],pixels[1],
4434 pixels[2]);
4435 }
4436 else
4437 {
4438 /*
4439 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4440 */
4441 delta.x=1.0-delta.x;
4442 delta.y=1.0-delta.y;
4443 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
cristyc58380a2012-06-03 15:12:30 +00004444 gamma=MagickEpsilonReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004445 *pixel=gamma*MeshInterpolate(&delta,pixels[3],pixels[2],
4446 pixels[1]);
4447 }
4448 }
cristya085a432011-07-30 01:39:32 +00004449 break;
4450 }
cristy884f6002011-07-31 00:51:45 +00004451 case SplineInterpolatePixel:
4452 {
4453 MagickRealType
nicolasd32d5e52012-06-12 15:34:10 +00004454 cx[4],
nicolas6676f5a2012-06-12 16:01:15 +00004455 cy[4];
cristy884f6002011-07-31 00:51:45 +00004456
4457 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4458 exception);
4459 if (p == (const Quantum *) NULL)
4460 {
4461 status=MagickFalse;
4462 break;
4463 }
cristy222b19c2011-08-04 01:35:11 +00004464 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004465 for (i=0; i < 16; i++)
4466 {
4467 alpha[i]=1.0;
4468 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4469 }
4470 else
4471 for (i=0; i < 16; i++)
4472 {
4473 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4474 GetPixelChannels(image));
4475 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4476 }
nicolasd32d5e52012-06-12 15:34:10 +00004477 SplineWeights((MagickRealType) (x-x_offset),&cx);
4478 SplineWeights((MagickRealType) (y-y_offset),&cy);
4479 gamma=(channel == AlphaPixelChannel ? (MagickRealType) 1.0 :
4480 MagickEpsilonReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
4481 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4482 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4483 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4484 cx[2]*alpha[14]+cx[3]*alpha[15])));
4485 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
4486 cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*
4487 pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+
4488 cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*
4489 pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15]));
cristy884f6002011-07-31 00:51:45 +00004490 break;
4491 }
cristya085a432011-07-30 01:39:32 +00004492 }
4493 return(status);
4494}
4495
4496/*
4497%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4498% %
4499% %
4500% %
cristy5c4e2582011-09-11 19:21:03 +00004501% I n t e r p o l a t e P i x e l C h a n n e l s %
4502% %
4503% %
4504% %
4505%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4506%
4507% InterpolatePixelChannels() applies a pixel interpolation method between a
4508% floating point coordinate and the pixels surrounding that coordinate. No
4509% pixel area resampling, or scaling of the result is performed.
4510%
anthonycf4e33d2012-06-08 07:33:23 +00004511% Interpolation is restricted to just the current channel setting of the
4512% destination image into which the color is to be stored
4513%
cristy5c4e2582011-09-11 19:21:03 +00004514% The format of the InterpolatePixelChannels method is:
4515%
4516% MagickBooleanType InterpolatePixelChannels(const Image *source,
4517% const CacheView *source_view,const Image *destination,
4518% const PixelInterpolateMethod method,const double x,const double y,
4519% Quantum *pixel,ExceptionInfo *exception)
4520%
4521% A description of each parameter follows:
4522%
4523% o source: the source.
4524%
4525% o source_view: the source view.
4526%
anthonycf4e33d2012-06-08 07:33:23 +00004527% o destination: the destination image, for the interpolated color
cristy5c4e2582011-09-11 19:21:03 +00004528%
4529% o method: the pixel color interpolation method.
4530%
4531% o x,y: A double representing the current (x,y) position of the pixel.
4532%
4533% o pixel: return the interpolated pixel here.
4534%
4535% o exception: return any errors or warnings in this structure.
4536%
4537*/
4538MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
4539 const CacheView *source_view,const Image *destination,
4540 const PixelInterpolateMethod method,const double x,const double y,
4541 Quantum *pixel,ExceptionInfo *exception)
4542{
4543 MagickBooleanType
4544 status;
4545
4546 MagickRealType
4547 alpha[16],
4548 gamma,
4549 pixels[16];
4550
4551 PixelChannel
4552 channel;
4553
4554 PixelTrait
4555 destination_traits,
4556 traits;
4557
4558 register const Quantum
4559 *p;
4560
cristy50e64b82012-06-22 17:46:19 +00004561 register ssize_t
cristy5c4e2582011-09-11 19:21:03 +00004562 i;
4563
4564 ssize_t
4565 x_offset,
4566 y_offset;
4567
anthonycf4e33d2012-06-08 07:33:23 +00004568 PixelInterpolateMethod
4569 interpolate;
4570
cristy5c4e2582011-09-11 19:21:03 +00004571 assert(source != (Image *) NULL);
4572 assert(source != (Image *) NULL);
4573 assert(source->signature == MagickSignature);
4574 assert(source_view != (CacheView *) NULL);
4575 status=MagickTrue;
4576 x_offset=(ssize_t) floor(x);
4577 y_offset=(ssize_t) floor(y);
anthonycf4e33d2012-06-08 07:33:23 +00004578 interpolate = method;
4579 if ( interpolate == UndefinedInterpolatePixel )
4580 interpolate = source->interpolate;
4581 switch (interpolate)
cristy5c4e2582011-09-11 19:21:03 +00004582 {
anthonycf4e33d2012-06-08 07:33:23 +00004583 case AverageInterpolatePixel: /* nearest 4 neighbours */
4584 case Average9InterpolatePixel: /* nearest 9 neighbours */
4585 case Average16InterpolatePixel: /* nearest 16 neighbours */
cristy5c4e2582011-09-11 19:21:03 +00004586 {
anthonycf4e33d2012-06-08 07:33:23 +00004587 size_t
4588 count=2; /* size of the area to average - default nearest 4 */
4589
4590 if (interpolate == Average9InterpolatePixel)
4591 {
4592 count=3;
4593 x_offset=(ssize_t) (floor(x+0.5)-1);
4594 y_offset=(ssize_t) (floor(y+0.5)-1);
4595 }
4596 else if (interpolate == Average16InterpolatePixel)
4597 {
4598 count=4;
4599 x_offset--;
4600 y_offset--;
4601 }
4602 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,count,count,
cristy5c4e2582011-09-11 19:21:03 +00004603 exception);
4604 if (p == (const Quantum *) NULL)
4605 {
4606 status=MagickFalse;
4607 break;
4608 }
anthonycf4e33d2012-06-08 07:33:23 +00004609 count*=count; /* Number of pixels to Average */
cristy50e64b82012-06-22 17:46:19 +00004610 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004611 {
4612 double
4613 sum;
4614
cristy50e64b82012-06-22 17:46:19 +00004615 register ssize_t
cristy5c4e2582011-09-11 19:21:03 +00004616 j;
4617
cristye2a912b2011-12-05 20:02:07 +00004618 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004619 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004620 destination_traits=GetPixelChannelMapTraits(destination,channel);
4621 if ((traits == UndefinedPixelTrait) ||
4622 (destination_traits == UndefinedPixelTrait))
4623 continue;
cristy50e64b82012-06-22 17:46:19 +00004624 for (j=0; j < (ssize_t) count; j++)
cristy5c4e2582011-09-11 19:21:03 +00004625 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
cristy4a7ae692011-12-14 12:24:11 +00004626 sum=0.0;
cristy5c4e2582011-09-11 19:21:03 +00004627 if ((traits & BlendPixelTrait) == 0)
4628 {
cristy50e64b82012-06-22 17:46:19 +00004629 for (j=0; j < (ssize_t) count; j++)
anthonycf4e33d2012-06-08 07:33:23 +00004630 sum+=pixels[j];
4631 sum/=count;
cristy4a7ae692011-12-14 12:24:11 +00004632 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004633 continue;
4634 }
cristy50e64b82012-06-22 17:46:19 +00004635 for (j=0; j < (ssize_t) count; j++)
cristy5c4e2582011-09-11 19:21:03 +00004636 {
4637 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4638 GetPixelChannels(source));
4639 pixels[j]*=alpha[j];
cristyc58380a2012-06-03 15:12:30 +00004640 gamma=MagickEpsilonReciprocal(alpha[j]);
anthonycf4e33d2012-06-08 07:33:23 +00004641 sum+=gamma*pixels[j];
cristy5c4e2582011-09-11 19:21:03 +00004642 }
anthonycf4e33d2012-06-08 07:33:23 +00004643 sum/=count;
cristy4a7ae692011-12-14 12:24:11 +00004644 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004645 }
4646 break;
4647 }
anthonycf4e33d2012-06-08 07:33:23 +00004648 case BilinearInterpolatePixel:
4649 default:
4650 {
4651 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4652 if (p == (const Quantum *) NULL)
4653 {
4654 status=MagickFalse;
4655 break;
4656 }
cristy50e64b82012-06-22 17:46:19 +00004657 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
anthonycf4e33d2012-06-08 07:33:23 +00004658 {
4659 PointInfo
4660 delta,
4661 epsilon;
4662
4663 channel=GetPixelChannelMapChannel(source,i);
4664 traits=GetPixelChannelMapTraits(source,channel);
4665 destination_traits=GetPixelChannelMapTraits(destination,channel);
4666 if ((traits == UndefinedPixelTrait) ||
4667 (destination_traits == UndefinedPixelTrait))
4668 continue;
4669 delta.x=x-x_offset;
4670 delta.y=y-y_offset;
4671 epsilon.x=1.0-delta.x;
4672 epsilon.y=1.0-delta.y;
4673 pixels[0]=(MagickRealType) p[i];
4674 pixels[1]=(MagickRealType) p[GetPixelChannels(source)+i];
4675 pixels[2]=(MagickRealType) p[2*GetPixelChannels(source)+i];
4676 pixels[3]=(MagickRealType) p[3*GetPixelChannels(source)+i];
4677 if ((traits & BlendPixelTrait) == 0)
4678 {
4679 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
4680 gamma=MagickEpsilonReciprocal(gamma);
4681 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
4682 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*
4683 pixels[2]+delta.x*pixels[3]))),pixel);
4684 continue;
4685 }
4686 alpha[0]=QuantumScale*GetPixelAlpha(source,p);
4687 alpha[1]=QuantumScale*GetPixelAlpha(source,p+GetPixelChannels(source));
4688 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
4689 GetPixelChannels(source));
4690 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
4691 GetPixelChannels(source));
4692 pixels[0]*=alpha[0];
4693 pixels[1]*=alpha[1];
4694 pixels[2]*=alpha[2];
4695 pixels[3]*=alpha[3];
4696 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4697 (epsilon.x*alpha[2]+delta.x*alpha[3])));
4698 gamma=MagickEpsilonReciprocal(gamma);
4699 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
4700 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*pixels[2]+
4701 delta.x*pixels[3]))),pixel);
4702 }
4703 break;
4704 }
4705 case CatromInterpolatePixel:
cristy5c4e2582011-09-11 19:21:03 +00004706 {
4707 MagickRealType
cristy380a11c2012-06-02 15:15:22 +00004708 cx[4],
4709 cy[4];
cristy5c4e2582011-09-11 19:21:03 +00004710
cristy5c4e2582011-09-11 19:21:03 +00004711 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4712 exception);
4713 if (p == (const Quantum *) NULL)
4714 {
4715 status=MagickFalse;
4716 break;
4717 }
cristy50e64b82012-06-22 17:46:19 +00004718 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004719 {
4720 register ssize_t
4721 j;
4722
cristye2a912b2011-12-05 20:02:07 +00004723 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004724 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004725 destination_traits=GetPixelChannelMapTraits(destination,channel);
4726 if ((traits == UndefinedPixelTrait) ||
4727 (destination_traits == UndefinedPixelTrait))
4728 continue;
4729 if ((traits & BlendPixelTrait) == 0)
4730 for (j=0; j < 16; j++)
4731 {
4732 alpha[j]=1.0;
4733 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
4734 }
4735 else
4736 for (j=0; j < 16; j++)
4737 {
4738 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4739 GetPixelChannels(source));
4740 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
4741 }
nicolasd32d5e52012-06-12 15:34:10 +00004742 CatromWeights((MagickRealType) (x-x_offset),&cx);
4743 CatromWeights((MagickRealType) (y-y_offset),&cy);
4744 gamma=((traits & BlendPixelTrait) ? (MagickRealType) (1.0) :
4745 MagickEpsilonReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
4746 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4747 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4748 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4749 cx[2]*alpha[14]+cx[3]*alpha[15])));
cristy380a11c2012-06-02 15:15:22 +00004750 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]*
4751 pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]*
4752 (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+
4753 cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*
nicolasd32d5e52012-06-12 15:34:10 +00004754 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*
4755 pixels[14]+cx[3]*pixels[15]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004756 }
4757 break;
4758 }
anthonycf4e33d2012-06-08 07:33:23 +00004759#if 0
nicolas20075dc2012-06-12 20:47:38 +00004760 /* deprecated useless and very slow interpolator */
cristy5c4e2582011-09-11 19:21:03 +00004761 case FilterInterpolatePixel:
4762 {
cristy50e64b82012-06-22 17:46:19 +00004763 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004764 {
4765 CacheView
4766 *filter_view;
4767
4768 Image
4769 *excerpt_source,
4770 *filter_source;
4771
4772 RectangleInfo
4773 geometry;
4774
cristye2a912b2011-12-05 20:02:07 +00004775 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004776 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004777 destination_traits=GetPixelChannelMapTraits(destination,channel);
4778 if ((traits == UndefinedPixelTrait) ||
4779 (destination_traits == UndefinedPixelTrait))
4780 continue;
4781 geometry.width=4L;
4782 geometry.height=4L;
4783 geometry.x=x_offset-1;
4784 geometry.y=y_offset-1;
4785 excerpt_source=ExcerptImage(source,&geometry,exception);
4786 if (excerpt_source == (Image *) NULL)
4787 {
4788 status=MagickFalse;
4789 continue;
4790 }
cristyaa2c16c2012-03-25 22:21:35 +00004791 filter_source=ResizeImage(excerpt_source,1,1,source->filter,exception);
cristy5c4e2582011-09-11 19:21:03 +00004792 excerpt_source=DestroyImage(excerpt_source);
4793 if (filter_source == (Image *) NULL)
4794 continue;
cristydb070952012-04-20 14:33:00 +00004795 filter_view=AcquireVirtualCacheView(filter_source,exception);
cristy5c4e2582011-09-11 19:21:03 +00004796 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4797 if (p == (const Quantum *) NULL)
4798 status=MagickFalse;
4799 else
cristy1861c902011-12-14 02:30:00 +00004800 {
cristy4a7ae692011-12-14 12:24:11 +00004801 SetPixelChannel(destination,channel,p[i],pixel);
cristy1861c902011-12-14 02:30:00 +00004802 }
cristy5c4e2582011-09-11 19:21:03 +00004803 filter_view=DestroyCacheView(filter_view);
4804 filter_source=DestroyImage(filter_source);
4805 }
4806 break;
4807 }
anthonycf4e33d2012-06-08 07:33:23 +00004808#endif
cristy5c4e2582011-09-11 19:21:03 +00004809 case IntegerInterpolatePixel:
4810 {
4811 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
4812 if (p == (const Quantum *) NULL)
4813 {
4814 status=MagickFalse;
4815 break;
4816 }
cristy50e64b82012-06-22 17:46:19 +00004817 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004818 {
cristye2a912b2011-12-05 20:02:07 +00004819 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004820 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004821 destination_traits=GetPixelChannelMapTraits(destination,channel);
4822 if ((traits == UndefinedPixelTrait) ||
4823 (destination_traits == UndefinedPixelTrait))
4824 continue;
cristy4a7ae692011-12-14 12:24:11 +00004825 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004826 }
4827 break;
4828 }
anthonycf4e33d2012-06-08 07:33:23 +00004829 case NearestInterpolatePixel:
cristy5c4e2582011-09-11 19:21:03 +00004830 {
anthonycf4e33d2012-06-08 07:33:23 +00004831 x_offset=(ssize_t) floor(x+0.5);
4832 y_offset=(ssize_t) floor(y+0.5);
4833 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
cristy5c4e2582011-09-11 19:21:03 +00004834 if (p == (const Quantum *) NULL)
4835 {
4836 status=MagickFalse;
4837 break;
4838 }
cristy50e64b82012-06-22 17:46:19 +00004839 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004840 {
cristye2a912b2011-12-05 20:02:07 +00004841 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004842 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004843 destination_traits=GetPixelChannelMapTraits(destination,channel);
4844 if ((traits == UndefinedPixelTrait) ||
4845 (destination_traits == UndefinedPixelTrait))
4846 continue;
cristy4a7ae692011-12-14 12:24:11 +00004847 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004848 }
4849 break;
4850 }
4851 case MeshInterpolatePixel:
4852 {
4853 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4854 if (p == (const Quantum *) NULL)
4855 {
4856 status=MagickFalse;
4857 break;
4858 }
cristy50e64b82012-06-22 17:46:19 +00004859 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004860 {
4861 PointInfo
4862 delta,
4863 luminance;
4864
cristye2a912b2011-12-05 20:02:07 +00004865 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004866 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004867 destination_traits=GetPixelChannelMapTraits(destination,channel);
4868 if ((traits == UndefinedPixelTrait) ||
4869 (destination_traits == UndefinedPixelTrait))
4870 continue;
cristy1861c902011-12-14 02:30:00 +00004871 pixels[0]=(MagickRealType) p[i];
4872 pixels[1]=(MagickRealType) p[GetPixelChannels(source)+i];
4873 pixels[2]=(MagickRealType) p[2*GetPixelChannels(source)+i];
4874 pixels[3]=(MagickRealType) p[3*GetPixelChannels(source)+i];
4875 if ((traits & BlendPixelTrait) == 0)
4876 {
4877 alpha[0]=1.0;
4878 alpha[1]=1.0;
4879 alpha[2]=1.0;
4880 alpha[3]=1.0;
4881 }
4882 else
4883 {
4884 alpha[0]=QuantumScale*GetPixelAlpha(source,p);
4885 alpha[1]=QuantumScale*GetPixelAlpha(source,p+
4886 GetPixelChannels(source));
4887 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
4888 GetPixelChannels(source));
4889 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
4890 GetPixelChannels(source));
4891 }
4892 delta.x=x-x_offset;
4893 delta.y=y-y_offset;
anthonycf4e33d2012-06-08 07:33:23 +00004894 luminance.x=fabs((double)(
4895 GetPixelLuminance(source,p)
4896 -GetPixelLuminance(source,p+3*GetPixelChannels(source))));
4897 luminance.y=fabs((double)(
4898 GetPixelLuminance(source,p+GetPixelChannels(source))
4899 -GetPixelLuminance(source,p+2*GetPixelChannels(source))));
4900 if (luminance.x < luminance.y)
cristy1861c902011-12-14 02:30:00 +00004901 {
4902 /*
4903 Diagonal 0-3 NW-SE.
4904 */
4905 if (delta.x <= delta.y)
4906 {
4907 /*
4908 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4909 */
4910 delta.y=1.0-delta.y;
4911 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
cristyc58380a2012-06-03 15:12:30 +00004912 gamma=MagickEpsilonReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00004913 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4914 MeshInterpolate(&delta,pixels[2],pixels[3],pixels[0])),pixel);
cristy1861c902011-12-14 02:30:00 +00004915 }
4916 else
4917 {
4918 /*
4919 Top-right triangle (pixel: 1, diagonal: 0-3).
4920 */
4921 delta.x=1.0-delta.x;
4922 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
cristyc58380a2012-06-03 15:12:30 +00004923 gamma=MagickEpsilonReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00004924 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4925 MeshInterpolate(&delta,pixels[1],pixels[0],pixels[3])),pixel);
cristy1861c902011-12-14 02:30:00 +00004926 }
4927 }
4928 else
4929 {
4930 /*
4931 Diagonal 1-2 NE-SW.
4932 */
4933 if (delta.x <= (1.0-delta.y))
4934 {
4935 /*
4936 Top-left triangle (pixel: 0, diagonal: 1-2).
4937 */
4938 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
cristyc58380a2012-06-03 15:12:30 +00004939 gamma=MagickEpsilonReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00004940 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4941 MeshInterpolate(&delta,pixels[0],pixels[1],pixels[2])),pixel);
cristy1861c902011-12-14 02:30:00 +00004942 }
4943 else
4944 {
4945 /*
4946 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4947 */
4948 delta.x=1.0-delta.x;
4949 delta.y=1.0-delta.y;
4950 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
cristyc58380a2012-06-03 15:12:30 +00004951 gamma=MagickEpsilonReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00004952 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4953 MeshInterpolate(&delta,pixels[3],pixels[2],pixels[1])),pixel);
cristy1861c902011-12-14 02:30:00 +00004954 }
4955 }
cristy5c4e2582011-09-11 19:21:03 +00004956 }
4957 break;
4958 }
4959 case SplineInterpolatePixel:
4960 {
nicolasd32d5e52012-06-12 15:34:10 +00004961 MagickRealType
4962 cx[4],
4963 cy[4];
4964
cristy5c4e2582011-09-11 19:21:03 +00004965 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4966 exception);
4967 if (p == (const Quantum *) NULL)
4968 {
4969 status=MagickFalse;
4970 break;
4971 }
cristy50e64b82012-06-22 17:46:19 +00004972 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004973 {
cristy5c4e2582011-09-11 19:21:03 +00004974 register ssize_t
4975 j;
4976
cristye2a912b2011-12-05 20:02:07 +00004977 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004978 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004979 destination_traits=GetPixelChannelMapTraits(destination,channel);
4980 if ((traits == UndefinedPixelTrait) ||
4981 (destination_traits == UndefinedPixelTrait))
4982 continue;
4983 if ((traits & BlendPixelTrait) == 0)
4984 for (j=0; j < 16; j++)
4985 {
4986 alpha[j]=1.0;
4987 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
4988 }
4989 else
4990 for (j=0; j < 16; j++)
4991 {
4992 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4993 GetPixelChannels(source));
4994 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
4995 }
nicolasd32d5e52012-06-12 15:34:10 +00004996 SplineWeights((MagickRealType) (x-x_offset),&cx);
4997 SplineWeights((MagickRealType) (y-y_offset),&cy);
4998 gamma=((traits & BlendPixelTrait) ? (MagickRealType) (1.0) :
4999 MagickEpsilonReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
5000 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
5001 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
5002 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
5003 cx[2]*alpha[14]+cx[3]*alpha[15])));
5004 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]*
5005 pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]*
5006 (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+
5007 cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*
5008 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*
5009 pixels[14]+cx[3]*pixels[15]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00005010 }
5011 break;
5012 }
5013 }
5014 return(status);
5015}
5016
5017/*
5018%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5019% %
5020% %
5021% %
cristy9075cdb2011-07-30 01:06:23 +00005022% 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 +00005023% %
5024% %
5025% %
5026%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5027%
cristy884f6002011-07-31 00:51:45 +00005028% InterpolatePixelInfo() applies a pixel interpolation method between a
5029% floating point coordinate and the pixels surrounding that coordinate. No
5030% pixel area resampling, or scaling of the result is performed.
cristy4c08aed2011-07-01 19:47:50 +00005031%
anthonycf4e33d2012-06-08 07:33:23 +00005032% Interpolation is restricted to just RGBKA channels.
5033%
cristy4c08aed2011-07-01 19:47:50 +00005034% The format of the InterpolatePixelInfo method is:
5035%
5036% MagickBooleanType InterpolatePixelInfo(const Image *image,
cristy5c4e2582011-09-11 19:21:03 +00005037% const CacheView *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00005038% const double x,const double y,PixelInfo *pixel,
5039% ExceptionInfo *exception)
5040%
5041% A description of each parameter follows:
5042%
5043% o image: the image.
5044%
5045% o image_view: the image view.
5046%
5047% o method: the pixel color interpolation method.
5048%
5049% o x,y: A double representing the current (x,y) position of the pixel.
5050%
5051% o pixel: return the interpolated pixel here.
5052%
5053% o exception: return any errors or warnings in this structure.
5054%
5055*/
5056
5057static inline void AlphaBlendPixelInfo(const Image *image,
5058 const Quantum *pixel,PixelInfo *pixel_info,MagickRealType *alpha)
5059{
5060 if (image->matte == MagickFalse)
5061 {
5062 *alpha=1.0;
5063 pixel_info->red=(MagickRealType) GetPixelRed(image,pixel);
5064 pixel_info->green=(MagickRealType) GetPixelGreen(image,pixel);
5065 pixel_info->blue=(MagickRealType) GetPixelBlue(image,pixel);
5066 pixel_info->black=0.0;
5067 if (image->colorspace == CMYKColorspace)
5068 pixel_info->black=(MagickRealType) GetPixelBlack(image,pixel);
5069 pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
5070 return;
5071 }
5072 *alpha=QuantumScale*GetPixelAlpha(image,pixel);
5073 pixel_info->red=(*alpha*GetPixelRed(image,pixel));
5074 pixel_info->green=(*alpha*GetPixelGreen(image,pixel));
5075 pixel_info->blue=(*alpha*GetPixelBlue(image,pixel));
5076 pixel_info->black=0.0;
5077 if (image->colorspace == CMYKColorspace)
5078 pixel_info->black=(*alpha*GetPixelBlack(image,pixel));
5079 pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
5080}
5081
cristy4c08aed2011-07-01 19:47:50 +00005082MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
cristy5c4e2582011-09-11 19:21:03 +00005083 const CacheView *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00005084 const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception)
5085{
5086 MagickBooleanType
5087 status;
5088
cristy4c08aed2011-07-01 19:47:50 +00005089 MagickRealType
5090 alpha[16],
5091 gamma;
5092
cristy865d58d2011-07-09 00:44:52 +00005093 PixelInfo
5094 pixels[16];
5095
cristy4c08aed2011-07-01 19:47:50 +00005096 register const Quantum
5097 *p;
5098
cristy50e64b82012-06-22 17:46:19 +00005099 register ssize_t
cristy4c08aed2011-07-01 19:47:50 +00005100 i;
5101
5102 ssize_t
5103 x_offset,
5104 y_offset;
5105
anthonycf4e33d2012-06-08 07:33:23 +00005106 PixelInterpolateMethod
5107 interpolate;
5108
cristy4c08aed2011-07-01 19:47:50 +00005109 assert(image != (Image *) NULL);
5110 assert(image->signature == MagickSignature);
5111 assert(image_view != (CacheView *) NULL);
5112 status=MagickTrue;
5113 x_offset=(ssize_t) floor(x);
5114 y_offset=(ssize_t) floor(y);
anthonycf4e33d2012-06-08 07:33:23 +00005115 interpolate = method;
5116 if ( interpolate == UndefinedInterpolatePixel )
5117 interpolate = image->interpolate;
5118 switch (interpolate)
cristy4c08aed2011-07-01 19:47:50 +00005119 {
anthonycf4e33d2012-06-08 07:33:23 +00005120 case AverageInterpolatePixel: /* nearest 4 neighbours */
5121 case Average9InterpolatePixel: /* nearest 9 neighbours */
5122 case Average16InterpolatePixel: /* nearest 16 neighbours */
cristy4c08aed2011-07-01 19:47:50 +00005123 {
anthonycf4e33d2012-06-08 07:33:23 +00005124 size_t
5125 count=2; /* size of the area to average - default nearest 4 */
5126
5127 if (interpolate == Average9InterpolatePixel)
5128 {
5129 count=3;
5130 x_offset=(ssize_t) (floor(x+0.5)-1);
5131 y_offset=(ssize_t) (floor(y+0.5)-1);
5132 }
5133 else if (interpolate == Average16InterpolatePixel)
5134 {
5135 count=4;
5136 x_offset--;
5137 y_offset--;
5138 }
5139 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,count,count,
cristy4c08aed2011-07-01 19:47:50 +00005140 exception);
5141 if (p == (const Quantum *) NULL)
5142 {
5143 status=MagickFalse;
5144 break;
5145 }
cristy4c08aed2011-07-01 19:47:50 +00005146 pixel->red=0.0;
5147 pixel->green=0.0;
5148 pixel->blue=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005149 pixel->black=0.0;
cristy865d58d2011-07-09 00:44:52 +00005150 pixel->alpha=0.0;
anthonycf4e33d2012-06-08 07:33:23 +00005151 count*=count; /* number of pixels - square of size */
cristy50e64b82012-06-22 17:46:19 +00005152 for (i=0; i < (ssize_t) count; i++)
cristy4c08aed2011-07-01 19:47:50 +00005153 {
anthonycf4e33d2012-06-08 07:33:23 +00005154 AlphaBlendPixelInfo(image,p,pixels,alpha);
5155 gamma=MagickEpsilonReciprocal(alpha[0]);
5156 pixel->red += gamma*pixels[0].red;
5157 pixel->green += gamma*pixels[0].green;
5158 pixel->blue += gamma*pixels[0].blue;
5159 pixel->black += gamma*pixels[0].black;
5160 pixel->alpha += pixels[0].alpha;
5161 p += GetPixelChannels(image);
cristy4c08aed2011-07-01 19:47:50 +00005162 }
anthonycf4e33d2012-06-08 07:33:23 +00005163 gamma=1.0/count; /* average weighting of each pixel in area */
5164 pixel->red *= gamma;
5165 pixel->green *= gamma;
5166 pixel->blue *= gamma;
5167 pixel->black *= gamma;
5168 pixel->alpha *= gamma;
cristy4c08aed2011-07-01 19:47:50 +00005169 break;
5170 }
anthonycf4e33d2012-06-08 07:33:23 +00005171 case BackgroundInterpolatePixel:
5172 {
5173 *pixel = image->background_color; /* Copy PixelInfo Structure */
5174 break;
5175 }
5176 case BilinearInterpolatePixel:
5177 default:
5178 {
5179 PointInfo
5180 delta,
5181 epsilon;
5182
5183 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5184 if (p == (const Quantum *) NULL)
5185 {
5186 status=MagickFalse;
5187 break;
5188 }
5189 for (i=0; i < 4L; i++)
5190 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
5191 delta.x=x-x_offset;
5192 delta.y=y-y_offset;
5193 epsilon.x=1.0-delta.x;
5194 epsilon.y=1.0-delta.y;
5195 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
5196 (epsilon.x*alpha[2]+delta.x*alpha[3])));
5197 gamma=MagickEpsilonReciprocal(gamma);
5198 pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x*
5199 pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red));
5200 pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x*
5201 pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x*
5202 pixels[3].green));
5203 pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x*
5204 pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x*
5205 pixels[3].blue));
5206 if (image->colorspace == CMYKColorspace)
5207 pixel->black=gamma*(epsilon.y*(epsilon.x*pixels[0].black+delta.x*
5208 pixels[1].black)+delta.y*(epsilon.x*pixels[2].black+delta.x*
5209 pixels[3].black));
5210 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
5211 gamma=MagickEpsilonReciprocal(gamma);
5212 pixel->alpha=(epsilon.y*(epsilon.x*pixels[0].alpha+delta.x*
5213 pixels[1].alpha)+delta.y*(epsilon.x*pixels[2].alpha+delta.x*
5214 pixels[3].alpha));
5215 break;
5216 }
5217 case BlendInterpolatePixel:
5218 {
5219 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5220 if (p == (const Quantum *) NULL)
5221 {
5222 status=MagickFalse;
5223 break;
5224 }
5225 for (i=0; i < 4L; i++)
5226 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
5227 gamma=1.0; /* number of pixels blended together */
5228 for (i=0; i <= 1L; i++) {
5229 if ( y-y_offset >= 0.75 ) {
5230 alpha[i] = alpha[i+2];
5231 pixels[i] = pixels[i+2];
5232 }
5233 else if ( y-y_offset > 0.25 ) {
5234 gamma = 2.0; /* each y pixels have been blended */
5235 alpha[i] += alpha[i+2]; /* add up alpha weights */
5236 pixels[i].red += pixels[i+2].red;
5237 pixels[i].green += pixels[i+2].green;
5238 pixels[i].blue += pixels[i+2].blue;
5239 pixels[i].black += pixels[i+2].black;
5240 pixels[i].alpha += pixels[i+2].alpha;
5241 }
5242 }
5243 if ( x-x_offset >= 0.75 ) {
5244 alpha[0] = alpha[1];
5245 pixels[0] = pixels[1];
5246 }
5247 else if ( x-x_offset > 0.25 ) {
5248 gamma *= 2.0; /* double number of pixels blended */
5249 alpha[0] += alpha[1]; /* add up alpha weights */
5250 pixels[0].red += pixels[1].red;
5251 pixels[0].green += pixels[1].green;
5252 pixels[0].blue += pixels[1].blue;
5253 pixels[0].black += pixels[1].black;
5254 pixels[0].alpha += pixels[1].alpha;
5255 }
5256 gamma = 1.0/gamma;
5257 alpha[0]=MagickEpsilonReciprocal(alpha[0]);
5258 pixel->red = alpha[0]*pixels[0].red;
5259 pixel->green = alpha[0]*pixels[0].green; /* divide by sum of alpha */
5260 pixel->blue = alpha[0]*pixels[0].blue;
5261 pixel->black = alpha[0]*pixels[0].black;
5262 pixel->alpha = gamma*pixels[0].alpha; /* divide by number of pixels */
5263 break;
5264 }
5265 case CatromInterpolatePixel:
cristy4c08aed2011-07-01 19:47:50 +00005266 {
cristy380a11c2012-06-02 15:15:22 +00005267 MagickRealType
cristy380a11c2012-06-02 15:15:22 +00005268 cx[4],
5269 cy[4];
cristy4c08aed2011-07-01 19:47:50 +00005270
cristy4c08aed2011-07-01 19:47:50 +00005271 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5272 exception);
5273 if (p == (const Quantum *) NULL)
5274 {
5275 status=MagickFalse;
5276 break;
5277 }
anthonycf4e33d2012-06-08 07:33:23 +00005278 for (i=0; i < 16L; i++)
5279 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
nicolasd32d5e52012-06-12 15:34:10 +00005280 CatromWeights((MagickRealType) (x-x_offset),&cx);
5281 CatromWeights((MagickRealType) (y-y_offset),&cy);
cristy380a11c2012-06-02 15:15:22 +00005282 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*
5283 pixels[1].red+cx[2]*pixels[2].red+cx[3]*
5284 pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
5285 pixels[5].red+cx[2]*pixels[6].red+cx[3]*
5286 pixels[7].red)+cy[2]*(cx[0]*pixels[8].red+cx[1]*
5287 pixels[9].red+cx[2]*pixels[10].red+cx[3]*
5288 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*
5289 pixels[13].red+cx[2]*pixels[14].red+cx[3]*pixels[15].red));
5290 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*
5291 pixels[1].green+cx[2]*pixels[2].green+cx[3]*
5292 pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+cx[1]*
5293 pixels[5].green+cx[2]*pixels[6].green+cx[3]*
5294 pixels[7].green)+cy[2]*(cx[0]*pixels[8].green+cx[1]*
5295 pixels[9].green+cx[2]*pixels[10].green+cx[3]*
5296 pixels[11].green)+cy[3]*(cx[0]*pixels[12].green+cx[1]*
5297 pixels[13].green+cx[2]*pixels[14].green+cx[3]*pixels[15].green));
5298 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*
5299 pixels[1].blue+cx[2]*pixels[2].blue+cx[3]*
5300 pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]*
5301 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*
5302 pixels[7].blue)+cy[2]*(cx[0]*pixels[8].blue+cx[1]*
5303 pixels[9].blue+cx[2]*pixels[10].blue+cx[3]*
5304 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*
5305 pixels[13].blue+cx[2]*pixels[14].blue+cx[3]*pixels[15].blue));
5306 if (image->colorspace == CMYKColorspace)
5307 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*
5308 pixels[1].black+cx[2]*pixels[2].black+cx[3]*
5309 pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+cx[1]*
5310 pixels[5].black+cx[2]*pixels[6].black+cx[3]*
5311 pixels[7].black)+cy[2]*(cx[0]*pixels[8].black+cx[1]*
5312 pixels[9].black+cx[2]*pixels[10].black+cx[3]*
5313 pixels[11].black)+cy[3]*(cx[0]*pixels[12].black+cx[1]*
5314 pixels[13].black+cx[2]*pixels[14].black+cx[3]*pixels[15].black));
5315 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*
5316 pixels[1].alpha+cx[2]*pixels[2].alpha+cx[3]*
5317 pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+cx[1]*
5318 pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*
5319 pixels[7].alpha)+cy[2]*(cx[0]*pixels[8].alpha+cx[1]*
5320 pixels[9].alpha+cx[2]*pixels[10].alpha+cx[3]*
5321 pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+cx[1]*
5322 pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha));
cristy4c08aed2011-07-01 19:47:50 +00005323 break;
5324 }
anthonycf4e33d2012-06-08 07:33:23 +00005325#if 0
nicolas20075dc2012-06-12 20:47:38 +00005326 /* deprecated useless and very slow interpolator */
cristy4c08aed2011-07-01 19:47:50 +00005327 case FilterInterpolatePixel:
5328 {
5329 CacheView
5330 *filter_view;
5331
5332 Image
5333 *excerpt_image,
5334 *filter_image;
5335
5336 RectangleInfo
5337 geometry;
5338
5339 geometry.width=4L;
5340 geometry.height=4L;
5341 geometry.x=x_offset-1;
5342 geometry.y=y_offset-1;
5343 excerpt_image=ExcerptImage(image,&geometry,exception);
5344 if (excerpt_image == (Image *) NULL)
5345 {
5346 status=MagickFalse;
5347 break;
5348 }
cristyaa2c16c2012-03-25 22:21:35 +00005349 filter_image=ResizeImage(excerpt_image,1,1,image->filter,exception);
cristy4c08aed2011-07-01 19:47:50 +00005350 excerpt_image=DestroyImage(excerpt_image);
5351 if (filter_image == (Image *) NULL)
5352 break;
cristydb070952012-04-20 14:33:00 +00005353 filter_view=AcquireVirtualCacheView(filter_image,exception);
cristy4c08aed2011-07-01 19:47:50 +00005354 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
5355 if (p != (const Quantum *) NULL)
cristy803640d2011-11-17 02:11:32 +00005356 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005357 filter_view=DestroyCacheView(filter_view);
5358 filter_image=DestroyImage(filter_image);
5359 break;
5360 }
anthonycf4e33d2012-06-08 07:33:23 +00005361#endif
cristy4c08aed2011-07-01 19:47:50 +00005362 case IntegerInterpolatePixel:
5363 {
5364 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
5365 if (p == (const Quantum *) NULL)
5366 {
5367 status=MagickFalse;
5368 break;
5369 }
cristy803640d2011-11-17 02:11:32 +00005370 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005371 break;
5372 }
5373 case MeshInterpolatePixel:
5374 {
5375 PointInfo
5376 delta,
5377 luminance;
5378
cristy94ea1632011-07-30 20:40:25 +00005379 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
cristy4c08aed2011-07-01 19:47:50 +00005380 if (p == (const Quantum *) NULL)
5381 {
5382 status=MagickFalse;
5383 break;
5384 }
cristy94ea1632011-07-30 20:40:25 +00005385 delta.x=x-x_offset;
5386 delta.y=y-y_offset;
cristy884f6002011-07-31 00:51:45 +00005387 luminance.x=GetPixelLuminance(image,p)-(double)
cristy94ea1632011-07-30 20:40:25 +00005388 GetPixelLuminance(image,p+3*GetPixelChannels(image));
cristy28474bf2011-09-11 23:32:52 +00005389 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
cristy94ea1632011-07-30 20:40:25 +00005390 GetPixelLuminance(image,p+2*GetPixelChannels(image));
cristy5ce8df82011-07-07 14:52:23 +00005391 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005392 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005393 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5394 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
cristy4c08aed2011-07-01 19:47:50 +00005395 if (fabs(luminance.x) < fabs(luminance.y))
5396 {
5397 /*
5398 Diagonal 0-3 NW-SE.
5399 */
5400 if (delta.x <= delta.y)
5401 {
5402 /*
cristy94ea1632011-07-30 20:40:25 +00005403 Bottom-left triangle (pixel: 2, diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005404 */
5405 delta.y=1.0-delta.y;
5406 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
cristyc58380a2012-06-03 15:12:30 +00005407 gamma=MagickEpsilonReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005408 pixel->red=gamma*MeshInterpolate(&delta,pixels[2].red,
5409 pixels[3].red,pixels[0].red);
5410 pixel->green=gamma*MeshInterpolate(&delta,pixels[2].green,
5411 pixels[3].green,pixels[0].green);
5412 pixel->blue=gamma*MeshInterpolate(&delta,pixels[2].blue,
5413 pixels[3].blue,pixels[0].blue);
cristy4c08aed2011-07-01 19:47:50 +00005414 if (image->colorspace == CMYKColorspace)
5415 pixel->black=gamma*MeshInterpolate(&delta,pixels[2].black,
5416 pixels[3].black,pixels[0].black);
cristy94ea1632011-07-30 20:40:25 +00005417 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005418 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[2].alpha,
5419 pixels[3].alpha,pixels[0].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005420 }
5421 else
5422 {
5423 /*
cristy94ea1632011-07-30 20:40:25 +00005424 Top-right triangle (pixel:1 , diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005425 */
5426 delta.x=1.0-delta.x;
5427 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
cristyc58380a2012-06-03 15:12:30 +00005428 gamma=MagickEpsilonReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005429 pixel->red=gamma*MeshInterpolate(&delta,pixels[1].red,
5430 pixels[0].red,pixels[3].red);
5431 pixel->green=gamma*MeshInterpolate(&delta,pixels[1].green,
5432 pixels[0].green,pixels[3].green);
5433 pixel->blue=gamma*MeshInterpolate(&delta,pixels[1].blue,
5434 pixels[0].blue,pixels[3].blue);
cristy4c08aed2011-07-01 19:47:50 +00005435 if (image->colorspace == CMYKColorspace)
5436 pixel->black=gamma*MeshInterpolate(&delta,pixels[1].black,
5437 pixels[0].black,pixels[3].black);
cristy94ea1632011-07-30 20:40:25 +00005438 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005439 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[1].alpha,
5440 pixels[0].alpha,pixels[3].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005441 }
5442 }
5443 else
5444 {
5445 /*
5446 Diagonal 1-2 NE-SW.
5447 */
5448 if (delta.x <= (1.0-delta.y))
5449 {
5450 /*
cristy94ea1632011-07-30 20:40:25 +00005451 Top-left triangle (pixel: 0, diagonal: 1-2).
cristy4c08aed2011-07-01 19:47:50 +00005452 */
5453 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
cristyc58380a2012-06-03 15:12:30 +00005454 gamma=MagickEpsilonReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005455 pixel->red=gamma*MeshInterpolate(&delta,pixels[0].red,
5456 pixels[1].red,pixels[2].red);
5457 pixel->green=gamma*MeshInterpolate(&delta,pixels[0].green,
5458 pixels[1].green,pixels[2].green);
5459 pixel->blue=gamma*MeshInterpolate(&delta,pixels[0].blue,
5460 pixels[1].blue,pixels[2].blue);
cristy4c08aed2011-07-01 19:47:50 +00005461 if (image->colorspace == CMYKColorspace)
5462 pixel->black=gamma*MeshInterpolate(&delta,pixels[0].black,
5463 pixels[1].black,pixels[2].black);
cristy94ea1632011-07-30 20:40:25 +00005464 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005465 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[0].alpha,
5466 pixels[1].alpha,pixels[2].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005467 }
5468 else
5469 {
5470 /*
5471 Bottom-right triangle (pixel: 3, diagonal: 1-2).
5472 */
5473 delta.x=1.0-delta.x;
5474 delta.y=1.0-delta.y;
5475 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
cristyc58380a2012-06-03 15:12:30 +00005476 gamma=MagickEpsilonReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005477 pixel->red=gamma*MeshInterpolate(&delta,pixels[3].red,
5478 pixels[2].red,pixels[1].red);
5479 pixel->green=gamma*MeshInterpolate(&delta,pixels[3].green,
5480 pixels[2].green,pixels[1].green);
5481 pixel->blue=gamma*MeshInterpolate(&delta,pixels[3].blue,
5482 pixels[2].blue,pixels[1].blue);
cristy4c08aed2011-07-01 19:47:50 +00005483 if (image->colorspace == CMYKColorspace)
5484 pixel->black=gamma*MeshInterpolate(&delta,pixels[3].black,
5485 pixels[2].black,pixels[1].black);
cristy94ea1632011-07-30 20:40:25 +00005486 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005487 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[3].alpha,
5488 pixels[2].alpha,pixels[1].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005489 }
5490 }
5491 break;
5492 }
anthonycf4e33d2012-06-08 07:33:23 +00005493 case NearestInterpolatePixel:
cristy4c08aed2011-07-01 19:47:50 +00005494 {
anthonycf4e33d2012-06-08 07:33:23 +00005495 x_offset=(ssize_t) floor(x+0.5);
5496 y_offset=(ssize_t) floor(y+0.5);
5497 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00005498 if (p == (const Quantum *) NULL)
5499 {
5500 status=MagickFalse;
5501 break;
5502 }
cristy803640d2011-11-17 02:11:32 +00005503 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005504 break;
5505 }
5506 case SplineInterpolatePixel:
5507 {
5508 MagickRealType
nicolasd32d5e52012-06-12 15:34:10 +00005509 cx[4],
5510 cy[4];
cristy4c08aed2011-07-01 19:47:50 +00005511
5512 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5513 exception);
5514 if (p == (const Quantum *) NULL)
5515 {
5516 status=MagickFalse;
5517 break;
5518 }
anthonycf4e33d2012-06-08 07:33:23 +00005519 for (i=0; i < 16L; i++)
5520 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
nicolasd32d5e52012-06-12 15:34:10 +00005521 SplineWeights((MagickRealType) (x-x_offset),&cx);
5522 SplineWeights((MagickRealType) (y-y_offset),&cy);
5523 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*
5524 pixels[1].red+cx[2]*pixels[2].red+cx[3]*
5525 pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
5526 pixels[5].red+cx[2]*pixels[6].red+cx[3]*
5527 pixels[7].red)+cy[2]*(cx[0]*pixels[8].red+cx[1]*
5528 pixels[9].red+cx[2]*pixels[10].red+cx[3]*
5529 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*
5530 pixels[13].red+cx[2]*pixels[14].red+cx[3]*pixels[15].red));
5531 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*
5532 pixels[1].green+cx[2]*pixels[2].green+cx[3]*
5533 pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+cx[1]*
5534 pixels[5].green+cx[2]*pixels[6].green+cx[3]*
5535 pixels[7].green)+cy[2]*(cx[0]*pixels[8].green+cx[1]*
5536 pixels[9].green+cx[2]*pixels[10].green+cx[3]*
5537 pixels[11].green)+cy[3]*(cx[0]*pixels[12].green+cx[1]*
5538 pixels[13].green+cx[2]*pixels[14].green+cx[3]*pixels[15].green));
5539 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*
5540 pixels[1].blue+cx[2]*pixels[2].blue+cx[3]*
5541 pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]*
5542 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*
5543 pixels[7].blue)+cy[2]*(cx[0]*pixels[8].blue+cx[1]*
5544 pixels[9].blue+cx[2]*pixels[10].blue+cx[3]*
5545 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*
5546 pixels[13].blue+cx[2]*pixels[14].blue+cx[3]*pixels[15].blue));
5547 if (image->colorspace == CMYKColorspace)
5548 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*
5549 pixels[1].black+cx[2]*pixels[2].black+cx[3]*
5550 pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+cx[1]*
5551 pixels[5].black+cx[2]*pixels[6].black+cx[3]*
5552 pixels[7].black)+cy[2]*(cx[0]*pixels[8].black+cx[1]*
5553 pixels[9].black+cx[2]*pixels[10].black+cx[3]*
5554 pixels[11].black)+cy[3]*(cx[0]*pixels[12].black+cx[1]*
5555 pixels[13].black+cx[2]*pixels[14].black+cx[3]*pixels[15].black));
5556 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*
5557 pixels[1].alpha+cx[2]*pixels[2].alpha+cx[3]*
5558 pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+cx[1]*
5559 pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*
5560 pixels[7].alpha)+cy[2]*(cx[0]*pixels[8].alpha+cx[1]*
5561 pixels[9].alpha+cx[2]*pixels[10].alpha+cx[3]*
5562 pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+cx[1]*
5563 pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha));
cristy4c08aed2011-07-01 19:47:50 +00005564 break;
5565 }
5566 }
5567 return(status);
5568}
5569
5570/*
5571%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5572% %
5573% %
5574% %
5575+ I s F u z z y E q u i v a l e n c e P i x e l %
5576% %
5577% %
5578% %
5579%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5580%
5581% IsFuzzyEquivalencePixel() returns MagickTrue if the distance between two
5582% pixels is less than the specified distance in a linear three (or four)u
5583% dimensional color space.
5584%
5585% The format of the IsFuzzyEquivalencePixel method is:
5586%
cristye4a40472011-12-22 02:56:19 +00005587% void IsFuzzyEquivalencePixel(const Image *source,const Quantum *p,
5588% const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005589%
5590% A description of each parameter follows:
5591%
cristye4a40472011-12-22 02:56:19 +00005592% o source: the source image.
cristy4c08aed2011-07-01 19:47:50 +00005593%
5594% o p: Pixel p.
5595%
cristye4a40472011-12-22 02:56:19 +00005596% o destination: the destination image.
5597%
cristy4c08aed2011-07-01 19:47:50 +00005598% o q: Pixel q.
5599%
5600*/
cristye4a40472011-12-22 02:56:19 +00005601MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source,
5602 const Quantum *p,const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005603{
5604 MagickRealType
5605 fuzz,
5606 pixel;
5607
5608 register MagickRealType
5609 distance,
5610 scale;
5611
cristye4a40472011-12-22 02:56:19 +00005612 fuzz=MagickMax(source->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(
5613 destination->fuzz,(MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005614 scale=1.0;
5615 distance=0.0;
cristye4a40472011-12-22 02:56:19 +00005616 if (source->matte != MagickFalse)
cristy4c08aed2011-07-01 19:47:50 +00005617 {
5618 /*
5619 Transparencies are involved - set alpha distance
5620 */
cristy99abff32011-12-24 20:45:16 +00005621 pixel=GetPixelAlpha(source,p)-(MagickRealType)
5622 GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005623 distance=pixel*pixel;
5624 if (distance > fuzz)
5625 return(MagickFalse);
5626 /*
5627 Generate a alpha scaling factor to generate a 4D cone on colorspace
5628 Note that if one color is transparent, distance has no color component.
5629 */
cristye4a40472011-12-22 02:56:19 +00005630 scale=QuantumScale*GetPixelAlpha(source,p);
5631 scale*=QuantumScale*GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005632 if (scale <= MagickEpsilon)
5633 return(MagickTrue);
5634 }
5635 /*
5636 RGB or CMY color cube
5637 */
5638 distance*=3.0; /* rescale appropriately */
5639 fuzz*=3.0;
cristye4a40472011-12-22 02:56:19 +00005640 pixel=GetPixelRed(source,p)-(MagickRealType) GetPixelRed(destination,q);
5641 if ((source->colorspace == HSLColorspace) ||
5642 (source->colorspace == HSBColorspace) ||
5643 (source->colorspace == HWBColorspace))
cristy4c08aed2011-07-01 19:47:50 +00005644 {
5645 /*
5646 Compute an arc distance for hue. It should be a vector angle of
5647 'S'/'W' length with 'L'/'B' forming appropriate cones.
5648 */
5649 if (fabs((double) pixel) > (QuantumRange/2))
5650 pixel-=QuantumRange;
5651 pixel*=2;
5652 }
5653 distance+=scale*pixel*pixel;
5654 if (distance > fuzz)
5655 return(MagickFalse);
cristye4a40472011-12-22 02:56:19 +00005656 pixel=GetPixelGreen(source,p)-(MagickRealType) GetPixelGreen(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005657 distance+=scale*pixel*pixel;
5658 if (distance > fuzz)
5659 return(MagickFalse);
cristye4a40472011-12-22 02:56:19 +00005660 pixel=GetPixelBlue(source,p)-(MagickRealType) GetPixelBlue(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005661 distance+=scale*pixel*pixel;
5662 if (distance > fuzz)
5663 return(MagickFalse);
5664 return(MagickTrue);
5665}
5666
5667/*
5668%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5669% %
5670% %
5671% %
5672+ 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 %
5673% %
5674% %
5675% %
5676%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5677%
5678% IsFuzzyEquivalencePixelInfo() returns true if the distance between two
5679% colors is less than the specified distance in a linear three (or four)
5680% dimensional color space.
5681%
cristy5f95f4f2011-10-23 01:01:01 +00005682% This implements the equivalent of:
5683% fuzz < sqrt(color_distance^2 * u.a*v.a + alpha_distance^2)
cristy4c08aed2011-07-01 19:47:50 +00005684%
5685% Which produces a multi-dimensional cone for that colorspace along the
5686% transparency vector.
5687%
cristy5f95f4f2011-10-23 01:01:01 +00005688% For example for an RGB:
cristy4c08aed2011-07-01 19:47:50 +00005689% color_distance^2 = ( (u.r-v.r)^2 + (u.g-v.g)^2 + (u.b-v.b)^2 ) / 3
5690%
5691% See http://www.imagemagick.org/Usage/bugs/fuzz_distance/
5692%
5693% Hue colorspace distances need more work. Hue is not a distance, it is an
5694% angle!
5695%
5696% A check that q is in the same color space as p should be made and the
5697% appropriate mapping made. -- Anthony Thyssen 8 December 2010
5698%
5699% The format of the IsFuzzyEquivalencePixelInfo method is:
5700%
5701% MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5702% const PixelInfo *q)
5703%
5704% A description of each parameter follows:
5705%
5706% o p: Pixel p.
5707%
5708% o q: Pixel q.
5709%
5710*/
5711MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5712 const PixelInfo *q)
5713{
5714 MagickRealType
5715 fuzz,
5716 pixel;
5717
5718 register MagickRealType
5719 scale,
5720 distance;
5721
5722 if ((p->fuzz == 0.0) && (q->fuzz == 0.0))
5723 return(IsPixelInfoEquivalent(p,q));
5724 if (p->fuzz == 0.0)
cristy5f95f4f2011-10-23 01:01:01 +00005725 fuzz=MagickMax(q->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(q->fuzz,
5726 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005727 else if (q->fuzz == 0.0)
cristy5f95f4f2011-10-23 01:01:01 +00005728 fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(p->fuzz,
5729 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005730 else
cristy5f95f4f2011-10-23 01:01:01 +00005731 fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(q->fuzz,
5732 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005733 scale=1.0;
5734 distance=0.0;
5735 if ((p->matte != MagickFalse) || (q->matte != MagickFalse))
5736 {
5737 /*
5738 Transparencies are involved - set alpha distance.
5739 */
5740 pixel=(p->matte != MagickFalse ? p->alpha : OpaqueAlpha)-
5741 (q->matte != MagickFalse ? q->alpha : OpaqueAlpha);
5742 distance=pixel*pixel;
5743 if (distance > fuzz)
5744 return(MagickFalse);
5745 /*
5746 Generate a alpha scaling factor to generate a 4D cone on colorspace.
cristy5f95f4f2011-10-23 01:01:01 +00005747 If one color is transparent, distance has no color component.
cristy4c08aed2011-07-01 19:47:50 +00005748 */
5749 if (p->matte != MagickFalse)
5750 scale=(QuantumScale*p->alpha);
5751 if (q->matte != MagickFalse)
5752 scale*=(QuantumScale*q->alpha);
5753 if (scale <= MagickEpsilon )
5754 return(MagickTrue);
5755 }
5756 /*
5757 CMYK create a CMY cube with a multi-dimensional cone toward black.
5758 */
5759 if (p->colorspace == CMYKColorspace)
5760 {
5761 pixel=p->black-q->black;
5762 distance+=pixel*pixel*scale;
5763 if (distance > fuzz)
5764 return(MagickFalse);
5765 scale*=(MagickRealType) (QuantumScale*(QuantumRange-p->black));
5766 scale*=(MagickRealType) (QuantumScale*(QuantumRange-q->black));
5767 }
5768 /*
5769 RGB or CMY color cube.
5770 */
5771 distance*=3.0; /* rescale appropriately */
5772 fuzz*=3.0;
5773 pixel=p->red-q->red;
5774 if ((p->colorspace == HSLColorspace) || (p->colorspace == HSBColorspace) ||
5775 (p->colorspace == HWBColorspace))
5776 {
cristy5f95f4f2011-10-23 01:01:01 +00005777 /*
5778 This calculates a arc distance for hue-- it should be a vector angle
5779 of 'S'/'W' length with 'L'/'B' forming appropriate cones. In other
5780 words this is a hack - Anthony.
cristy4c08aed2011-07-01 19:47:50 +00005781 */
5782 if (fabs((double) pixel) > (QuantumRange/2))
5783 pixel-=QuantumRange;
5784 pixel*=2;
5785 }
5786 distance+=pixel*pixel*scale;
5787 if (distance > fuzz)
5788 return(MagickFalse);
5789 pixel=p->green-q->green;
5790 distance+=pixel*pixel*scale;
5791 if (distance > fuzz)
5792 return(MagickFalse);
5793 pixel=p->blue-q->blue;
5794 distance+=pixel*pixel*scale;
5795 if (distance > fuzz)
5796 return(MagickFalse);
5797 return(MagickTrue);
5798}
5799
5800/*
5801%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5802% %
5803% %
5804% %
cristye2a912b2011-12-05 20:02:07 +00005805% 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 +00005806% %
5807% %
5808% %
5809%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5810%
cristye2a912b2011-12-05 20:02:07 +00005811% SetPixelChannelMapMask() sets the pixel channel map from the specified
5812% channel mask.
cristy2b9582a2011-07-04 17:38:56 +00005813%
cristye2a912b2011-12-05 20:02:07 +00005814% The format of the SetPixelChannelMapMask method is:
cristy2b9582a2011-07-04 17:38:56 +00005815%
cristye2a912b2011-12-05 20:02:07 +00005816% void SetPixelChannelMapMask(Image *image,const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005817%
5818% A description of each parameter follows:
5819%
5820% o image: the image.
5821%
cristydfdb19e2012-03-21 22:22:24 +00005822% o channel_mask: the channel mask.
cristy2b9582a2011-07-04 17:38:56 +00005823%
5824*/
cristye2a912b2011-12-05 20:02:07 +00005825MagickExport void SetPixelChannelMapMask(Image *image,
cristy07a67852011-08-26 13:25:03 +00005826 const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005827{
cristy6a917d62011-08-24 17:31:30 +00005828#define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01)
cristydafd2872011-07-24 22:06:13 +00005829
cristy2b9582a2011-07-04 17:38:56 +00005830 register ssize_t
5831 i;
5832
cristy177e41c2012-04-15 15:08:25 +00005833 if (image->debug != MagickFalse)
5834 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%08x]", \
5835 image->filename,channel_mask); \
cristy3c309812011-11-08 02:40:43 +00005836 image->channel_mask=channel_mask;
cristydafd2872011-07-24 22:06:13 +00005837 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
cristye2a912b2011-12-05 20:02:07 +00005838 {
5839 PixelChannel
5840 channel;
5841
5842 channel=GetPixelChannelMapChannel(image,i);
5843 SetPixelChannelMapTraits(image,channel,
5844 GetChannelBit(channel_mask,channel) == 0 ? CopyPixelTrait :
cristy0bbd87c2011-12-13 19:34:45 +00005845 image->matte == MagickFalse || (channel == AlphaPixelChannel) ?
5846 UpdatePixelTrait : (PixelTrait) (UpdatePixelTrait | BlendPixelTrait));
cristye2a912b2011-12-05 20:02:07 +00005847 }
cristy1685e722011-09-06 00:04:19 +00005848 if (image->storage_class == PseudoClass)
5849 SetPixelChannelMapTraits(image,IndexPixelChannel,CopyPixelTrait);
cristy183a5c72012-01-30 01:40:35 +00005850 if (image->mask != MagickFalse)
cristy10a6c612012-01-29 21:41:05 +00005851 SetPixelChannelMapTraits(image,MaskPixelChannel,CopyPixelTrait);
cristy6dcb9b82011-10-23 23:21:25 +00005852 if (image->debug != MagickFalse)
5853 LogPixelChannels(image);
cristy2b9582a2011-07-04 17:38:56 +00005854}
5855
5856/*
5857%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5858% %
5859% %
5860% %
cristybd5a96c2011-08-21 00:04:26 +00005861% S e t P i x e l C h a n n e l M a s k %
cristy2b9582a2011-07-04 17:38:56 +00005862% %
5863% %
5864% %
5865%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5866%
cristy5f95f4f2011-10-23 01:01:01 +00005867% SetPixelChannelMask() sets the pixel channel mask from the specified channel
5868% mask.
cristy2b9582a2011-07-04 17:38:56 +00005869%
cristybd5a96c2011-08-21 00:04:26 +00005870% The format of the SetPixelChannelMask method is:
cristy2b9582a2011-07-04 17:38:56 +00005871%
cristybd5a96c2011-08-21 00:04:26 +00005872% ChannelType SetPixelChannelMask(Image *image,
5873% const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005874%
5875% A description of each parameter follows:
5876%
5877% o image: the image.
5878%
cristybd5a96c2011-08-21 00:04:26 +00005879% o channel_mask: the channel mask.
5880%
cristy2b9582a2011-07-04 17:38:56 +00005881*/
cristybd5a96c2011-08-21 00:04:26 +00005882MagickExport ChannelType SetPixelChannelMask(Image *image,
5883 const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005884{
cristybd5a96c2011-08-21 00:04:26 +00005885 ChannelType
5886 mask;
cristy222b19c2011-08-04 01:35:11 +00005887
cristybd5a96c2011-08-21 00:04:26 +00005888 mask=image->channel_mask;
5889 image->channel_mask=channel_mask;
cristye2a912b2011-12-05 20:02:07 +00005890 SetPixelChannelMapMask(image,channel_mask);
cristybd5a96c2011-08-21 00:04:26 +00005891 return(mask);
cristy2b9582a2011-07-04 17:38:56 +00005892}
cristy322d07d2012-03-18 21:17:23 +00005893
5894/*
5895%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5896% %
5897% %
5898% %
5899% S e t P i x e l M e t a C h a n n e l s %
5900% %
5901% %
5902% %
5903%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5904%
5905% SetPixelMetaChannels() sets the image meta channels.
5906%
5907% The format of the SetPixelMetaChannels method is:
5908%
5909% MagickBooleanType SetPixelMetaChannels(Image *image,
5910% const size_t number_meta_channels,ExceptionInfo *exception)
5911%
5912% A description of each parameter follows:
5913%
5914% o image: the image.
5915%
5916% o number_meta_channels: the number of meta channels.
5917%
5918% o exception: return any errors or warnings in this structure.
5919%
5920*/
5921MagickExport MagickBooleanType SetPixelMetaChannels(Image *image,
5922 const size_t number_meta_channels,ExceptionInfo *exception)
5923{
5924 image->number_meta_channels=number_meta_channels;
5925 return(SyncImagePixelCache(image,exception));
5926}