blob: 73a5f903cd365facbb080e6bf692d18d22198c08 [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"
45#include "MagickCore/color-private.h"
46#include "MagickCore/draw.h"
47#include "MagickCore/exception.h"
48#include "MagickCore/exception-private.h"
49#include "MagickCore/cache.h"
50#include "MagickCore/constitute.h"
51#include "MagickCore/delegate.h"
52#include "MagickCore/geometry.h"
53#include "MagickCore/image-private.h"
54#include "MagickCore/list.h"
55#include "MagickCore/magick.h"
56#include "MagickCore/memory_.h"
57#include "MagickCore/monitor.h"
58#include "MagickCore/option.h"
59#include "MagickCore/pixel.h"
60#include "MagickCore/pixel-accessor.h"
61#include "MagickCore/quantum.h"
62#include "MagickCore/quantum-private.h"
63#include "MagickCore/resource_.h"
64#include "MagickCore/semaphore.h"
65#include "MagickCore/statistic.h"
66#include "MagickCore/stream.h"
67#include "MagickCore/string_.h"
68#include "MagickCore/transform.h"
69#include "MagickCore/utility.h"
70
cristy146a62b2011-10-23 23:40:46 +000071#define LogPixelChannels(image) \
72{ \
73 register ssize_t \
74 i; \
75 \
76 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%.20g]", \
77 image->filename,(double) image->number_channels); \
78 for (i=0; i < (ssize_t) image->number_channels; i++) \
79 { \
80 char \
81 traits[MaxTextExtent]; \
82 \
83 const char \
cristy46795722011-12-10 23:56:57 +000084 *name; \
85 \
86 PixelChannel \
87 channel; \
cristy146a62b2011-10-23 23:40:46 +000088 \
cristye2a912b2011-12-05 20:02:07 +000089 switch (GetPixelChannelMapChannel(image,i)) \
cristy146a62b2011-10-23 23:40:46 +000090 { \
91 case RedPixelChannel: \
92 { \
cristy46795722011-12-10 23:56:57 +000093 name="red"; \
cristy146a62b2011-10-23 23:40:46 +000094 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +000095 name="cyan"; \
cristy146a62b2011-10-23 23:40:46 +000096 if (image->colorspace == GRAYColorspace) \
cristy46795722011-12-10 23:56:57 +000097 name="gray"; \
cristy146a62b2011-10-23 23:40:46 +000098 break; \
99 } \
100 case GreenPixelChannel: \
101 { \
cristy46795722011-12-10 23:56:57 +0000102 name="green"; \
cristy146a62b2011-10-23 23:40:46 +0000103 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +0000104 name="magenta"; \
cristy146a62b2011-10-23 23:40:46 +0000105 break; \
106 } \
107 case BluePixelChannel: \
108 { \
cristy46795722011-12-10 23:56:57 +0000109 name="blue"; \
cristy146a62b2011-10-23 23:40:46 +0000110 if (image->colorspace == CMYKColorspace) \
cristy46795722011-12-10 23:56:57 +0000111 name="yellow"; \
cristy146a62b2011-10-23 23:40:46 +0000112 break; \
113 } \
114 case BlackPixelChannel: \
115 { \
cristy46795722011-12-10 23:56:57 +0000116 name="black"; \
cristy146a62b2011-10-23 23:40:46 +0000117 if (image->storage_class == PseudoClass) \
cristy46795722011-12-10 23:56:57 +0000118 name="index"; \
cristy146a62b2011-10-23 23:40:46 +0000119 break; \
120 } \
cristye2a912b2011-12-05 20:02:07 +0000121 case IndexPixelChannel: \
122 { \
cristy46795722011-12-10 23:56:57 +0000123 name="index"; \
cristye2a912b2011-12-05 20:02:07 +0000124 break; \
125 } \
cristy146a62b2011-10-23 23:40:46 +0000126 case AlphaPixelChannel: \
127 { \
cristy46795722011-12-10 23:56:57 +0000128 name="alpha"; \
cristy146a62b2011-10-23 23:40:46 +0000129 break; \
130 } \
131 case MaskPixelChannel: \
132 { \
cristy46795722011-12-10 23:56:57 +0000133 name="mask"; \
cristy146a62b2011-10-23 23:40:46 +0000134 break; \
135 } \
cristye2a912b2011-12-05 20:02:07 +0000136 case MetaPixelChannel: \
cristy146a62b2011-10-23 23:40:46 +0000137 { \
cristy46795722011-12-10 23:56:57 +0000138 name="meta"; \
cristye2a912b2011-12-05 20:02:07 +0000139 break; \
cristy146a62b2011-10-23 23:40:46 +0000140 } \
cristye2a912b2011-12-05 20:02:07 +0000141 default: \
cristy46795722011-12-10 23:56:57 +0000142 name="undefined"; \
cristy146a62b2011-10-23 23:40:46 +0000143 } \
cristy46795722011-12-10 23:56:57 +0000144 channel=GetPixelChannelMapChannel(image,i); \
cristy146a62b2011-10-23 23:40:46 +0000145 *traits='\0'; \
cristy46795722011-12-10 23:56:57 +0000146 if ((GetPixelChannelMapTraits(image,channel) & UpdatePixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000147 (void) ConcatenateMagickString(traits,"update,",MaxTextExtent); \
cristy46795722011-12-10 23:56:57 +0000148 if ((GetPixelChannelMapTraits(image,channel) & BlendPixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000149 (void) ConcatenateMagickString(traits,"blend,",MaxTextExtent); \
cristy46795722011-12-10 23:56:57 +0000150 if ((GetPixelChannelMapTraits(image,channel) & CopyPixelTrait) != 0) \
cristy146a62b2011-10-23 23:40:46 +0000151 (void) ConcatenateMagickString(traits,"copy,",MaxTextExtent); \
152 if (*traits == '\0') \
153 (void) ConcatenateMagickString(traits,"undefined,",MaxTextExtent); \
154 traits[strlen(traits)-1]='\0'; \
155 (void) LogMagickEvent(PixelEvent,GetMagickModule()," %.20g: %s (%s)", \
cristy46795722011-12-10 23:56:57 +0000156 (double) i,name,traits); \
cristy146a62b2011-10-23 23:40:46 +0000157 } \
158}
159
160/*
cristy4c08aed2011-07-01 19:47:50 +0000161%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
162% %
163% %
164% %
cristyed231572011-07-14 02:18:59 +0000165+ 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 +0000166% %
167% %
168% %
169%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
170%
cristyed231572011-07-14 02:18:59 +0000171% AcquirePixelChannelMap() acquires a pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000172%
cristyed231572011-07-14 02:18:59 +0000173% The format of the AcquirePixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000174%
cristybd5a96c2011-08-21 00:04:26 +0000175% PixelChannelMap *AcquirePixelChannelMap(void)
cristy4c08aed2011-07-01 19:47:50 +0000176%
177*/
cristybd5a96c2011-08-21 00:04:26 +0000178MagickExport PixelChannelMap *AcquirePixelChannelMap(void)
cristy4c08aed2011-07-01 19:47:50 +0000179{
cristyed231572011-07-14 02:18:59 +0000180 PixelChannelMap
cristybd5a96c2011-08-21 00:04:26 +0000181 *channel_map;
cristy4c08aed2011-07-01 19:47:50 +0000182
183 register ssize_t
184 i;
185
cristybd5a96c2011-08-21 00:04:26 +0000186 channel_map=(PixelChannelMap *) AcquireQuantumMemory(MaxPixelChannels,
187 sizeof(*channel_map));
188 if (channel_map == (PixelChannelMap *) NULL)
cristy4c08aed2011-07-01 19:47:50 +0000189 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristybd5a96c2011-08-21 00:04:26 +0000190 (void) ResetMagickMemory(channel_map,0,MaxPixelChannels*sizeof(*channel_map));
191 for (i=0; i < MaxPixelChannels; i++)
192 channel_map[i].channel=(PixelChannel) i;
cristyed231572011-07-14 02:18:59 +0000193 return(channel_map);
cristy4c08aed2011-07-01 19:47:50 +0000194}
195
196/*
197%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
198% %
199% %
200% %
cristyed231572011-07-14 02:18:59 +0000201+ 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 +0000202% %
203% %
204% %
205%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
206%
cristyed231572011-07-14 02:18:59 +0000207% ClonePixelChannelMap() clones a pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000208%
cristyed231572011-07-14 02:18:59 +0000209% The format of the ClonePixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000210%
cristybd5a96c2011-08-21 00:04:26 +0000211% PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000212%
213% A description of each parameter follows:
214%
cristyed231572011-07-14 02:18:59 +0000215% o channel_map: the pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000216%
217*/
cristybd5a96c2011-08-21 00:04:26 +0000218MagickExport PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000219{
cristyed231572011-07-14 02:18:59 +0000220 PixelChannelMap
cristybd5a96c2011-08-21 00:04:26 +0000221 *clone_map;
cristy4c08aed2011-07-01 19:47:50 +0000222
cristybd5a96c2011-08-21 00:04:26 +0000223 assert(channel_map != (PixelChannelMap *) NULL);
cristyed231572011-07-14 02:18:59 +0000224 clone_map=AcquirePixelChannelMap();
cristybd5a96c2011-08-21 00:04:26 +0000225 if (clone_map == (PixelChannelMap *) NULL)
226 return((PixelChannelMap *) NULL);
227 (void) CopyMagickMemory(clone_map,channel_map,MaxPixelChannels*
228 sizeof(*channel_map));
cristy4c08aed2011-07-01 19:47:50 +0000229 return(clone_map);
230}
231
232/*
233%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
234% %
235% %
236% %
237+ C l o n e P i x e l I n f o %
238% %
239% %
240% %
241%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
242%
243% ClonePixelInfo() makes a duplicate of the given pixel info structure, or if
244% pixel info is NULL, a new one.
245%
246% The format of the ClonePixelInfo method is:
247%
248% PixelInfo *ClonePixelInfo(const PixelInfo *pixel_info)
249%
250% A description of each parameter follows:
251%
252% o pixel_info: the pixel info.
253%
254*/
255MagickExport PixelInfo *ClonePixelInfo(const PixelInfo *pixel)
256{
257 PixelInfo
258 *pixel_info;
259
cristya64b85d2011-09-14 01:02:31 +0000260 pixel_info=(PixelInfo *) AcquireQuantumMemory(1,sizeof(*pixel_info));
cristy4c08aed2011-07-01 19:47:50 +0000261 if (pixel_info == (PixelInfo *) NULL)
262 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
263 *pixel_info=(*pixel);
264 return(pixel_info);
265}
266
267/*
268%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
269% %
270% %
271% %
cristyed231572011-07-14 02:18:59 +0000272+ 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 +0000273% %
274% %
275% %
276%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
277%
cristyed231572011-07-14 02:18:59 +0000278% DestroyPixelChannelMap() deallocates memory associated with the pixel
279% channel map.
cristy4c08aed2011-07-01 19:47:50 +0000280%
cristyed231572011-07-14 02:18:59 +0000281% The format of the DestroyPixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000282%
cristybd5a96c2011-08-21 00:04:26 +0000283% PixelChannelMap *DestroyPixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000284%
285% A description of each parameter follows:
286%
cristyed231572011-07-14 02:18:59 +0000287% o channel_map: the pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000288%
289*/
cristybd5a96c2011-08-21 00:04:26 +0000290MagickExport PixelChannelMap *DestroyPixelChannelMap(
291 PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000292{
cristybd5a96c2011-08-21 00:04:26 +0000293 assert(channel_map != (PixelChannelMap *) NULL);
294 channel_map=(PixelChannelMap *) RelinquishMagickMemory(channel_map);
295 return((PixelChannelMap *) RelinquishMagickMemory(channel_map));
cristy4c08aed2011-07-01 19:47:50 +0000296}
297
298/*
299%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
300% %
301% %
302% %
303% E x p o r t I m a g e P i x e l s %
304% %
305% %
306% %
307%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
308%
309% ExportImagePixels() extracts pixel data from an image and returns it to you.
310% The method returns MagickTrue on success otherwise MagickFalse if an error is
cristyb5a45a32012-01-10 13:31:13 +0000311% encountered. The data is returned as char, short int, Quantum, unsigned int,
cristycafe0412012-01-10 13:29:58 +0000312% unsigned long long, float, or double in the order specified by map.
cristy4c08aed2011-07-01 19:47:50 +0000313%
314% Suppose you want to extract the first scanline of a 640x480 image as
315% character data in red-green-blue order:
316%
317% ExportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels,exception);
318%
319% The format of the ExportImagePixels method is:
320%
cristycafe0412012-01-10 13:29:58 +0000321% MagickBooleanType ExportImagePixels(const Image *image,const ssize_t x,
322% const ssize_t y,const size_t width,const size_t height,
323% const char *map,const StorageType type,void *pixels,
cristy46f4be22012-01-07 00:26:39 +0000324% ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +0000325%
326% A description of each parameter follows:
327%
328% o image: the image.
329%
cristycafe0412012-01-10 13:29:58 +0000330% o x,y,width,height: These values define the perimeter
cristy4c08aed2011-07-01 19:47:50 +0000331% of a region of pixels you want to extract.
332%
333% o map: This string reflects the expected ordering of the pixel array.
334% It can be any combination or order of R = red, G = green, B = blue,
335% A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
336% Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
337% P = pad.
338%
339% o type: Define the data type of the pixels. Float and double types are
340% normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
cristy6c9e1682012-01-07 21:37:44 +0000341% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
cristyff6834e2012-01-10 03:00:25 +0000342% LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
cristy6c9e1682012-01-07 21:37:44 +0000343% QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
cristy4c08aed2011-07-01 19:47:50 +0000344%
345% o pixels: This array of values contain the pixel components as defined by
346% map and type. You must preallocate this array where the expected
347% length varies depending on the values of width, height, map, and type.
348%
349% o exception: return any errors or warnings in this structure.
350%
351*/
cristye5370942012-01-06 03:49:31 +0000352
cristycafe0412012-01-10 13:29:58 +0000353static void ExportCharPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000354 const char *restrict map,const QuantumType *quantum_map,void *pixels,
355 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000356{
357 register const Quantum
358 *restrict p;
359
360 register ssize_t
361 x;
362
363 register unsigned char
cristy3fe11452012-01-09 01:27:42 +0000364 *restrict q;
cristye5370942012-01-06 03:49:31 +0000365
366 ssize_t
367 y;
368
cristy46f4be22012-01-07 00:26:39 +0000369 q=(unsigned char *) pixels;
cristye5370942012-01-06 03:49:31 +0000370 if (LocaleCompare(map,"BGR") == 0)
371 {
cristycafe0412012-01-10 13:29:58 +0000372 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000373 {
cristycafe0412012-01-10 13:29:58 +0000374 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000375 if (p == (const Quantum *) NULL)
376 break;
cristycafe0412012-01-10 13:29:58 +0000377 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000378 {
379 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
380 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
381 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
382 p+=GetPixelChannels(image);
383 }
384 }
385 return;
386 }
387 if (LocaleCompare(map,"BGRA") == 0)
388 {
cristycafe0412012-01-10 13:29:58 +0000389 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000390 {
cristycafe0412012-01-10 13:29:58 +0000391 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000392 if (p == (const Quantum *) NULL)
393 break;
cristycafe0412012-01-10 13:29:58 +0000394 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000395 {
396 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
397 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
398 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
399 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
400 p+=GetPixelChannels(image);
401 }
402 }
403 return;
404 }
405 if (LocaleCompare(map,"BGRP") == 0)
406 {
cristycafe0412012-01-10 13:29:58 +0000407 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000408 {
cristycafe0412012-01-10 13:29:58 +0000409 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000410 if (p == (const Quantum *) NULL)
411 break;
cristycafe0412012-01-10 13:29:58 +0000412 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000413 {
414 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
415 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
416 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
417 *q++=ScaleQuantumToChar((Quantum) 0);
418 p+=GetPixelChannels(image);
419 }
420 }
421 return;
422 }
423 if (LocaleCompare(map,"I") == 0)
424 {
cristycafe0412012-01-10 13:29:58 +0000425 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000426 {
cristycafe0412012-01-10 13:29:58 +0000427 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000428 if (p == (const Quantum *) NULL)
429 break;
cristycafe0412012-01-10 13:29:58 +0000430 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000431 {
432 *q++=ScaleQuantumToChar(GetPixelIntensity(image,p));
433 p+=GetPixelChannels(image);
434 }
435 }
436 return;
437 }
438 if (LocaleCompare(map,"RGB") == 0)
439 {
cristycafe0412012-01-10 13:29:58 +0000440 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000441 {
cristycafe0412012-01-10 13:29:58 +0000442 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000443 if (p == (const Quantum *) NULL)
444 break;
cristycafe0412012-01-10 13:29:58 +0000445 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000446 {
447 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
448 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
449 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
450 p+=GetPixelChannels(image);
451 }
452 }
453 return;
454 }
455 if (LocaleCompare(map,"RGBA") == 0)
456 {
cristycafe0412012-01-10 13:29:58 +0000457 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000458 {
cristycafe0412012-01-10 13:29:58 +0000459 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000460 if (p == (const Quantum *) NULL)
461 break;
cristycafe0412012-01-10 13:29:58 +0000462 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000463 {
464 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
465 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
466 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
467 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
468 p+=GetPixelChannels(image);
469 }
470 }
471 return;
472 }
473 if (LocaleCompare(map,"RGBP") == 0)
474 {
cristycafe0412012-01-10 13:29:58 +0000475 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000476 {
cristycafe0412012-01-10 13:29:58 +0000477 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000478 if (p == (const Quantum *) NULL)
479 break;
cristycafe0412012-01-10 13:29:58 +0000480 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000481 {
482 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
483 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
484 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
485 *q++=ScaleQuantumToChar((Quantum) 0);
486 p+=GetPixelChannels(image);
487 }
488 }
489 return;
490 }
cristycafe0412012-01-10 13:29:58 +0000491 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000492 {
cristycafe0412012-01-10 13:29:58 +0000493 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000494 if (p == (const Quantum *) NULL)
495 break;
cristycafe0412012-01-10 13:29:58 +0000496 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000497 {
498 register ssize_t
499 i;
500
501 for (i=0; i < (ssize_t) strlen(map); i++)
502 {
503 *q=0;
504 switch (quantum_map[i])
505 {
506 case RedQuantum:
507 case CyanQuantum:
508 {
509 *q=ScaleQuantumToChar(GetPixelRed(image,p));
510 break;
511 }
512 case GreenQuantum:
513 case MagentaQuantum:
514 {
515 *q=ScaleQuantumToChar(GetPixelGreen(image,p));
516 break;
517 }
518 case BlueQuantum:
519 case YellowQuantum:
520 {
521 *q=ScaleQuantumToChar(GetPixelBlue(image,p));
522 break;
523 }
524 case AlphaQuantum:
525 {
526 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
527 break;
528 }
529 case OpacityQuantum:
530 {
531 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
532 break;
533 }
534 case BlackQuantum:
535 {
536 if (image->colorspace == CMYKColorspace)
537 *q=ScaleQuantumToChar(GetPixelBlack(image,p));
538 break;
539 }
540 case IndexQuantum:
541 {
542 *q=ScaleQuantumToChar(GetPixelIntensity(image,p));
543 break;
544 }
545 default:
546 break;
547 }
548 q++;
549 }
550 p+=GetPixelChannels(image);
551 }
552 }
553}
554
cristycafe0412012-01-10 13:29:58 +0000555static void ExportDoublePixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000556 const char *restrict map,const QuantumType *quantum_map,void *pixels,
557 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000558{
559 register const Quantum
560 *restrict p;
561
562 register double
cristy3fe11452012-01-09 01:27:42 +0000563 *restrict q;
cristye5370942012-01-06 03:49:31 +0000564
565 register ssize_t
566 x;
567
568 ssize_t
569 y;
570
571 q=(double *) pixels;
572 if (LocaleCompare(map,"BGR") == 0)
573 {
cristycafe0412012-01-10 13:29:58 +0000574 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000575 {
cristycafe0412012-01-10 13:29:58 +0000576 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000577 if (p == (const Quantum *) NULL)
578 break;
cristycafe0412012-01-10 13:29:58 +0000579 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000580 {
581 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
582 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
583 *q++=(double) (QuantumScale*GetPixelRed(image,p));
584 p+=GetPixelChannels(image);
585 }
586 }
587 return;
588 }
589 if (LocaleCompare(map,"BGRA") == 0)
590 {
cristycafe0412012-01-10 13:29:58 +0000591 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000592 {
cristycafe0412012-01-10 13:29:58 +0000593 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000594 if (p == (const Quantum *) NULL)
595 break;
cristycafe0412012-01-10 13:29:58 +0000596 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000597 {
598 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
599 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
600 *q++=(double) (QuantumScale*GetPixelRed(image,p));
601 *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
602 p+=GetPixelChannels(image);
603 }
604 }
605 return;
606 }
607 if (LocaleCompare(map,"BGRP") == 0)
608 {
cristycafe0412012-01-10 13:29:58 +0000609 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000610 {
cristycafe0412012-01-10 13:29:58 +0000611 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000612 if (p == (const Quantum *) NULL)
613 break;
cristycafe0412012-01-10 13:29:58 +0000614 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000615 {
616 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
617 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
618 *q++=(double) (QuantumScale*GetPixelRed(image,p));
619 *q++=0.0;
620 p+=GetPixelChannels(image);
621 }
622 }
623 return;
624 }
625 if (LocaleCompare(map,"I") == 0)
626 {
cristycafe0412012-01-10 13:29:58 +0000627 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000628 {
cristycafe0412012-01-10 13:29:58 +0000629 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000630 if (p == (const Quantum *) NULL)
631 break;
cristycafe0412012-01-10 13:29:58 +0000632 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000633 {
634 *q++=(double) (QuantumScale*GetPixelIntensity(image,p));
635 p+=GetPixelChannels(image);
636 }
637 }
638 return;
639 }
640 if (LocaleCompare(map,"RGB") == 0)
641 {
cristycafe0412012-01-10 13:29:58 +0000642 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000643 {
cristycafe0412012-01-10 13:29:58 +0000644 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000645 if (p == (const Quantum *) NULL)
646 break;
cristycafe0412012-01-10 13:29:58 +0000647 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000648 {
649 *q++=(double) (QuantumScale*GetPixelRed(image,p));
650 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
651 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
652 p+=GetPixelChannels(image);
653 }
654 }
655 return;
656 }
657 if (LocaleCompare(map,"RGBA") == 0)
658 {
cristycafe0412012-01-10 13:29:58 +0000659 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000660 {
cristycafe0412012-01-10 13:29:58 +0000661 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000662 if (p == (const Quantum *) NULL)
663 break;
cristycafe0412012-01-10 13:29:58 +0000664 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000665 {
666 *q++=(double) (QuantumScale*GetPixelRed(image,p));
667 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
668 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
669 *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
670 p+=GetPixelChannels(image);
671 }
672 }
673 return;
674 }
675 if (LocaleCompare(map,"RGBP") == 0)
676 {
cristycafe0412012-01-10 13:29:58 +0000677 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000678 {
cristycafe0412012-01-10 13:29:58 +0000679 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000680 if (p == (const Quantum *) NULL)
681 break;
cristycafe0412012-01-10 13:29:58 +0000682 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000683 {
684 *q++=(double) (QuantumScale*GetPixelRed(image,p));
685 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
686 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
687 *q++=0.0;
688 p+=GetPixelChannels(image);
689 }
690 }
691 return;
692 }
cristycafe0412012-01-10 13:29:58 +0000693 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000694 {
cristycafe0412012-01-10 13:29:58 +0000695 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000696 if (p == (const Quantum *) NULL)
697 break;
cristycafe0412012-01-10 13:29:58 +0000698 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000699 {
700 register ssize_t
701 i;
702
703 for (i=0; i < (ssize_t) strlen(map); i++)
704 {
705 *q=0;
706 switch (quantum_map[i])
707 {
708 case RedQuantum:
709 case CyanQuantum:
710 {
711 *q=(double) (QuantumScale*GetPixelRed(image,p));
712 break;
713 }
714 case GreenQuantum:
715 case MagentaQuantum:
716 {
717 *q=(double) (QuantumScale*GetPixelGreen(image,p));
718 break;
719 }
720 case BlueQuantum:
721 case YellowQuantum:
722 {
723 *q=(double) (QuantumScale*GetPixelBlue(image,p));
724 break;
725 }
726 case AlphaQuantum:
727 {
728 *q=(double) (QuantumScale*GetPixelAlpha(image,p));
729 break;
730 }
731 case OpacityQuantum:
732 {
733 *q=(double) (QuantumScale*GetPixelAlpha(image,p));
734 break;
735 }
736 case BlackQuantum:
737 {
738 if (image->colorspace == CMYKColorspace)
739 *q=(double) (QuantumScale*
740 GetPixelBlack(image,p));
741 break;
742 }
743 case IndexQuantum:
744 {
745 *q=(double) (QuantumScale*GetPixelIntensity(image,p));
746 break;
747 }
748 default:
749 *q=0;
750 }
751 q++;
752 }
753 p+=GetPixelChannels(image);
754 }
755 }
756}
757
cristycafe0412012-01-10 13:29:58 +0000758static void ExportFloatPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000759 const char *restrict map,const QuantumType *quantum_map,void *pixels,
760 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000761{
762 register const Quantum
763 *restrict p;
764
765 register float
cristy3fe11452012-01-09 01:27:42 +0000766 *restrict q;
cristye5370942012-01-06 03:49:31 +0000767
768 register ssize_t
769 x;
770
771 ssize_t
772 y;
773
774 q=(float *) pixels;
775 if (LocaleCompare(map,"BGR") == 0)
776 {
cristycafe0412012-01-10 13:29:58 +0000777 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000778 {
cristycafe0412012-01-10 13:29:58 +0000779 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000780 if (p == (const Quantum *) NULL)
781 break;
cristycafe0412012-01-10 13:29:58 +0000782 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000783 {
784 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
785 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
786 *q++=(float) (QuantumScale*GetPixelRed(image,p));
787 p+=GetPixelChannels(image);
788 }
789 }
790 return;
791 }
792 if (LocaleCompare(map,"BGRA") == 0)
793 {
cristycafe0412012-01-10 13:29:58 +0000794 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000795 {
cristycafe0412012-01-10 13:29:58 +0000796 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000797 if (p == (const Quantum *) NULL)
798 break;
cristycafe0412012-01-10 13:29:58 +0000799 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000800 {
801 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
802 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
803 *q++=(float) (QuantumScale*GetPixelRed(image,p));
804 *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
805 p+=GetPixelChannels(image);
806 }
807 }
808 return;
809 }
810 if (LocaleCompare(map,"BGRP") == 0)
811 {
cristycafe0412012-01-10 13:29:58 +0000812 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000813 {
cristycafe0412012-01-10 13:29:58 +0000814 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000815 if (p == (const Quantum *) NULL)
816 break;
cristycafe0412012-01-10 13:29:58 +0000817 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000818 {
819 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
820 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
821 *q++=(float) (QuantumScale*GetPixelRed(image,p));
822 *q++=0.0;
823 p+=GetPixelChannels(image);
824 }
825 }
826 return;
827 }
828 if (LocaleCompare(map,"I") == 0)
829 {
cristycafe0412012-01-10 13:29:58 +0000830 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000831 {
cristycafe0412012-01-10 13:29:58 +0000832 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000833 if (p == (const Quantum *) NULL)
834 break;
cristycafe0412012-01-10 13:29:58 +0000835 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000836 {
837 *q++=(float) (QuantumScale*GetPixelIntensity(image,p));
838 p+=GetPixelChannels(image);
839 }
840 }
841 return;
842 }
843 if (LocaleCompare(map,"RGB") == 0)
844 {
cristycafe0412012-01-10 13:29:58 +0000845 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000846 {
cristycafe0412012-01-10 13:29:58 +0000847 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000848 if (p == (const Quantum *) NULL)
849 break;
cristycafe0412012-01-10 13:29:58 +0000850 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000851 {
852 *q++=(float) (QuantumScale*GetPixelRed(image,p));
853 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
854 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
855 p+=GetPixelChannels(image);
856 }
857 }
858 return;
859 }
860 if (LocaleCompare(map,"RGBA") == 0)
861 {
cristycafe0412012-01-10 13:29:58 +0000862 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000863 {
cristycafe0412012-01-10 13:29:58 +0000864 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000865 if (p == (const Quantum *) NULL)
866 break;
cristycafe0412012-01-10 13:29:58 +0000867 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000868 {
869 *q++=(float) (QuantumScale*GetPixelRed(image,p));
870 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
871 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
872 *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
873 p+=GetPixelChannels(image);
874 }
875 }
876 return;
877 }
878 if (LocaleCompare(map,"RGBP") == 0)
879 {
cristycafe0412012-01-10 13:29:58 +0000880 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000881 {
cristycafe0412012-01-10 13:29:58 +0000882 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000883 if (p == (const Quantum *) NULL)
884 break;
cristycafe0412012-01-10 13:29:58 +0000885 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000886 {
887 *q++=(float) (QuantumScale*GetPixelRed(image,p));
888 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
889 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
890 *q++=0.0;
891 p+=GetPixelChannels(image);
892 }
893 }
894 return;
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 register ssize_t
904 i;
905
906 for (i=0; i < (ssize_t) strlen(map); i++)
907 {
908 *q=0;
909 switch (quantum_map[i])
910 {
911 case RedQuantum:
912 case CyanQuantum:
913 {
914 *q=(float) (QuantumScale*GetPixelRed(image,p));
915 break;
916 }
917 case GreenQuantum:
918 case MagentaQuantum:
919 {
920 *q=(float) (QuantumScale*GetPixelGreen(image,p));
921 break;
922 }
923 case BlueQuantum:
924 case YellowQuantum:
925 {
926 *q=(float) (QuantumScale*GetPixelBlue(image,p));
927 break;
928 }
929 case AlphaQuantum:
930 {
931 *q=(float) (QuantumScale*((Quantum) (GetPixelAlpha(image,p))));
932 break;
933 }
934 case OpacityQuantum:
935 {
936 *q=(float) (QuantumScale*GetPixelAlpha(image,p));
937 break;
938 }
939 case BlackQuantum:
940 {
941 if (image->colorspace == CMYKColorspace)
942 *q=(float) (QuantumScale* GetPixelBlack(image,p));
943 break;
944 }
945 case IndexQuantum:
946 {
947 *q=(float) (QuantumScale*GetPixelIntensity(image,p));
948 break;
949 }
950 default:
951 *q=0;
952 }
953 q++;
954 }
955 p+=GetPixelChannels(image);
956 }
957 }
958}
959
cristycafe0412012-01-10 13:29:58 +0000960static void ExportLongPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +0000961 const char *restrict map,const QuantumType *quantum_map,void *pixels,
962 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000963{
964 register const Quantum
965 *restrict p;
966
967 register ssize_t
968 x;
969
970 register unsigned int
cristy3fe11452012-01-09 01:27:42 +0000971 *restrict q;
cristye5370942012-01-06 03:49:31 +0000972
973 ssize_t
974 y;
975
976 q=(unsigned int *) pixels;
977 if (LocaleCompare(map,"BGR") == 0)
978 {
cristycafe0412012-01-10 13:29:58 +0000979 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000980 {
cristycafe0412012-01-10 13:29:58 +0000981 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000982 if (p == (const Quantum *) NULL)
983 break;
cristycafe0412012-01-10 13:29:58 +0000984 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000985 {
cristy6c9e1682012-01-07 21:37:44 +0000986 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
987 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
988 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +0000989 p+=GetPixelChannels(image);
990 }
991 }
992 return;
993 }
994 if (LocaleCompare(map,"BGRA") == 0)
995 {
cristycafe0412012-01-10 13:29:58 +0000996 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000997 {
cristycafe0412012-01-10 13:29:58 +0000998 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000999 if (p == (const Quantum *) NULL)
1000 break;
cristycafe0412012-01-10 13:29:58 +00001001 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001002 {
cristy6c9e1682012-01-07 21:37:44 +00001003 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1004 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1005 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1006 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001007 p+=GetPixelChannels(image);
1008 }
1009 }
1010 return;
1011 }
1012 if (LocaleCompare(map,"BGRP") == 0)
1013 {
cristycafe0412012-01-10 13:29:58 +00001014 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001015 {
cristycafe0412012-01-10 13:29:58 +00001016 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001017 if (p == (const Quantum *) NULL)
1018 break;
cristycafe0412012-01-10 13:29:58 +00001019 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001020 {
cristy6c9e1682012-01-07 21:37:44 +00001021 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1022 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1023 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1024 *q++=0;
cristye5370942012-01-06 03:49:31 +00001025 p+=GetPixelChannels(image);
1026 }
1027 }
1028 return;
1029 }
1030 if (LocaleCompare(map,"I") == 0)
1031 {
cristycafe0412012-01-10 13:29:58 +00001032 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001033 {
cristycafe0412012-01-10 13:29:58 +00001034 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001035 if (p == (const Quantum *) NULL)
1036 break;
cristycafe0412012-01-10 13:29:58 +00001037 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001038 {
cristy6c9e1682012-01-07 21:37:44 +00001039 *q++=ScaleQuantumToLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001040 p+=GetPixelChannels(image);
1041 }
1042 }
1043 return;
1044 }
1045 if (LocaleCompare(map,"RGB") == 0)
1046 {
cristycafe0412012-01-10 13:29:58 +00001047 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001048 {
cristycafe0412012-01-10 13:29:58 +00001049 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001050 if (p == (const Quantum *) NULL)
1051 break;
cristycafe0412012-01-10 13:29:58 +00001052 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001053 {
cristy6c9e1682012-01-07 21:37:44 +00001054 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1055 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1056 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001057 p+=GetPixelChannels(image);
1058 }
1059 }
1060 return;
1061 }
1062 if (LocaleCompare(map,"RGBA") == 0)
1063 {
cristycafe0412012-01-10 13:29:58 +00001064 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001065 {
cristycafe0412012-01-10 13:29:58 +00001066 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001067 if (p == (const Quantum *) NULL)
1068 break;
cristycafe0412012-01-10 13:29:58 +00001069 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001070 {
cristy6c9e1682012-01-07 21:37:44 +00001071 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1072 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1073 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1074 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001075 p+=GetPixelChannels(image);
1076 }
1077 }
1078 return;
1079 }
1080 if (LocaleCompare(map,"RGBP") == 0)
1081 {
cristycafe0412012-01-10 13:29:58 +00001082 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001083 {
cristycafe0412012-01-10 13:29:58 +00001084 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001085 if (p == (const Quantum *) NULL)
1086 break;
cristycafe0412012-01-10 13:29:58 +00001087 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001088 {
cristy6c9e1682012-01-07 21:37:44 +00001089 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1090 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1091 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1092 *q++=0;
cristye5370942012-01-06 03:49:31 +00001093 p+=GetPixelChannels(image);
1094 }
1095 }
1096 return;
1097 }
cristycafe0412012-01-10 13:29:58 +00001098 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001099 {
cristycafe0412012-01-10 13:29:58 +00001100 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001101 if (p == (const Quantum *) NULL)
1102 break;
cristycafe0412012-01-10 13:29:58 +00001103 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001104 {
1105 register ssize_t
1106 i;
1107
1108 for (i=0; i < (ssize_t) strlen(map); i++)
1109 {
1110 *q=0;
1111 switch (quantum_map[i])
1112 {
1113 case RedQuantum:
1114 case CyanQuantum:
1115 {
cristy6c9e1682012-01-07 21:37:44 +00001116 *q=ScaleQuantumToLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001117 break;
1118 }
1119 case GreenQuantum:
1120 case MagentaQuantum:
1121 {
cristy6c9e1682012-01-07 21:37:44 +00001122 *q=ScaleQuantumToLong(GetPixelGreen(image,p));
cristye5370942012-01-06 03:49:31 +00001123 break;
1124 }
1125 case BlueQuantum:
1126 case YellowQuantum:
1127 {
cristy6c9e1682012-01-07 21:37:44 +00001128 *q=ScaleQuantumToLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001129 break;
1130 }
1131 case AlphaQuantum:
1132 {
cristy6c9e1682012-01-07 21:37:44 +00001133 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001134 break;
1135 }
1136 case OpacityQuantum:
1137 {
cristy6c9e1682012-01-07 21:37:44 +00001138 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001139 break;
1140 }
1141 case BlackQuantum:
1142 {
1143 if (image->colorspace == CMYKColorspace)
cristy6c9e1682012-01-07 21:37:44 +00001144 *q=ScaleQuantumToLong(GetPixelBlack(image,p));
cristye5370942012-01-06 03:49:31 +00001145 break;
1146 }
1147 case IndexQuantum:
1148 {
cristy6c9e1682012-01-07 21:37:44 +00001149 *q=ScaleQuantumToLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001150 break;
1151 }
1152 default:
cristy6c9e1682012-01-07 21:37:44 +00001153 break;
cristye5370942012-01-06 03:49:31 +00001154 }
1155 q++;
1156 }
1157 p+=GetPixelChannels(image);
1158 }
1159 }
1160}
1161
cristycafe0412012-01-10 13:29:58 +00001162static void ExportLongLongPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00001163 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1164 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001165{
1166 register const Quantum
1167 *restrict p;
1168
1169 register ssize_t
1170 x;
1171
cristyb13e12a2012-01-06 21:48:27 +00001172 register MagickSizeType
cristy3fe11452012-01-09 01:27:42 +00001173 *restrict q;
cristye5370942012-01-06 03:49:31 +00001174
1175 ssize_t
1176 y;
1177
cristyb13e12a2012-01-06 21:48:27 +00001178 q=(MagickSizeType *) pixels;
cristye5370942012-01-06 03:49:31 +00001179 if (LocaleCompare(map,"BGR") == 0)
1180 {
cristycafe0412012-01-10 13:29:58 +00001181 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001182 {
cristycafe0412012-01-10 13:29:58 +00001183 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001184 if (p == (const Quantum *) NULL)
1185 break;
cristycafe0412012-01-10 13:29:58 +00001186 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001187 {
cristyb13e12a2012-01-06 21:48:27 +00001188 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1189 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1190 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001191 p+=GetPixelChannels(image);
1192 }
1193 }
1194 return;
1195 }
1196 if (LocaleCompare(map,"BGRA") == 0)
1197 {
cristycafe0412012-01-10 13:29:58 +00001198 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001199 {
cristycafe0412012-01-10 13:29:58 +00001200 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001201 if (p == (const Quantum *) NULL)
1202 break;
cristycafe0412012-01-10 13:29:58 +00001203 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001204 {
cristyb13e12a2012-01-06 21:48:27 +00001205 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1206 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1207 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1208 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001209 p+=GetPixelChannels(image);
1210 }
1211 }
1212 return;
1213 }
1214 if (LocaleCompare(map,"BGRP") == 0)
1215 {
cristycafe0412012-01-10 13:29:58 +00001216 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001217 {
cristycafe0412012-01-10 13:29:58 +00001218 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001219 if (p == (const Quantum *) NULL)
1220 break;
cristycafe0412012-01-10 13:29:58 +00001221 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001222 {
cristyb13e12a2012-01-06 21:48:27 +00001223 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1224 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1225 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001226 *q++=0;
1227 p+=GetPixelChannels(image);
1228 }
1229 }
1230 return;
1231 }
1232 if (LocaleCompare(map,"I") == 0)
1233 {
cristycafe0412012-01-10 13:29:58 +00001234 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001235 {
cristycafe0412012-01-10 13:29:58 +00001236 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001237 if (p == (const Quantum *) NULL)
1238 break;
cristycafe0412012-01-10 13:29:58 +00001239 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001240 {
cristyb13e12a2012-01-06 21:48:27 +00001241 *q++=ScaleQuantumToLongLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001242 p+=GetPixelChannels(image);
1243 }
1244 }
1245 return;
1246 }
1247 if (LocaleCompare(map,"RGB") == 0)
1248 {
cristycafe0412012-01-10 13:29:58 +00001249 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001250 {
cristycafe0412012-01-10 13:29:58 +00001251 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001252 if (p == (const Quantum *) NULL)
1253 break;
cristycafe0412012-01-10 13:29:58 +00001254 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001255 {
cristyb13e12a2012-01-06 21:48:27 +00001256 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1257 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1258 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001259 p+=GetPixelChannels(image);
1260 }
1261 }
1262 return;
1263 }
1264 if (LocaleCompare(map,"RGBA") == 0)
1265 {
cristycafe0412012-01-10 13:29:58 +00001266 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001267 {
cristycafe0412012-01-10 13:29:58 +00001268 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001269 if (p == (const Quantum *) NULL)
1270 break;
cristycafe0412012-01-10 13:29:58 +00001271 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001272 {
cristyb13e12a2012-01-06 21:48:27 +00001273 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1274 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1275 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1276 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001277 p+=GetPixelChannels(image);
1278 }
1279 }
1280 return;
1281 }
1282 if (LocaleCompare(map,"RGBP") == 0)
1283 {
cristycafe0412012-01-10 13:29:58 +00001284 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001285 {
cristycafe0412012-01-10 13:29:58 +00001286 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001287 if (p == (const Quantum *) NULL)
1288 break;
cristycafe0412012-01-10 13:29:58 +00001289 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001290 {
cristyb13e12a2012-01-06 21:48:27 +00001291 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1292 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1293 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001294 *q++=0;
1295 p+=GetPixelChannels(image);
1296 }
1297 }
1298 return;
1299 }
cristycafe0412012-01-10 13:29:58 +00001300 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001301 {
cristycafe0412012-01-10 13:29:58 +00001302 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001303 if (p == (const Quantum *) NULL)
1304 break;
cristycafe0412012-01-10 13:29:58 +00001305 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001306 {
1307 register ssize_t
1308 i;
1309
1310 for (i=0; i < (ssize_t) strlen(map); i++)
1311 {
1312 *q=0;
1313 switch (quantum_map[i])
1314 {
1315 case RedQuantum:
1316 case CyanQuantum:
1317 {
cristyb13e12a2012-01-06 21:48:27 +00001318 *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001319 break;
1320 }
1321 case GreenQuantum:
1322 case MagentaQuantum:
1323 {
cristyb13e12a2012-01-06 21:48:27 +00001324 *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
cristye5370942012-01-06 03:49:31 +00001325 break;
1326 }
1327 case BlueQuantum:
1328 case YellowQuantum:
1329 {
cristyb13e12a2012-01-06 21:48:27 +00001330 *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001331 break;
1332 }
1333 case AlphaQuantum:
1334 {
cristyb13e12a2012-01-06 21:48:27 +00001335 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001336 break;
1337 }
1338 case OpacityQuantum:
1339 {
cristyb13e12a2012-01-06 21:48:27 +00001340 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001341 break;
1342 }
1343 case BlackQuantum:
1344 {
1345 if (image->colorspace == CMYKColorspace)
cristyb13e12a2012-01-06 21:48:27 +00001346 *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
cristye5370942012-01-06 03:49:31 +00001347 break;
1348 }
1349 case IndexQuantum:
1350 {
cristyb13e12a2012-01-06 21:48:27 +00001351 *q=ScaleQuantumToLongLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001352 break;
1353 }
1354 default:
1355 break;
1356 }
1357 q++;
1358 }
1359 p+=GetPixelChannels(image);
1360 }
1361 }
1362}
1363
cristycafe0412012-01-10 13:29:58 +00001364static void ExportQuantumPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00001365 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1366 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001367{
1368 register const Quantum
1369 *restrict p;
1370
1371 register Quantum
cristy3fe11452012-01-09 01:27:42 +00001372 *restrict q;
cristye5370942012-01-06 03:49:31 +00001373
1374 register ssize_t
1375 x;
1376
1377 ssize_t
1378 y;
1379
1380 q=(Quantum *) pixels;
1381 if (LocaleCompare(map,"BGR") == 0)
1382 {
cristycafe0412012-01-10 13:29:58 +00001383 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001384 {
cristycafe0412012-01-10 13:29:58 +00001385 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001386 if (p == (const Quantum *) NULL)
1387 break;
cristycafe0412012-01-10 13:29:58 +00001388 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001389 {
1390 *q++=GetPixelBlue(image,p);
1391 *q++=GetPixelGreen(image,p);
1392 *q++=GetPixelRed(image,p);
1393 p+=GetPixelChannels(image);
1394 }
1395 }
1396 return;
1397 }
1398 if (LocaleCompare(map,"BGRA") == 0)
1399 {
cristycafe0412012-01-10 13:29:58 +00001400 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001401 {
cristycafe0412012-01-10 13:29:58 +00001402 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001403 if (p == (const Quantum *) NULL)
1404 break;
cristycafe0412012-01-10 13:29:58 +00001405 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001406 {
1407 *q++=GetPixelBlue(image,p);
1408 *q++=GetPixelGreen(image,p);
1409 *q++=GetPixelRed(image,p);
1410 *q++=(Quantum) (GetPixelAlpha(image,p));
1411 p+=GetPixelChannels(image);
1412 }
1413 }
1414 return;
1415 }
1416 if (LocaleCompare(map,"BGRP") == 0)
1417 {
cristycafe0412012-01-10 13:29:58 +00001418 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001419 {
cristycafe0412012-01-10 13:29:58 +00001420 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001421 if (p == (const Quantum *) NULL)
1422 break;
cristycafe0412012-01-10 13:29:58 +00001423 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001424 {
1425 *q++=GetPixelBlue(image,p);
1426 *q++=GetPixelGreen(image,p);
1427 *q++=GetPixelRed(image,p);
1428 *q++=(Quantum) 0;
1429 p+=GetPixelChannels(image);
1430 }
1431 }
1432 return;
1433 }
1434 if (LocaleCompare(map,"I") == 0)
1435 {
cristycafe0412012-01-10 13:29:58 +00001436 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001437 {
cristycafe0412012-01-10 13:29:58 +00001438 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001439 if (p == (const Quantum *) NULL)
1440 break;
cristycafe0412012-01-10 13:29:58 +00001441 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001442 {
1443 *q++=GetPixelIntensity(image,p);
1444 p+=GetPixelChannels(image);
1445 }
1446 }
1447 return;
1448 }
1449 if (LocaleCompare(map,"RGB") == 0)
1450 {
cristycafe0412012-01-10 13:29:58 +00001451 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001452 {
cristycafe0412012-01-10 13:29:58 +00001453 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001454 if (p == (const Quantum *) NULL)
1455 break;
cristycafe0412012-01-10 13:29:58 +00001456 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001457 {
1458 *q++=GetPixelRed(image,p);
1459 *q++=GetPixelGreen(image,p);
1460 *q++=GetPixelBlue(image,p);
1461 p+=GetPixelChannels(image);
1462 }
1463 }
1464 return;
1465 }
1466 if (LocaleCompare(map,"RGBA") == 0)
1467 {
cristycafe0412012-01-10 13:29:58 +00001468 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001469 {
cristycafe0412012-01-10 13:29:58 +00001470 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001471 if (p == (const Quantum *) NULL)
1472 break;
cristycafe0412012-01-10 13:29:58 +00001473 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001474 {
1475 *q++=GetPixelRed(image,p);
1476 *q++=GetPixelGreen(image,p);
1477 *q++=GetPixelBlue(image,p);
1478 *q++=(Quantum) (GetPixelAlpha(image,p));
1479 p+=GetPixelChannels(image);
1480 }
1481 }
1482 return;
1483 }
1484 if (LocaleCompare(map,"RGBP") == 0)
1485 {
cristycafe0412012-01-10 13:29:58 +00001486 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001487 {
cristycafe0412012-01-10 13:29:58 +00001488 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001489 if (p == (const Quantum *) NULL)
1490 break;
cristycafe0412012-01-10 13:29:58 +00001491 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001492 {
1493 *q++=GetPixelRed(image,p);
1494 *q++=GetPixelGreen(image,p);
1495 *q++=GetPixelBlue(image,p);
1496 *q++=(Quantum) 0;
1497 p+=GetPixelChannels(image);
1498 }
1499 }
1500 return;
1501 }
cristycafe0412012-01-10 13:29:58 +00001502 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001503 {
cristycafe0412012-01-10 13:29:58 +00001504 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001505 if (p == (const Quantum *) NULL)
1506 break;
cristycafe0412012-01-10 13:29:58 +00001507 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001508 {
1509 register ssize_t
1510 i;
1511
1512 for (i=0; i < (ssize_t) strlen(map); i++)
1513 {
1514 *q=(Quantum) 0;
1515 switch (quantum_map[i])
1516 {
1517 case RedQuantum:
1518 case CyanQuantum:
1519 {
1520 *q=GetPixelRed(image,p);
1521 break;
1522 }
1523 case GreenQuantum:
1524 case MagentaQuantum:
1525 {
1526 *q=GetPixelGreen(image,p);
1527 break;
1528 }
1529 case BlueQuantum:
1530 case YellowQuantum:
1531 {
1532 *q=GetPixelBlue(image,p);
1533 break;
1534 }
1535 case AlphaQuantum:
1536 {
1537 *q=GetPixelAlpha(image,p);
1538 break;
1539 }
1540 case OpacityQuantum:
1541 {
1542 *q=GetPixelAlpha(image,p);
1543 break;
1544 }
1545 case BlackQuantum:
1546 {
1547 if (image->colorspace == CMYKColorspace)
1548 *q=GetPixelBlack(image,p);
1549 break;
1550 }
1551 case IndexQuantum:
1552 {
1553 *q=(GetPixelIntensity(image,p));
1554 break;
1555 }
1556 default:
1557 {
1558 *q=(Quantum) 0;
1559 break;
1560 }
1561 }
1562 q++;
1563 }
1564 p+=GetPixelChannels(image);
1565 }
1566 }
1567}
1568
cristycafe0412012-01-10 13:29:58 +00001569static void ExportShortPixel(const Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00001570 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1571 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001572{
1573 register const Quantum
1574 *restrict p;
1575
1576 register ssize_t
1577 x;
1578
1579 ssize_t
1580 y;
1581
1582 register unsigned short
cristy3fe11452012-01-09 01:27:42 +00001583 *restrict q;
cristye5370942012-01-06 03:49:31 +00001584
1585 q=(unsigned short *) pixels;
1586 if (LocaleCompare(map,"BGR") == 0)
1587 {
cristycafe0412012-01-10 13:29:58 +00001588 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001589 {
cristycafe0412012-01-10 13:29:58 +00001590 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001591 if (p == (const Quantum *) NULL)
1592 break;
cristycafe0412012-01-10 13:29:58 +00001593 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001594 {
1595 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1596 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1597 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1598 p+=GetPixelChannels(image);
1599 }
1600 }
1601 return;
1602 }
1603 if (LocaleCompare(map,"BGRA") == 0)
1604 {
cristycafe0412012-01-10 13:29:58 +00001605 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001606 {
cristycafe0412012-01-10 13:29:58 +00001607 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001608 if (p == (const Quantum *) NULL)
1609 break;
cristycafe0412012-01-10 13:29:58 +00001610 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001611 {
1612 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1613 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1614 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1615 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1616 p+=GetPixelChannels(image);
1617 }
1618 }
1619 return;
1620 }
1621 if (LocaleCompare(map,"BGRP") == 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 *q++=0;
1634 p+=GetPixelChannels(image);
1635 }
1636 }
1637 return;
1638 }
1639 if (LocaleCompare(map,"I") == 0)
1640 {
cristycafe0412012-01-10 13:29:58 +00001641 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001642 {
cristycafe0412012-01-10 13:29:58 +00001643 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001644 if (p == (const Quantum *) NULL)
1645 break;
cristycafe0412012-01-10 13:29:58 +00001646 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001647 {
1648 *q++=ScaleQuantumToShort(GetPixelIntensity(image,p));
1649 p+=GetPixelChannels(image);
1650 }
1651 }
1652 return;
1653 }
1654 if (LocaleCompare(map,"RGB") == 0)
1655 {
cristycafe0412012-01-10 13:29:58 +00001656 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001657 {
cristycafe0412012-01-10 13:29:58 +00001658 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001659 if (p == (const Quantum *) NULL)
1660 break;
cristycafe0412012-01-10 13:29:58 +00001661 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001662 {
1663 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1664 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1665 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1666 p+=GetPixelChannels(image);
1667 }
1668 }
1669 return;
1670 }
1671 if (LocaleCompare(map,"RGBA") == 0)
1672 {
cristycafe0412012-01-10 13:29:58 +00001673 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001674 {
cristycafe0412012-01-10 13:29:58 +00001675 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001676 if (p == (const Quantum *) NULL)
1677 break;
cristycafe0412012-01-10 13:29:58 +00001678 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001679 {
1680 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1681 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1682 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1683 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1684 p+=GetPixelChannels(image);
1685 }
1686 }
1687 return;
1688 }
1689 if (LocaleCompare(map,"RGBP") == 0)
1690 {
cristycafe0412012-01-10 13:29:58 +00001691 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001692 {
cristycafe0412012-01-10 13:29:58 +00001693 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001694 if (p == (const Quantum *) NULL)
1695 break;
cristycafe0412012-01-10 13:29:58 +00001696 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001697 {
1698 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1699 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1700 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1701 *q++=0;
1702 p+=GetPixelChannels(image);
1703 }
1704 }
1705 return;
1706 }
cristycafe0412012-01-10 13:29:58 +00001707 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001708 {
cristycafe0412012-01-10 13:29:58 +00001709 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001710 if (p == (const Quantum *) NULL)
1711 break;
cristycafe0412012-01-10 13:29:58 +00001712 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001713 {
1714 register ssize_t
1715 i;
1716
1717 for (i=0; i < (ssize_t) strlen(map); i++)
1718 {
1719 *q=0;
1720 switch (quantum_map[i])
1721 {
1722 case RedQuantum:
1723 case CyanQuantum:
1724 {
1725 *q=ScaleQuantumToShort(GetPixelRed(image,p));
1726 break;
1727 }
1728 case GreenQuantum:
1729 case MagentaQuantum:
1730 {
1731 *q=ScaleQuantumToShort(GetPixelGreen(image,p));
1732 break;
1733 }
1734 case BlueQuantum:
1735 case YellowQuantum:
1736 {
1737 *q=ScaleQuantumToShort(GetPixelBlue(image,p));
1738 break;
1739 }
1740 case AlphaQuantum:
1741 {
1742 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1743 break;
1744 }
1745 case OpacityQuantum:
1746 {
1747 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1748 break;
1749 }
1750 case BlackQuantum:
1751 {
1752 if (image->colorspace == CMYKColorspace)
1753 *q=ScaleQuantumToShort(GetPixelBlack(image,p));
1754 break;
1755 }
1756 case IndexQuantum:
1757 {
1758 *q=ScaleQuantumToShort(GetPixelIntensity(image,p));
1759 break;
1760 }
1761 default:
1762 break;
1763 }
1764 q++;
1765 }
1766 p+=GetPixelChannels(image);
1767 }
1768 }
1769}
1770
cristy4c08aed2011-07-01 19:47:50 +00001771MagickExport MagickBooleanType ExportImagePixels(const Image *image,
cristycafe0412012-01-10 13:29:58 +00001772 const ssize_t x,const ssize_t y,const size_t width,const size_t height,
1773 const char *map,const StorageType type,void *pixels,ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00001774{
1775 QuantumType
1776 *quantum_map;
1777
cristycafe0412012-01-10 13:29:58 +00001778 RectangleInfo
1779 roi;
1780
cristy4c08aed2011-07-01 19:47:50 +00001781 register ssize_t
cristye5370942012-01-06 03:49:31 +00001782 i;
cristy4c08aed2011-07-01 19:47:50 +00001783
1784 assert(image != (Image *) NULL);
1785 assert(image->signature == MagickSignature);
1786 if (image->debug != MagickFalse)
1787 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristye5370942012-01-06 03:49:31 +00001788 quantum_map=(QuantumType *) AcquireQuantumMemory(strlen(map),
1789 sizeof(*quantum_map));
cristy4c08aed2011-07-01 19:47:50 +00001790 if (quantum_map == (QuantumType *) NULL)
1791 {
1792 (void) ThrowMagickException(exception,GetMagickModule(),
1793 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1794 return(MagickFalse);
1795 }
cristye5370942012-01-06 03:49:31 +00001796 for (i=0; i < (ssize_t) strlen(map); i++)
cristy4c08aed2011-07-01 19:47:50 +00001797 {
1798 switch (map[i])
1799 {
1800 case 'A':
1801 case 'a':
1802 {
1803 quantum_map[i]=AlphaQuantum;
1804 break;
1805 }
1806 case 'B':
1807 case 'b':
1808 {
1809 quantum_map[i]=BlueQuantum;
1810 break;
1811 }
1812 case 'C':
1813 case 'c':
1814 {
1815 quantum_map[i]=CyanQuantum;
1816 if (image->colorspace == CMYKColorspace)
1817 break;
1818 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1819 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1820 "ColorSeparatedImageRequired","`%s'",map);
1821 return(MagickFalse);
1822 }
1823 case 'g':
1824 case 'G':
1825 {
1826 quantum_map[i]=GreenQuantum;
1827 break;
1828 }
1829 case 'I':
1830 case 'i':
1831 {
1832 quantum_map[i]=IndexQuantum;
1833 break;
1834 }
1835 case 'K':
1836 case 'k':
1837 {
1838 quantum_map[i]=BlackQuantum;
1839 if (image->colorspace == CMYKColorspace)
1840 break;
1841 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1842 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1843 "ColorSeparatedImageRequired","`%s'",map);
1844 return(MagickFalse);
1845 }
1846 case 'M':
1847 case 'm':
1848 {
1849 quantum_map[i]=MagentaQuantum;
1850 if (image->colorspace == CMYKColorspace)
1851 break;
1852 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1853 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1854 "ColorSeparatedImageRequired","`%s'",map);
1855 return(MagickFalse);
1856 }
1857 case 'o':
1858 case 'O':
1859 {
1860 quantum_map[i]=OpacityQuantum;
1861 break;
1862 }
1863 case 'P':
1864 case 'p':
1865 {
1866 quantum_map[i]=UndefinedQuantum;
1867 break;
1868 }
1869 case 'R':
1870 case 'r':
1871 {
1872 quantum_map[i]=RedQuantum;
1873 break;
1874 }
1875 case 'Y':
1876 case 'y':
1877 {
1878 quantum_map[i]=YellowQuantum;
1879 if (image->colorspace == CMYKColorspace)
1880 break;
1881 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1882 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1883 "ColorSeparatedImageRequired","`%s'",map);
1884 return(MagickFalse);
1885 }
1886 default:
1887 {
1888 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1889 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
1890 "UnrecognizedPixelMap","`%s'",map);
1891 return(MagickFalse);
1892 }
1893 }
1894 }
cristycafe0412012-01-10 13:29:58 +00001895 roi.width=width;
1896 roi.height=height;
1897 roi.x=x;
1898 roi.y=y;
cristy4c08aed2011-07-01 19:47:50 +00001899 switch (type)
1900 {
1901 case CharPixel:
1902 {
cristycafe0412012-01-10 13:29:58 +00001903 ExportCharPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001904 break;
1905 }
1906 case DoublePixel:
1907 {
cristycafe0412012-01-10 13:29:58 +00001908 ExportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001909 break;
1910 }
1911 case FloatPixel:
1912 {
cristycafe0412012-01-10 13:29:58 +00001913 ExportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001914 break;
1915 }
cristy4c08aed2011-07-01 19:47:50 +00001916 case LongPixel:
1917 {
cristycafe0412012-01-10 13:29:58 +00001918 ExportLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001919 break;
1920 }
cristy6c9e1682012-01-07 21:37:44 +00001921 case LongLongPixel:
1922 {
cristycafe0412012-01-10 13:29:58 +00001923 ExportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy6c9e1682012-01-07 21:37:44 +00001924 break;
1925 }
cristy4c08aed2011-07-01 19:47:50 +00001926 case QuantumPixel:
1927 {
cristycafe0412012-01-10 13:29:58 +00001928 ExportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001929 break;
1930 }
1931 case ShortPixel:
1932 {
cristycafe0412012-01-10 13:29:58 +00001933 ExportShortPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001934 break;
1935 }
1936 default:
1937 {
1938 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1939 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
1940 "UnrecognizedPixelMap","`%s'",map);
1941 break;
1942 }
1943 }
1944 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1945 return(MagickTrue);
1946}
1947
1948/*
1949%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1950% %
1951% %
1952% %
cristyaa8634f2011-10-01 13:25:12 +00001953% G e t P i x e l I n f o %
cristy4c08aed2011-07-01 19:47:50 +00001954% %
1955% %
1956% %
1957%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1958%
1959% GetPixelInfo() initializes the PixelInfo structure.
1960%
1961% The format of the GetPixelInfo method is:
1962%
1963% GetPixelInfo(const Image *image,PixelInfo *pixel)
1964%
1965% A description of each parameter follows:
1966%
1967% o image: the image.
1968%
cristy101ab702011-10-13 13:06:32 +00001969% o pixel: Specifies a pointer to a PixelInfo structure.
cristy4c08aed2011-07-01 19:47:50 +00001970%
1971*/
cristyaa8634f2011-10-01 13:25:12 +00001972MagickExport void GetPixelInfo(const Image *image,PixelInfo *pixel)
cristy4c08aed2011-07-01 19:47:50 +00001973{
1974 pixel->storage_class=DirectClass;
1975 pixel->colorspace=RGBColorspace;
1976 pixel->matte=MagickFalse;
1977 pixel->fuzz=0.0;
1978 pixel->depth=MAGICKCORE_QUANTUM_DEPTH;
1979 pixel->red=0.0;
1980 pixel->green=0.0;
1981 pixel->blue=0.0;
1982 pixel->black=0.0;
1983 pixel->alpha=(MagickRealType) OpaqueAlpha;
1984 pixel->index=0.0;
1985 if (image == (const Image *) NULL)
1986 return;
1987 pixel->storage_class=image->storage_class;
1988 pixel->colorspace=image->colorspace;
1989 pixel->matte=image->matte;
1990 pixel->depth=image->depth;
1991 pixel->fuzz=image->fuzz;
1992}
1993
1994/*
1995%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1996% %
1997% %
1998% %
1999% I m p o r t I m a g e P i x e l s %
2000% %
2001% %
2002% %
2003%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2004%
2005% ImportImagePixels() accepts pixel data and stores in the image at the
2006% location you specify. The method returns MagickTrue on success otherwise
2007% MagickFalse if an error is encountered. The pixel data can be either char,
cristyb5a45a32012-01-10 13:31:13 +00002008% Quantum, short int, unsigned int, unsigned long long, float, or double in
2009% the order specified by map.
cristy4c08aed2011-07-01 19:47:50 +00002010%
2011% Suppose your want to upload the first scanline of a 640x480 image from
2012% character data in red-green-blue order:
2013%
2014% ImportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels);
2015%
2016% The format of the ImportImagePixels method is:
2017%
cristycafe0412012-01-10 13:29:58 +00002018% MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
2019% const ssize_t y,const size_t width,const size_t height,
2020% const char *map,const StorageType type,const void *pixels,
2021% ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00002022%
2023% A description of each parameter follows:
2024%
2025% o image: the image.
2026%
cristycafe0412012-01-10 13:29:58 +00002027% o x,y,width,height: These values define the perimeter
cristy4c08aed2011-07-01 19:47:50 +00002028% of a region of pixels you want to define.
2029%
2030% o map: This string reflects the expected ordering of the pixel array.
2031% It can be any combination or order of R = red, G = green, B = blue,
2032% A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
2033% Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
2034% P = pad.
2035%
2036% o type: Define the data type of the pixels. Float and double types are
2037% normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
cristy6c9e1682012-01-07 21:37:44 +00002038% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
cristyff6834e2012-01-10 03:00:25 +00002039% LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
cristy6c9e1682012-01-07 21:37:44 +00002040% QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
cristy4c08aed2011-07-01 19:47:50 +00002041%
2042% o pixels: This array of values contain the pixel components as defined by
2043% map and type. You must preallocate this array where the expected
2044% length varies depending on the values of width, height, map, and type.
2045%
cristy018f07f2011-09-04 21:15:19 +00002046% o exception: return any errors or warnings in this structure.
2047%
cristy4c08aed2011-07-01 19:47:50 +00002048*/
cristye5370942012-01-06 03:49:31 +00002049
cristycafe0412012-01-10 13:29:58 +00002050static void ImportCharPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002051 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2052 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002053{
2054 register const unsigned char
2055 *restrict p;
2056
2057 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002058 *restrict q;
cristye5370942012-01-06 03:49:31 +00002059
2060 register ssize_t
2061 x;
2062
2063 ssize_t
2064 y;
2065
2066 p=(const unsigned char *) pixels;
2067 if (LocaleCompare(map,"BGR") == 0)
2068 {
cristycafe0412012-01-10 13:29:58 +00002069 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002070 {
cristycafe0412012-01-10 13:29:58 +00002071 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002072 if (q == (Quantum *) NULL)
2073 break;
cristycafe0412012-01-10 13:29:58 +00002074 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002075 {
2076 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2077 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2078 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2079 q+=GetPixelChannels(image);
2080 }
2081 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2082 break;
2083 }
2084 return;
2085 }
2086 if (LocaleCompare(map,"BGRA") == 0)
2087 {
cristycafe0412012-01-10 13:29:58 +00002088 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002089 {
cristycafe0412012-01-10 13:29:58 +00002090 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002091 if (q == (Quantum *) NULL)
2092 break;
cristycafe0412012-01-10 13:29:58 +00002093 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002094 {
2095 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2096 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2097 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2098 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2099 q+=GetPixelChannels(image);
2100 }
2101 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2102 break;
2103 }
2104 return;
2105 }
2106 if (LocaleCompare(map,"BGRO") == 0)
2107 {
cristycafe0412012-01-10 13:29:58 +00002108 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002109 {
cristycafe0412012-01-10 13:29:58 +00002110 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002111 if (q == (Quantum *) NULL)
2112 break;
cristycafe0412012-01-10 13:29:58 +00002113 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002114 {
2115 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2116 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2117 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2118 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2119 q+=GetPixelChannels(image);
2120 }
2121 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2122 break;
2123 }
2124 return;
2125 }
2126 if (LocaleCompare(map,"BGRP") == 0)
2127 {
cristycafe0412012-01-10 13:29:58 +00002128 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002129 {
cristycafe0412012-01-10 13:29:58 +00002130 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002131 if (q == (Quantum *) NULL)
2132 break;
cristycafe0412012-01-10 13:29:58 +00002133 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002134 {
2135 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2136 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2137 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2138 p++;
2139 q+=GetPixelChannels(image);
2140 }
2141 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2142 break;
2143 }
2144 return;
2145 }
2146 if (LocaleCompare(map,"I") == 0)
2147 {
cristycafe0412012-01-10 13:29:58 +00002148 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002149 {
cristycafe0412012-01-10 13:29:58 +00002150 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002151 if (q == (Quantum *) NULL)
2152 break;
cristycafe0412012-01-10 13:29:58 +00002153 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002154 {
2155 SetPixelGray(image,ScaleCharToQuantum(*p++),q);
2156 q+=GetPixelChannels(image);
2157 }
2158 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2159 break;
2160 }
2161 return;
2162 }
2163 if (LocaleCompare(map,"RGB") == 0)
2164 {
cristycafe0412012-01-10 13:29:58 +00002165 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002166 {
cristycafe0412012-01-10 13:29:58 +00002167 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002168 if (q == (Quantum *) NULL)
2169 break;
cristycafe0412012-01-10 13:29:58 +00002170 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002171 {
2172 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2173 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2174 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2175 q+=GetPixelChannels(image);
2176 }
2177 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2178 break;
2179 }
2180 return;
2181 }
2182 if (LocaleCompare(map,"RGBA") == 0)
2183 {
cristycafe0412012-01-10 13:29:58 +00002184 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002185 {
cristycafe0412012-01-10 13:29:58 +00002186 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002187 if (q == (Quantum *) NULL)
2188 break;
cristycafe0412012-01-10 13:29:58 +00002189 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002190 {
2191 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2192 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2193 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2194 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2195 q+=GetPixelChannels(image);
2196 }
2197 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2198 break;
2199 }
2200 return;
2201 }
2202 if (LocaleCompare(map,"RGBO") == 0)
2203 {
cristycafe0412012-01-10 13:29:58 +00002204 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002205 {
cristycafe0412012-01-10 13:29:58 +00002206 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002207 if (q == (Quantum *) NULL)
2208 break;
cristycafe0412012-01-10 13:29:58 +00002209 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002210 {
2211 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2212 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2213 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2214 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2215 q+=GetPixelChannels(image);
2216 }
2217 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2218 break;
2219 }
2220 return;
2221 }
2222 if (LocaleCompare(map,"RGBP") == 0)
2223 {
cristycafe0412012-01-10 13:29:58 +00002224 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002225 {
cristycafe0412012-01-10 13:29:58 +00002226 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002227 if (q == (Quantum *) NULL)
2228 break;
cristycafe0412012-01-10 13:29:58 +00002229 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002230 {
2231 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2232 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2233 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2234 p++;
2235 q+=GetPixelChannels(image);
2236 }
2237 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2238 break;
2239 }
2240 return;
2241 }
cristycafe0412012-01-10 13:29:58 +00002242 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002243 {
cristycafe0412012-01-10 13:29:58 +00002244 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002245 if (q == (Quantum *) NULL)
2246 break;
cristycafe0412012-01-10 13:29:58 +00002247 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002248 {
2249 register ssize_t
2250 i;
2251
2252 for (i=0; i < (ssize_t) strlen(map); i++)
2253 {
2254 switch (quantum_map[i])
2255 {
2256 case RedQuantum:
2257 case CyanQuantum:
2258 {
2259 SetPixelRed(image,ScaleCharToQuantum(*p),q);
2260 break;
2261 }
2262 case GreenQuantum:
2263 case MagentaQuantum:
2264 {
2265 SetPixelGreen(image,ScaleCharToQuantum(*p),q);
2266 break;
2267 }
2268 case BlueQuantum:
2269 case YellowQuantum:
2270 {
2271 SetPixelBlue(image,ScaleCharToQuantum(*p),q);
2272 break;
2273 }
2274 case AlphaQuantum:
2275 {
2276 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2277 break;
2278 }
2279 case OpacityQuantum:
2280 {
2281 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2282 break;
2283 }
2284 case BlackQuantum:
2285 {
2286 SetPixelBlack(image,ScaleCharToQuantum(*p),q);
2287 break;
2288 }
2289 case IndexQuantum:
2290 {
2291 SetPixelGray(image,ScaleCharToQuantum(*p),q);
2292 break;
2293 }
2294 default:
2295 break;
2296 }
2297 p++;
2298 }
2299 q+=GetPixelChannels(image);
2300 }
2301 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2302 break;
2303 }
2304}
2305
cristycafe0412012-01-10 13:29:58 +00002306static void ImportDoublePixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002307 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2308 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002309{
2310 register const double
2311 *restrict p;
2312
2313 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002314 *restrict q;
cristye5370942012-01-06 03:49:31 +00002315
2316 register ssize_t
2317 x;
2318
2319 ssize_t
2320 y;
2321
2322 p=(const double *) pixels;
2323 if (LocaleCompare(map,"BGR") == 0)
2324 {
cristycafe0412012-01-10 13:29:58 +00002325 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002326 {
cristycafe0412012-01-10 13:29:58 +00002327 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002328 if (q == (Quantum *) NULL)
2329 break;
cristycafe0412012-01-10 13:29:58 +00002330 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002331 {
2332 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2333 (*p)),q);
2334 p++;
2335 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2336 (*p)),q);
2337 p++;
2338 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2339 (*p)),q);
2340 p++;
2341 q+=GetPixelChannels(image);
2342 }
2343 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2344 break;
2345 }
2346 return;
2347 }
2348 if (LocaleCompare(map,"BGRA") == 0)
2349 {
cristycafe0412012-01-10 13:29:58 +00002350 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002351 {
cristycafe0412012-01-10 13:29:58 +00002352 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002353 if (q == (Quantum *) NULL)
2354 break;
cristycafe0412012-01-10 13:29:58 +00002355 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002356 {
2357 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2358 (*p)),q);
2359 p++;
2360 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2361 (*p)),q);
2362 p++;
2363 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2364 (*p)),q);
2365 p++;
2366 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2367 (*p)),q);
2368 p++;
2369 q+=GetPixelChannels(image);
2370 }
2371 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2372 break;
2373 }
2374 return;
2375 }
2376 if (LocaleCompare(map,"BGRP") == 0)
2377 {
cristycafe0412012-01-10 13:29:58 +00002378 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002379 {
cristycafe0412012-01-10 13:29:58 +00002380 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002381 if (q == (Quantum *) NULL)
2382 break;
cristycafe0412012-01-10 13:29:58 +00002383 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002384 {
2385 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2386 (*p)),q);
2387 p++;
2388 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2389 (*p)),q);
2390 p++;
2391 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2392 (*p)),q);
2393 p++;
2394 p++;
2395 q+=GetPixelChannels(image);
2396 }
2397 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2398 break;
2399 }
2400 return;
2401 }
2402 if (LocaleCompare(map,"I") == 0)
2403 {
cristycafe0412012-01-10 13:29:58 +00002404 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002405 {
cristycafe0412012-01-10 13:29:58 +00002406 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002407 if (q == (Quantum *) NULL)
2408 break;
cristycafe0412012-01-10 13:29:58 +00002409 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002410 {
2411 SetPixelGray(image,ClampToQuantum((MagickRealType) QuantumRange*
2412 (*p)),q);
2413 p++;
2414 q+=GetPixelChannels(image);
2415 }
2416 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2417 break;
2418 }
2419 return;
2420 }
2421 if (LocaleCompare(map,"RGB") == 0)
2422 {
cristycafe0412012-01-10 13:29:58 +00002423 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002424 {
cristycafe0412012-01-10 13:29:58 +00002425 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002426 if (q == (Quantum *) NULL)
2427 break;
cristycafe0412012-01-10 13:29:58 +00002428 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002429 {
2430 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2431 (*p)),q);
2432 p++;
2433 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2434 (*p)),q);
2435 p++;
2436 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2437 (*p)),q);
2438 p++;
2439 q+=GetPixelChannels(image);
2440 }
2441 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2442 break;
2443 }
2444 return;
2445 }
2446 if (LocaleCompare(map,"RGBA") == 0)
2447 {
cristycafe0412012-01-10 13:29:58 +00002448 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002449 {
cristycafe0412012-01-10 13:29:58 +00002450 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002451 if (q == (Quantum *) NULL)
2452 break;
cristycafe0412012-01-10 13:29:58 +00002453 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002454 {
2455 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2456 (*p)),q);
2457 p++;
2458 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2459 (*p)),q);
2460 p++;
2461 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2462 (*p)),q);
2463 p++;
2464 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2465 (*p)),q);
2466 p++;
2467 q+=GetPixelChannels(image);
2468 }
2469 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2470 break;
2471 }
2472 return;
2473 }
2474 if (LocaleCompare(map,"RGBP") == 0)
2475 {
cristycafe0412012-01-10 13:29:58 +00002476 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002477 {
cristycafe0412012-01-10 13:29:58 +00002478 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002479 if (q == (Quantum *) NULL)
2480 break;
cristycafe0412012-01-10 13:29:58 +00002481 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002482 {
2483 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2484 (*p)),q);
2485 p++;
2486 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2487 (*p)),q);
2488 p++;
2489 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2490 (*p)),q);
2491 p++;
2492 q+=GetPixelChannels(image);
2493 }
2494 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2495 break;
2496 }
2497 return;
2498 }
cristycafe0412012-01-10 13:29:58 +00002499 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002500 {
cristycafe0412012-01-10 13:29:58 +00002501 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002502 if (q == (Quantum *) NULL)
2503 break;
cristycafe0412012-01-10 13:29:58 +00002504 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002505 {
2506 register ssize_t
2507 i;
2508
2509 for (i=0; i < (ssize_t) strlen(map); i++)
2510 {
2511 switch (quantum_map[i])
2512 {
2513 case RedQuantum:
2514 case CyanQuantum:
2515 {
2516 SetPixelRed(image,ClampToQuantum((MagickRealType)
2517 QuantumRange*(*p)),q);
2518 break;
2519 }
2520 case GreenQuantum:
2521 case MagentaQuantum:
2522 {
2523 SetPixelGreen(image,ClampToQuantum((MagickRealType)
2524 QuantumRange*(*p)),q);
2525 break;
2526 }
2527 case BlueQuantum:
2528 case YellowQuantum:
2529 {
2530 SetPixelBlue(image,ClampToQuantum((MagickRealType)
2531 QuantumRange*(*p)),q);
2532 break;
2533 }
2534 case AlphaQuantum:
2535 {
2536 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2537 QuantumRange*(*p)),q);
2538 break;
2539 }
2540 case OpacityQuantum:
2541 {
2542 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2543 QuantumRange*(*p)),q);
2544 break;
2545 }
2546 case BlackQuantum:
2547 {
2548 SetPixelBlack(image,ClampToQuantum((MagickRealType)
2549 QuantumRange*(*p)),q);
2550 break;
2551 }
2552 case IndexQuantum:
2553 {
2554 SetPixelGray(image,ClampToQuantum((MagickRealType)
2555 QuantumRange*(*p)),q);
2556 break;
2557 }
2558 default:
2559 break;
2560 }
2561 p++;
2562 }
2563 q+=GetPixelChannels(image);
2564 }
2565 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2566 break;
2567 }
2568}
2569
cristycafe0412012-01-10 13:29:58 +00002570static void ImportFloatPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002571 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2572 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002573{
2574 register const float
2575 *restrict p;
2576
2577 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002578 *restrict q;
cristye5370942012-01-06 03:49:31 +00002579
2580 register ssize_t
2581 x;
2582
2583 ssize_t
2584 y;
2585
2586 p=(const float *) pixels;
2587 if (LocaleCompare(map,"BGR") == 0)
2588 {
cristycafe0412012-01-10 13:29:58 +00002589 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002590 {
cristycafe0412012-01-10 13:29:58 +00002591 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002592 if (q == (Quantum *) NULL)
2593 break;
cristycafe0412012-01-10 13:29:58 +00002594 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002595 {
2596 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2597 (*p)),q);
2598 p++;
2599 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2600 (*p)),q);
2601 p++;
2602 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2603 (*p)),q);
2604 p++;
2605 q+=GetPixelChannels(image);
2606 }
2607 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2608 break;
2609 }
2610 return;
2611 }
2612 if (LocaleCompare(map,"BGRA") == 0)
2613 {
cristycafe0412012-01-10 13:29:58 +00002614 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002615 {
cristycafe0412012-01-10 13:29:58 +00002616 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002617 if (q == (Quantum *) NULL)
2618 break;
cristycafe0412012-01-10 13:29:58 +00002619 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002620 {
2621 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2622 (*p)),q);
2623 p++;
2624 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2625 (*p)),q);
2626 p++;
2627 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2628 (*p)),q);
2629 p++;
2630 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2631 (*p)),q);
2632 p++;
2633 q+=GetPixelChannels(image);
2634 }
2635 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2636 break;
2637 }
2638 return;
2639 }
2640 if (LocaleCompare(map,"BGRP") == 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 p++;
2659 q+=GetPixelChannels(image);
2660 }
2661 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2662 break;
2663 }
2664 return;
2665 }
2666 if (LocaleCompare(map,"I") == 0)
2667 {
cristycafe0412012-01-10 13:29:58 +00002668 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002669 {
cristycafe0412012-01-10 13:29:58 +00002670 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002671 if (q == (Quantum *) NULL)
2672 break;
cristycafe0412012-01-10 13:29:58 +00002673 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002674 {
2675 SetPixelGray(image,ClampToQuantum((MagickRealType) QuantumRange*
2676 (*p)),q);
2677 p++;
2678 q+=GetPixelChannels(image);
2679 }
2680 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2681 break;
2682 }
2683 return;
2684 }
2685 if (LocaleCompare(map,"RGB") == 0)
2686 {
cristycafe0412012-01-10 13:29:58 +00002687 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002688 {
cristycafe0412012-01-10 13:29:58 +00002689 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002690 if (q == (Quantum *) NULL)
2691 break;
cristycafe0412012-01-10 13:29:58 +00002692 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002693 {
2694 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2695 (*p)),q);
2696 p++;
2697 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2698 (*p)),q);
2699 p++;
2700 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2701 (*p)),q);
2702 p++;
2703 q+=GetPixelChannels(image);
2704 }
2705 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2706 break;
2707 }
2708 return;
2709 }
2710 if (LocaleCompare(map,"RGBA") == 0)
2711 {
cristycafe0412012-01-10 13:29:58 +00002712 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002713 {
cristycafe0412012-01-10 13:29:58 +00002714 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002715 if (q == (Quantum *) NULL)
2716 break;
cristycafe0412012-01-10 13:29:58 +00002717 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002718 {
2719 SetPixelRed(image,ClampToQuantum((MagickRealType)
2720 QuantumRange*(*p)),q);
2721 p++;
2722 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2723 (*p)),q);
2724 p++;
2725 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2726 (*p)),q);
2727 p++;
2728 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2729 (*p)),q);
2730 p++;
2731 q+=GetPixelChannels(image);
2732 }
2733 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2734 break;
2735 }
2736 return;
2737 }
2738 if (LocaleCompare(map,"RGBP") == 0)
2739 {
cristycafe0412012-01-10 13:29:58 +00002740 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002741 {
cristycafe0412012-01-10 13:29:58 +00002742 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002743 if (q == (Quantum *) NULL)
2744 break;
cristycafe0412012-01-10 13:29:58 +00002745 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002746 {
2747 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2748 (*p)),q);
2749 p++;
2750 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2751 (*p)),q);
2752 p++;
2753 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2754 (*p)),q);
2755 p++;
2756 q+=GetPixelChannels(image);
2757 }
2758 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2759 break;
2760 }
2761 return;
2762 }
cristycafe0412012-01-10 13:29:58 +00002763 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002764 {
cristycafe0412012-01-10 13:29:58 +00002765 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002766 if (q == (Quantum *) NULL)
2767 break;
cristycafe0412012-01-10 13:29:58 +00002768 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002769 {
2770 register ssize_t
2771 i;
2772
2773 for (i=0; i < (ssize_t) strlen(map); i++)
2774 {
2775 switch (quantum_map[i])
2776 {
2777 case RedQuantum:
2778 case CyanQuantum:
2779 {
2780 SetPixelRed(image,ClampToQuantum((MagickRealType)
2781 QuantumRange*(*p)),q);
2782 break;
2783 }
2784 case GreenQuantum:
2785 case MagentaQuantum:
2786 {
2787 SetPixelGreen(image,ClampToQuantum((MagickRealType)
2788 QuantumRange*(*p)),q);
2789 break;
2790 }
2791 case BlueQuantum:
2792 case YellowQuantum:
2793 {
2794 SetPixelBlue(image,ClampToQuantum((MagickRealType)
2795 QuantumRange*(*p)),q);
2796 break;
2797 }
2798 case AlphaQuantum:
2799 {
2800 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2801 QuantumRange*(*p)),q);
2802 break;
2803 }
2804 case OpacityQuantum:
2805 {
2806 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2807 QuantumRange*(*p)),q);
2808 break;
2809 }
2810 case BlackQuantum:
2811 {
2812 SetPixelBlack(image,ClampToQuantum((MagickRealType)
2813 QuantumRange*(*p)),q);
2814 break;
2815 }
2816 case IndexQuantum:
2817 {
2818 SetPixelGray(image,ClampToQuantum((MagickRealType)
2819 QuantumRange*(*p)),q);
2820 break;
2821 }
2822 default:
2823 break;
2824 }
2825 p++;
2826 }
2827 q+=GetPixelChannels(image);
2828 }
2829 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2830 break;
2831 }
2832}
2833
cristycafe0412012-01-10 13:29:58 +00002834static void ImportLongPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00002835 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2836 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002837{
2838 register const unsigned int
2839 *restrict p;
2840
2841 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002842 *restrict q;
cristye5370942012-01-06 03:49:31 +00002843
2844 register ssize_t
2845 x;
2846
2847 ssize_t
2848 y;
2849
2850 p=(const unsigned int *) pixels;
2851 if (LocaleCompare(map,"BGR") == 0)
2852 {
cristycafe0412012-01-10 13:29:58 +00002853 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002854 {
cristycafe0412012-01-10 13:29:58 +00002855 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002856 if (q == (Quantum *) NULL)
2857 break;
cristycafe0412012-01-10 13:29:58 +00002858 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002859 {
2860 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2861 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2862 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2863 q+=GetPixelChannels(image);
2864 }
2865 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2866 break;
2867 }
2868 return;
2869 }
2870 if (LocaleCompare(map,"BGRA") == 0)
2871 {
cristycafe0412012-01-10 13:29:58 +00002872 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002873 {
cristycafe0412012-01-10 13:29:58 +00002874 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002875 if (q == (Quantum *) NULL)
2876 break;
cristycafe0412012-01-10 13:29:58 +00002877 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002878 {
2879 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2880 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2881 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2882 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
2883 q+=GetPixelChannels(image);
2884 }
2885 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2886 break;
2887 }
2888 return;
2889 }
2890 if (LocaleCompare(map,"BGRP") == 0)
2891 {
cristycafe0412012-01-10 13:29:58 +00002892 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002893 {
cristycafe0412012-01-10 13:29:58 +00002894 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002895 if (q == (Quantum *) NULL)
2896 break;
cristycafe0412012-01-10 13:29:58 +00002897 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002898 {
2899 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2900 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2901 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2902 p++;
2903 q+=GetPixelChannels(image);
2904 }
2905 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2906 break;
2907 }
2908 return;
2909 }
2910 if (LocaleCompare(map,"I") == 0)
2911 {
cristycafe0412012-01-10 13:29:58 +00002912 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002913 {
cristycafe0412012-01-10 13:29:58 +00002914 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002915 if (q == (Quantum *) NULL)
2916 break;
cristycafe0412012-01-10 13:29:58 +00002917 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002918 {
2919 SetPixelGray(image,ScaleLongToQuantum(*p++),q);
2920 q+=GetPixelChannels(image);
2921 }
2922 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2923 break;
2924 }
2925 return;
2926 }
2927 if (LocaleCompare(map,"RGB") == 0)
2928 {
cristycafe0412012-01-10 13:29:58 +00002929 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002930 {
cristycafe0412012-01-10 13:29:58 +00002931 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002932 if (q == (Quantum *) NULL)
2933 break;
cristycafe0412012-01-10 13:29:58 +00002934 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002935 {
2936 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2937 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2938 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2939 q+=GetPixelChannels(image);
2940 }
2941 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2942 break;
2943 }
2944 return;
2945 }
2946 if (LocaleCompare(map,"RGBA") == 0)
2947 {
cristycafe0412012-01-10 13:29:58 +00002948 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002949 {
cristycafe0412012-01-10 13:29:58 +00002950 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002951 if (q == (Quantum *) NULL)
2952 break;
cristycafe0412012-01-10 13:29:58 +00002953 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002954 {
2955 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2956 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2957 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2958 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
2959 q+=GetPixelChannels(image);
2960 }
2961 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2962 break;
2963 }
2964 return;
2965 }
2966 if (LocaleCompare(map,"RGBP") == 0)
2967 {
cristycafe0412012-01-10 13:29:58 +00002968 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002969 {
cristycafe0412012-01-10 13:29:58 +00002970 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002971 if (q == (Quantum *) NULL)
2972 break;
cristycafe0412012-01-10 13:29:58 +00002973 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002974 {
2975 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2976 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2977 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2978 p++;
2979 q+=GetPixelChannels(image);
2980 }
2981 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2982 break;
2983 }
2984 return;
2985 }
cristycafe0412012-01-10 13:29:58 +00002986 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002987 {
cristycafe0412012-01-10 13:29:58 +00002988 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002989 if (q == (Quantum *) NULL)
2990 break;
cristycafe0412012-01-10 13:29:58 +00002991 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002992 {
2993 register ssize_t
2994 i;
2995
2996 for (i=0; i < (ssize_t) strlen(map); i++)
2997 {
2998 switch (quantum_map[i])
2999 {
3000 case RedQuantum:
3001 case CyanQuantum:
3002 {
3003 SetPixelRed(image,ScaleLongToQuantum(*p),q);
3004 break;
3005 }
3006 case GreenQuantum:
3007 case MagentaQuantum:
3008 {
3009 SetPixelGreen(image,ScaleLongToQuantum(*p),q);
3010 break;
3011 }
3012 case BlueQuantum:
3013 case YellowQuantum:
3014 {
3015 SetPixelBlue(image,ScaleLongToQuantum(*p),q);
3016 break;
3017 }
3018 case AlphaQuantum:
3019 {
3020 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3021 break;
3022 }
3023 case OpacityQuantum:
3024 {
3025 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3026 break;
3027 }
3028 case BlackQuantum:
3029 {
3030 SetPixelBlack(image,ScaleLongToQuantum(*p),q);
3031 break;
3032 }
3033 case IndexQuantum:
3034 {
3035 SetPixelGray(image,ScaleLongToQuantum(*p),q);
3036 break;
3037 }
3038 default:
3039 break;
3040 }
3041 p++;
3042 }
3043 q+=GetPixelChannels(image);
3044 }
3045 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3046 break;
3047 }
3048}
3049
cristycafe0412012-01-10 13:29:58 +00003050static void ImportLongLongPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003051 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3052 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003053{
cristyb13e12a2012-01-06 21:48:27 +00003054 register const MagickSizeType
cristye5370942012-01-06 03:49:31 +00003055 *restrict p;
3056
3057 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003058 *restrict q;
cristye5370942012-01-06 03:49:31 +00003059
3060 register ssize_t
3061 x;
3062
3063 ssize_t
3064 y;
3065
cristyb13e12a2012-01-06 21:48:27 +00003066 p=(const MagickSizeType *) pixels;
cristye5370942012-01-06 03:49:31 +00003067 if (LocaleCompare(map,"BGR") == 0)
3068 {
cristycafe0412012-01-10 13:29:58 +00003069 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003070 {
cristycafe0412012-01-10 13:29:58 +00003071 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003072 if (q == (Quantum *) NULL)
3073 break;
cristycafe0412012-01-10 13:29:58 +00003074 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003075 {
cristyb13e12a2012-01-06 21:48:27 +00003076 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3077 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3078 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003079 q+=GetPixelChannels(image);
3080 }
3081 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3082 break;
3083 }
3084 return;
3085 }
3086 if (LocaleCompare(map,"BGRA") == 0)
3087 {
cristycafe0412012-01-10 13:29:58 +00003088 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003089 {
cristycafe0412012-01-10 13:29:58 +00003090 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003091 if (q == (Quantum *) NULL)
3092 break;
cristycafe0412012-01-10 13:29:58 +00003093 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003094 {
cristyb13e12a2012-01-06 21:48:27 +00003095 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3096 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3097 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3098 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003099 q+=GetPixelChannels(image);
3100 }
3101 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3102 break;
3103 }
3104 return;
3105 }
3106 if (LocaleCompare(map,"BGRP") == 0)
3107 {
cristycafe0412012-01-10 13:29:58 +00003108 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003109 {
cristycafe0412012-01-10 13:29:58 +00003110 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003111 if (q == (Quantum *) NULL)
3112 break;
cristycafe0412012-01-10 13:29:58 +00003113 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003114 {
cristyb13e12a2012-01-06 21:48:27 +00003115 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3116 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3117 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003118 p++;
3119 q+=GetPixelChannels(image);
3120 }
3121 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3122 break;
3123 }
3124 return;
3125 }
3126 if (LocaleCompare(map,"I") == 0)
3127 {
cristycafe0412012-01-10 13:29:58 +00003128 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003129 {
cristycafe0412012-01-10 13:29:58 +00003130 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003131 if (q == (Quantum *) NULL)
3132 break;
cristycafe0412012-01-10 13:29:58 +00003133 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003134 {
cristyb13e12a2012-01-06 21:48:27 +00003135 SetPixelGray(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003136 q+=GetPixelChannels(image);
3137 }
3138 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3139 break;
3140 }
3141 return;
3142 }
3143 if (LocaleCompare(map,"RGB") == 0)
3144 {
cristycafe0412012-01-10 13:29:58 +00003145 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003146 {
cristycafe0412012-01-10 13:29:58 +00003147 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003148 if (q == (Quantum *) NULL)
3149 break;
cristycafe0412012-01-10 13:29:58 +00003150 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003151 {
cristyb13e12a2012-01-06 21:48:27 +00003152 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3153 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3154 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003155 q+=GetPixelChannels(image);
3156 }
3157 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3158 break;
3159 }
3160 return;
3161 }
3162 if (LocaleCompare(map,"RGBA") == 0)
3163 {
cristycafe0412012-01-10 13:29:58 +00003164 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003165 {
cristycafe0412012-01-10 13:29:58 +00003166 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003167 if (q == (Quantum *) NULL)
3168 break;
cristycafe0412012-01-10 13:29:58 +00003169 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003170 {
cristyb13e12a2012-01-06 21:48:27 +00003171 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3172 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3173 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3174 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003175 q+=GetPixelChannels(image);
3176 }
3177 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3178 break;
3179 }
3180 return;
3181 }
3182 if (LocaleCompare(map,"RGBP") == 0)
3183 {
cristycafe0412012-01-10 13:29:58 +00003184 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003185 {
cristycafe0412012-01-10 13:29:58 +00003186 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003187 if (q == (Quantum *) NULL)
3188 break;
cristycafe0412012-01-10 13:29:58 +00003189 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003190 {
cristyb13e12a2012-01-06 21:48:27 +00003191 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3192 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3193 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003194 p++;
3195 q+=GetPixelChannels(image);
3196 }
3197 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3198 break;
3199 }
3200 return;
3201 }
cristycafe0412012-01-10 13:29:58 +00003202 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003203 {
cristycafe0412012-01-10 13:29:58 +00003204 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003205 if (q == (Quantum *) NULL)
3206 break;
cristycafe0412012-01-10 13:29:58 +00003207 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003208 {
3209 register ssize_t
3210 i;
3211
3212 for (i=0; i < (ssize_t) strlen(map); i++)
3213 {
3214 switch (quantum_map[i])
3215 {
3216 case RedQuantum:
3217 case CyanQuantum:
3218 {
cristyb13e12a2012-01-06 21:48:27 +00003219 SetPixelRed(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003220 break;
3221 }
3222 case GreenQuantum:
3223 case MagentaQuantum:
3224 {
cristyb13e12a2012-01-06 21:48:27 +00003225 SetPixelGreen(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003226 break;
3227 }
3228 case BlueQuantum:
3229 case YellowQuantum:
3230 {
cristyb13e12a2012-01-06 21:48:27 +00003231 SetPixelBlue(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003232 break;
3233 }
3234 case AlphaQuantum:
3235 {
cristyb13e12a2012-01-06 21:48:27 +00003236 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003237 break;
3238 }
3239 case OpacityQuantum:
3240 {
cristyb13e12a2012-01-06 21:48:27 +00003241 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003242 break;
3243 }
3244 case BlackQuantum:
3245 {
cristyb13e12a2012-01-06 21:48:27 +00003246 SetPixelBlack(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003247 break;
3248 }
3249 case IndexQuantum:
3250 {
cristyb13e12a2012-01-06 21:48:27 +00003251 SetPixelGray(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003252 break;
3253 }
3254 default:
3255 break;
3256 }
3257 p++;
3258 }
3259 q+=GetPixelChannels(image);
3260 }
3261 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3262 break;
3263 }
3264}
3265
cristycafe0412012-01-10 13:29:58 +00003266static void ImportQuantumPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003267 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3268 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003269{
3270 register const Quantum
3271 *restrict p;
3272
3273 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003274 *restrict q;
cristye5370942012-01-06 03:49:31 +00003275
3276 register ssize_t
3277 x;
3278
3279 ssize_t
3280 y;
3281
3282 p=(const Quantum *) pixels;
3283 if (LocaleCompare(map,"BGR") == 0)
3284 {
cristycafe0412012-01-10 13:29:58 +00003285 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003286 {
cristycafe0412012-01-10 13:29:58 +00003287 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003288 if (q == (Quantum *) NULL)
3289 break;
cristycafe0412012-01-10 13:29:58 +00003290 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003291 {
3292 SetPixelBlue(image,*p++,q);
3293 SetPixelGreen(image,*p++,q);
3294 SetPixelRed(image,*p++,q);
3295 q+=GetPixelChannels(image);
3296 }
3297 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3298 break;
3299 }
3300 return;
3301 }
3302 if (LocaleCompare(map,"BGRA") == 0)
3303 {
cristycafe0412012-01-10 13:29:58 +00003304 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003305 {
cristycafe0412012-01-10 13:29:58 +00003306 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003307 if (q == (Quantum *) NULL)
3308 break;
cristycafe0412012-01-10 13:29:58 +00003309 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003310 {
3311 SetPixelBlue(image,*p++,q);
3312 SetPixelGreen(image,*p++,q);
3313 SetPixelRed(image,*p++,q);
3314 SetPixelAlpha(image,*p++,q);
3315 q+=GetPixelChannels(image);
3316 }
3317 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3318 break;
3319 }
3320 return;
3321 }
3322 if (LocaleCompare(map,"BGRP") == 0)
3323 {
cristycafe0412012-01-10 13:29:58 +00003324 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003325 {
cristycafe0412012-01-10 13:29:58 +00003326 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003327 if (q == (Quantum *) NULL)
3328 break;
cristycafe0412012-01-10 13:29:58 +00003329 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003330 {
3331 SetPixelBlue(image,*p++,q);
3332 SetPixelGreen(image,*p++,q);
3333 SetPixelRed(image,*p++,q);
3334 p++;
3335 q+=GetPixelChannels(image);
3336 }
3337 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3338 break;
3339 }
3340 return;
3341 }
3342 if (LocaleCompare(map,"I") == 0)
3343 {
cristycafe0412012-01-10 13:29:58 +00003344 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003345 {
cristycafe0412012-01-10 13:29:58 +00003346 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003347 if (q == (Quantum *) NULL)
3348 break;
cristycafe0412012-01-10 13:29:58 +00003349 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003350 {
3351 SetPixelGray(image,*p++,q);
3352 q+=GetPixelChannels(image);
3353 }
3354 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3355 break;
3356 }
3357 return;
3358 }
3359 if (LocaleCompare(map,"RGB") == 0)
3360 {
cristycafe0412012-01-10 13:29:58 +00003361 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003362 {
cristycafe0412012-01-10 13:29:58 +00003363 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003364 if (q == (Quantum *) NULL)
3365 break;
cristycafe0412012-01-10 13:29:58 +00003366 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003367 {
3368 SetPixelRed(image,*p++,q);
3369 SetPixelGreen(image,*p++,q);
3370 SetPixelBlue(image,*p++,q);
3371 q+=GetPixelChannels(image);
3372 }
3373 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3374 break;
3375 }
3376 return;
3377 }
3378 if (LocaleCompare(map,"RGBA") == 0)
3379 {
cristycafe0412012-01-10 13:29:58 +00003380 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003381 {
cristycafe0412012-01-10 13:29:58 +00003382 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003383 if (q == (Quantum *) NULL)
3384 break;
cristycafe0412012-01-10 13:29:58 +00003385 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003386 {
3387 SetPixelRed(image,*p++,q);
3388 SetPixelGreen(image,*p++,q);
3389 SetPixelBlue(image,*p++,q);
3390 SetPixelAlpha(image,*p++,q);
3391 q+=GetPixelChannels(image);
3392 }
3393 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3394 break;
3395 }
3396 return;
3397 }
3398 if (LocaleCompare(map,"RGBP") == 0)
3399 {
cristycafe0412012-01-10 13:29:58 +00003400 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003401 {
cristycafe0412012-01-10 13:29:58 +00003402 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003403 if (q == (Quantum *) NULL)
3404 break;
cristycafe0412012-01-10 13:29:58 +00003405 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003406 {
3407 SetPixelRed(image,*p++,q);
3408 SetPixelGreen(image,*p++,q);
3409 SetPixelBlue(image,*p++,q);
3410 p++;
3411 q+=GetPixelChannels(image);
3412 }
3413 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3414 break;
3415 }
3416 return;
3417 }
cristycafe0412012-01-10 13:29:58 +00003418 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003419 {
cristycafe0412012-01-10 13:29:58 +00003420 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003421 if (q == (Quantum *) NULL)
3422 break;
cristycafe0412012-01-10 13:29:58 +00003423 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003424 {
3425 register ssize_t
3426 i;
3427
3428 for (i=0; i < (ssize_t) strlen(map); i++)
3429 {
3430 switch (quantum_map[i])
3431 {
3432 case RedQuantum:
3433 case CyanQuantum:
3434 {
3435 SetPixelRed(image,*p,q);
3436 break;
3437 }
3438 case GreenQuantum:
3439 case MagentaQuantum:
3440 {
3441 SetPixelGreen(image,*p,q);
3442 break;
3443 }
3444 case BlueQuantum:
3445 case YellowQuantum:
3446 {
3447 SetPixelBlue(image,*p,q);
3448 break;
3449 }
3450 case AlphaQuantum:
3451 {
3452 SetPixelAlpha(image,*p,q);
3453 break;
3454 }
3455 case OpacityQuantum:
3456 {
3457 SetPixelAlpha(image,*p,q);
3458 break;
3459 }
3460 case BlackQuantum:
3461 {
3462 SetPixelBlack(image,*p,q);
3463 break;
3464 }
3465 case IndexQuantum:
3466 {
3467 SetPixelGray(image,*p,q);
3468 break;
3469 }
3470 default:
3471 break;
3472 }
3473 p++;
3474 }
3475 q+=GetPixelChannels(image);
3476 }
3477 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3478 break;
3479 }
3480}
3481
cristycafe0412012-01-10 13:29:58 +00003482static void ImportShortPixel(Image *image,const RectangleInfo *roi,
cristy46f4be22012-01-07 00:26:39 +00003483 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3484 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003485{
3486 register const unsigned short
3487 *restrict p;
3488
3489 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003490 *restrict q;
cristye5370942012-01-06 03:49:31 +00003491
3492 register ssize_t
3493 x;
3494
3495 ssize_t
3496 y;
3497
3498 p=(const unsigned short *) pixels;
3499 if (LocaleCompare(map,"BGR") == 0)
3500 {
cristycafe0412012-01-10 13:29:58 +00003501 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003502 {
cristycafe0412012-01-10 13:29:58 +00003503 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003504 if (q == (Quantum *) NULL)
3505 break;
cristycafe0412012-01-10 13:29:58 +00003506 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003507 {
3508 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3509 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3510 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3511 q+=GetPixelChannels(image);
3512 }
3513 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3514 break;
3515 }
3516 return;
3517 }
3518 if (LocaleCompare(map,"BGRA") == 0)
3519 {
cristycafe0412012-01-10 13:29:58 +00003520 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003521 {
cristycafe0412012-01-10 13:29:58 +00003522 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003523 if (q == (Quantum *) NULL)
3524 break;
cristycafe0412012-01-10 13:29:58 +00003525 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003526 {
3527 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3528 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3529 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3530 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3531 q+=GetPixelChannels(image);
3532 }
3533 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3534 break;
3535 }
3536 return;
3537 }
3538 if (LocaleCompare(map,"BGRP") == 0)
3539 {
cristycafe0412012-01-10 13:29:58 +00003540 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003541 {
cristycafe0412012-01-10 13:29:58 +00003542 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003543 if (q == (Quantum *) NULL)
3544 break;
cristycafe0412012-01-10 13:29:58 +00003545 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003546 {
3547 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3548 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3549 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3550 p++;
3551 q+=GetPixelChannels(image);
3552 }
3553 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3554 break;
3555 }
3556 return;
3557 }
3558 if (LocaleCompare(map,"I") == 0)
3559 {
cristycafe0412012-01-10 13:29:58 +00003560 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003561 {
cristycafe0412012-01-10 13:29:58 +00003562 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003563 if (q == (Quantum *) NULL)
3564 break;
cristycafe0412012-01-10 13:29:58 +00003565 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003566 {
3567 SetPixelGray(image,ScaleShortToQuantum(*p++),q);
3568 q+=GetPixelChannels(image);
3569 }
3570 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3571 break;
3572 }
3573 return;
3574 }
3575 if (LocaleCompare(map,"RGB") == 0)
3576 {
cristycafe0412012-01-10 13:29:58 +00003577 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003578 {
cristycafe0412012-01-10 13:29:58 +00003579 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003580 if (q == (Quantum *) NULL)
3581 break;
cristycafe0412012-01-10 13:29:58 +00003582 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003583 {
3584 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3585 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3586 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3587 q+=GetPixelChannels(image);
3588 }
3589 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3590 break;
3591 }
3592 return;
3593 }
3594 if (LocaleCompare(map,"RGBA") == 0)
3595 {
cristycafe0412012-01-10 13:29:58 +00003596 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003597 {
cristycafe0412012-01-10 13:29:58 +00003598 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003599 if (q == (Quantum *) NULL)
3600 break;
cristycafe0412012-01-10 13:29:58 +00003601 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003602 {
3603 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3604 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3605 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3606 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3607 q+=GetPixelChannels(image);
3608 }
3609 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3610 break;
3611 }
3612 return;
3613 }
3614 if (LocaleCompare(map,"RGBP") == 0)
3615 {
cristycafe0412012-01-10 13:29:58 +00003616 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003617 {
cristycafe0412012-01-10 13:29:58 +00003618 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003619 if (q == (Quantum *) NULL)
3620 break;
cristycafe0412012-01-10 13:29:58 +00003621 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003622 {
3623 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3624 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3625 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3626 p++;
3627 q+=GetPixelChannels(image);
3628 }
3629 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3630 break;
3631 }
3632 return;
3633 }
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 register ssize_t
3642 i;
3643
3644 for (i=0; i < (ssize_t) strlen(map); i++)
3645 {
3646 switch (quantum_map[i])
3647 {
3648 case RedQuantum:
3649 case CyanQuantum:
3650 {
3651 SetPixelRed(image,ScaleShortToQuantum(*p),q);
3652 break;
3653 }
3654 case GreenQuantum:
3655 case MagentaQuantum:
3656 {
3657 SetPixelGreen(image,ScaleShortToQuantum(*p),q);
3658 break;
3659 }
3660 case BlueQuantum:
3661 case YellowQuantum:
3662 {
3663 SetPixelBlue(image,ScaleShortToQuantum(*p),q);
3664 break;
3665 }
3666 case AlphaQuantum:
3667 {
3668 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
3669 break;
3670 }
3671 case OpacityQuantum:
3672 {
3673 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
3674 break;
3675 }
3676 case BlackQuantum:
3677 {
3678 SetPixelBlack(image,ScaleShortToQuantum(*p),q);
3679 break;
3680 }
3681 case IndexQuantum:
3682 {
3683 SetPixelGray(image,ScaleShortToQuantum(*p),q);
3684 break;
3685 }
3686 default:
3687 break;
3688 }
3689 p++;
3690 }
3691 q+=GetPixelChannels(image);
3692 }
3693 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3694 break;
3695 }
3696}
3697
cristycafe0412012-01-10 13:29:58 +00003698MagickExport MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
3699 const ssize_t y,const size_t width,const size_t height,const char *map,
3700 const StorageType type,const void *pixels,ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00003701{
cristy4c08aed2011-07-01 19:47:50 +00003702 QuantumType
3703 *quantum_map;
3704
cristycafe0412012-01-10 13:29:58 +00003705 RectangleInfo
3706 roi;
3707
cristy4c08aed2011-07-01 19:47:50 +00003708 register ssize_t
cristye5370942012-01-06 03:49:31 +00003709 i;
cristy4c08aed2011-07-01 19:47:50 +00003710
3711 /*
3712 Allocate image structure.
3713 */
3714 assert(image != (Image *) NULL);
3715 assert(image->signature == MagickSignature);
3716 if (image->debug != MagickFalse)
3717 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristye5370942012-01-06 03:49:31 +00003718 quantum_map=(QuantumType *) AcquireQuantumMemory(strlen(map),
3719 sizeof(*quantum_map));
cristy4c08aed2011-07-01 19:47:50 +00003720 if (quantum_map == (QuantumType *) NULL)
3721 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
3722 image->filename);
cristye5370942012-01-06 03:49:31 +00003723 for (i=0; i < (ssize_t) strlen(map); i++)
cristy4c08aed2011-07-01 19:47:50 +00003724 {
3725 switch (map[i])
3726 {
3727 case 'a':
3728 case 'A':
3729 {
3730 quantum_map[i]=AlphaQuantum;
3731 image->matte=MagickTrue;
3732 break;
3733 }
3734 case 'B':
3735 case 'b':
3736 {
3737 quantum_map[i]=BlueQuantum;
3738 break;
3739 }
3740 case 'C':
3741 case 'c':
3742 {
3743 quantum_map[i]=CyanQuantum;
cristy63240882011-08-05 19:05:27 +00003744 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003745 break;
3746 }
3747 case 'g':
3748 case 'G':
3749 {
3750 quantum_map[i]=GreenQuantum;
3751 break;
3752 }
3753 case 'K':
3754 case 'k':
3755 {
3756 quantum_map[i]=BlackQuantum;
cristy63240882011-08-05 19:05:27 +00003757 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003758 break;
3759 }
3760 case 'I':
3761 case 'i':
3762 {
3763 quantum_map[i]=IndexQuantum;
3764 break;
3765 }
3766 case 'm':
3767 case 'M':
3768 {
3769 quantum_map[i]=MagentaQuantum;
cristy63240882011-08-05 19:05:27 +00003770 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003771 break;
3772 }
3773 case 'O':
3774 case 'o':
3775 {
3776 quantum_map[i]=OpacityQuantum;
3777 image->matte=MagickTrue;
3778 break;
3779 }
3780 case 'P':
3781 case 'p':
3782 {
3783 quantum_map[i]=UndefinedQuantum;
3784 break;
3785 }
3786 case 'R':
3787 case 'r':
3788 {
3789 quantum_map[i]=RedQuantum;
3790 break;
3791 }
3792 case 'Y':
3793 case 'y':
3794 {
3795 quantum_map[i]=YellowQuantum;
cristy63240882011-08-05 19:05:27 +00003796 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003797 break;
3798 }
3799 default:
3800 {
3801 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
cristy63240882011-08-05 19:05:27 +00003802 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
3803 "UnrecognizedPixelMap","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00003804 return(MagickFalse);
3805 }
3806 }
3807 }
cristy63240882011-08-05 19:05:27 +00003808 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
cristy4c08aed2011-07-01 19:47:50 +00003809 return(MagickFalse);
3810 /*
cristye5370942012-01-06 03:49:31 +00003811 Transfer the pixels from the pixel data to the image.
cristy4c08aed2011-07-01 19:47:50 +00003812 */
cristycafe0412012-01-10 13:29:58 +00003813 roi.width=width;
3814 roi.height=height;
3815 roi.x=x;
3816 roi.y=y;
cristy4c08aed2011-07-01 19:47:50 +00003817 switch (type)
3818 {
3819 case CharPixel:
3820 {
cristycafe0412012-01-10 13:29:58 +00003821 ImportCharPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003822 break;
3823 }
3824 case DoublePixel:
3825 {
cristycafe0412012-01-10 13:29:58 +00003826 ImportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003827 break;
3828 }
3829 case FloatPixel:
3830 {
cristycafe0412012-01-10 13:29:58 +00003831 ImportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003832 break;
3833 }
cristy4c08aed2011-07-01 19:47:50 +00003834 case LongPixel:
3835 {
cristycafe0412012-01-10 13:29:58 +00003836 ImportLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003837 break;
3838 }
cristy6c9e1682012-01-07 21:37:44 +00003839 case LongLongPixel:
3840 {
cristycafe0412012-01-10 13:29:58 +00003841 ImportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy6c9e1682012-01-07 21:37:44 +00003842 break;
3843 }
cristy4c08aed2011-07-01 19:47:50 +00003844 case QuantumPixel:
3845 {
cristycafe0412012-01-10 13:29:58 +00003846 ImportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003847 break;
3848 }
3849 case ShortPixel:
3850 {
cristycafe0412012-01-10 13:29:58 +00003851 ImportShortPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003852 break;
3853 }
3854 default:
3855 {
3856 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
cristyc82a27b2011-10-21 01:07:16 +00003857 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
3858 "UnrecognizedPixelMap","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00003859 break;
3860 }
3861 }
3862 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
3863 return(MagickTrue);
3864}
3865
3866/*
3867%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3868% %
3869% %
3870% %
cristybd5a96c2011-08-21 00:04:26 +00003871+ 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 %
3872% %
3873% %
3874% %
3875%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3876%
3877% InitializePixelChannelMap() defines the standard pixel component map.
3878%
3879% The format of the InitializePixelChannelMap() method is:
3880%
3881% void InitializePixelChannelMap(Image *image)
3882%
3883% A description of each parameter follows:
3884%
3885% o image: the image.
3886%
3887*/
cristye2a912b2011-12-05 20:02:07 +00003888MagickExport void InitializePixelChannelMap(Image *image)
cristy77c30f52011-10-24 18:56:57 +00003889{
cristye2a912b2011-12-05 20:02:07 +00003890 PixelTrait
3891 trait;
3892
cristy77c30f52011-10-24 18:56:57 +00003893 register ssize_t
3894 i;
3895
cristyd26338f2011-12-14 02:39:30 +00003896 ssize_t
cristy77c30f52011-10-24 18:56:57 +00003897 n;
3898
3899 assert(image != (Image *) NULL);
3900 assert(image->signature == MagickSignature);
cristye2a912b2011-12-05 20:02:07 +00003901 (void) ResetMagickMemory(image->channel_map,0,MaxPixelChannels*
3902 sizeof(*image->channel_map));
3903 trait=UpdatePixelTrait;
3904 if (image->matte != MagickFalse)
cristy61f18ad2011-12-08 21:12:37 +00003905 trait=(PixelTrait) (trait | BlendPixelTrait);
cristy77c30f52011-10-24 18:56:57 +00003906 n=0;
cristyc06c5802011-12-31 23:36:16 +00003907 if (image->colorspace == GRAYColorspace)
cristy77c30f52011-10-24 18:56:57 +00003908 {
cristy3c316282011-12-15 15:43:24 +00003909 SetPixelChannelMap(image,BluePixelChannel,trait,n);
cristye2a912b2011-12-05 20:02:07 +00003910 SetPixelChannelMap(image,GreenPixelChannel,trait,n);
cristy3c316282011-12-15 15:43:24 +00003911 SetPixelChannelMap(image,RedPixelChannel,trait,n++);
3912 }
3913 else
3914 {
3915 SetPixelChannelMap(image,RedPixelChannel,trait,n++);
3916 SetPixelChannelMap(image,GreenPixelChannel,trait,n++);
cristye2a912b2011-12-05 20:02:07 +00003917 SetPixelChannelMap(image,BluePixelChannel,trait,n++);
cristy77c30f52011-10-24 18:56:57 +00003918 }
3919 if (image->colorspace == CMYKColorspace)
cristye2a912b2011-12-05 20:02:07 +00003920 SetPixelChannelMap(image,BlackPixelChannel,trait,n++);
cristy77c30f52011-10-24 18:56:57 +00003921 if (image->matte != MagickFalse)
cristye2a912b2011-12-05 20:02:07 +00003922 SetPixelChannelMap(image,AlphaPixelChannel,CopyPixelTrait,n++);
3923 if (image->storage_class == PseudoClass)
3924 SetPixelChannelMap(image,IndexPixelChannel,CopyPixelTrait,n++);
cristy183a5c72012-01-30 01:40:35 +00003925 if (image->mask != MagickFalse)
cristy10a6c612012-01-29 21:41:05 +00003926 SetPixelChannelMap(image,MaskPixelChannel,CopyPixelTrait,n++);
cristye2a912b2011-12-05 20:02:07 +00003927 assert((n+image->number_meta_channels) < MaxPixelChannels);
3928 for (i=0; i < (ssize_t) image->number_meta_channels; i++)
cristy61f18ad2011-12-08 21:12:37 +00003929 SetPixelChannelMap(image,(PixelChannel) (MetaPixelChannel+i),CopyPixelTrait,
cristye2a912b2011-12-05 20:02:07 +00003930 n++);
cristyd26338f2011-12-14 02:39:30 +00003931 image->number_channels=(size_t) n;
cristy77c30f52011-10-24 18:56:57 +00003932 if (image->debug != MagickFalse)
3933 LogPixelChannels(image);
3934 (void) SetPixelChannelMask(image,image->channel_mask);
3935}
cristybd5a96c2011-08-21 00:04:26 +00003936
3937/*
3938%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3939% %
3940% %
3941% %
cristya085a432011-07-30 01:39:32 +00003942% I n t e r p o l a t e P i x e l C h a n n e l %
3943% %
3944% %
3945% %
3946%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3947%
cristy884f6002011-07-31 00:51:45 +00003948% InterpolatePixelChannel() applies a pixel interpolation method between a
3949% floating point coordinate and the pixels surrounding that coordinate. No
3950% pixel area resampling, or scaling of the result is performed.
cristya085a432011-07-30 01:39:32 +00003951%
3952% The format of the InterpolatePixelChannel method is:
3953%
3954% MagickBooleanType InterpolatePixelChannel(const Image *image,
cristy444eda62011-08-10 02:07:46 +00003955% const CacheView *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00003956% const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00003957% double *pixel,ExceptionInfo *exception)
3958%
3959% A description of each parameter follows:
3960%
3961% o image: the image.
3962%
3963% o image_view: the image view.
3964%
3965% o channel: the pixel channel to interpolate.
3966%
3967% o method: the pixel color interpolation method.
3968%
3969% o x,y: A double representing the current (x,y) position of the pixel.
3970%
3971% o pixel: return the interpolated pixel here.
3972%
3973% o exception: return any errors or warnings in this structure.
3974%
3975*/
cristy94ea1632011-07-30 20:40:25 +00003976
cristy884f6002011-07-31 00:51:45 +00003977static inline double MagickMax(const MagickRealType x,const MagickRealType y)
3978{
3979 if (x > y)
3980 return(x);
3981 return(y);
3982}
3983
3984static inline MagickRealType CubicWeightingFunction(const MagickRealType x)
3985{
3986 MagickRealType
3987 alpha,
3988 gamma;
3989
3990 alpha=MagickMax(x+2.0,0.0);
3991 gamma=1.0*alpha*alpha*alpha;
3992 alpha=MagickMax(x+1.0,0.0);
3993 gamma-=4.0*alpha*alpha*alpha;
3994 alpha=MagickMax(x+0.0,0.0);
3995 gamma+=6.0*alpha*alpha*alpha;
3996 alpha=MagickMax(x-1.0,0.0);
3997 gamma-=4.0*alpha*alpha*alpha;
3998 return(gamma/6.0);
3999}
4000
cristy94ea1632011-07-30 20:40:25 +00004001static inline double MeshInterpolate(const PointInfo *delta,const double p,
4002 const double x,const double y)
4003{
4004 return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p);
4005}
4006
cristy884f6002011-07-31 00:51:45 +00004007static inline ssize_t NearestNeighbor(const MagickRealType x)
4008{
4009 if (x >= 0.0)
4010 return((ssize_t) (x+0.5));
4011 return((ssize_t) (x-0.5));
4012}
4013
cristya085a432011-07-30 01:39:32 +00004014MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
4015 const CacheView *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00004016 const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00004017 double *pixel,ExceptionInfo *exception)
4018{
4019 MagickBooleanType
4020 status;
4021
cristy94ea1632011-07-30 20:40:25 +00004022 MagickRealType
4023 alpha[16],
cristy884f6002011-07-31 00:51:45 +00004024 gamma,
4025 pixels[16];
cristy94ea1632011-07-30 20:40:25 +00004026
4027 PixelTrait
4028 traits;
4029
cristy94ea1632011-07-30 20:40:25 +00004030 register const Quantum
4031 *p;
4032
4033 register ssize_t
4034 i;
4035
cristya085a432011-07-30 01:39:32 +00004036 ssize_t
4037 x_offset,
4038 y_offset;
4039
4040 assert(image != (Image *) NULL);
4041 assert(image != (Image *) NULL);
4042 assert(image->signature == MagickSignature);
4043 assert(image_view != (CacheView *) NULL);
4044 status=MagickTrue;
cristy884f6002011-07-31 00:51:45 +00004045 *pixel=0.0;
cristy94ea1632011-07-30 20:40:25 +00004046 traits=GetPixelChannelMapTraits(image,channel);
cristya085a432011-07-30 01:39:32 +00004047 x_offset=(ssize_t) floor(x);
4048 y_offset=(ssize_t) floor(y);
4049 switch (method == UndefinedInterpolatePixel ? image->interpolate : method)
4050 {
cristy884f6002011-07-31 00:51:45 +00004051 case AverageInterpolatePixel:
4052 {
4053 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4054 exception);
4055 if (p == (const Quantum *) NULL)
4056 {
4057 status=MagickFalse;
4058 break;
4059 }
cristy222b19c2011-08-04 01:35:11 +00004060 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004061 for (i=0; i < 16; i++)
4062 {
4063 alpha[i]=1.0;
4064 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4065 }
4066 else
4067 for (i=0; i < 16; i++)
4068 {
4069 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4070 GetPixelChannels(image));
4071 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4072 }
4073 for (i=0; i < 16; i++)
4074 {
4075 gamma=1.0/(fabs((double) alpha[i]) <= MagickEpsilon ? 1.0 : alpha[i]);
4076 *pixel+=gamma*0.0625*pixels[i];
4077 }
4078 break;
4079 }
4080 case BicubicInterpolatePixel:
4081 {
4082 MagickRealType
4083 u[4],
4084 v[4];
4085
4086 PointInfo
4087 delta;
4088
4089 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4090 exception);
4091 if (p == (const Quantum *) NULL)
4092 {
4093 status=MagickFalse;
4094 break;
4095 }
cristy222b19c2011-08-04 01:35:11 +00004096 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004097 for (i=0; i < 16; i++)
4098 {
4099 alpha[i]=1.0;
4100 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4101 }
4102 else
4103 for (i=0; i < 16; i++)
4104 {
4105 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4106 GetPixelChannels(image));
4107 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4108 }
4109 delta.x=x-x_offset;
4110 delta.y=y-y_offset;
4111 for (i=0; i < 4; i++)
4112 {
4113 u[0]=(pixels[4*i+3]-pixels[4*i+2])-(pixels[4*i+0]-pixels[4*i+1]);
4114 u[1]=(pixels[4*i+0]-pixels[4*i+1])-u[0];
4115 u[2]=pixels[4*i+2]-pixels[4*i+0];
4116 u[3]=pixels[4*i+1];
4117 v[i]=(delta.x*delta.x*delta.x*u[0])+(delta.x*delta.x*u[1])+(delta.x*
4118 u[2])+u[3];
4119 }
4120 u[0]=(v[3]-v[2])-(v[0]-v[1]);
4121 u[1]=(v[0]-v[1])-u[0];
4122 u[2]=v[2]-v[0];
4123 u[3]=v[1];
4124 *pixel=(delta.y*delta.y*delta.y*u[0])+(delta.y*delta.y*u[1])+(delta.y*
4125 u[2])+u[3];
4126 break;
4127 }
4128 case BilinearInterpolatePixel:
cristy94ea1632011-07-30 20:40:25 +00004129 default:
cristya085a432011-07-30 01:39:32 +00004130 {
cristy94ea1632011-07-30 20:40:25 +00004131 PointInfo
4132 delta,
cristy884f6002011-07-31 00:51:45 +00004133 epsilon;
4134
4135 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4136 if (p == (const Quantum *) NULL)
4137 {
4138 status=MagickFalse;
4139 break;
4140 }
cristy222b19c2011-08-04 01:35:11 +00004141 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004142 for (i=0; i < 4; i++)
4143 {
4144 alpha[i]=1.0;
4145 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4146 }
4147 else
4148 for (i=0; i < 4; i++)
4149 {
4150 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4151 GetPixelChannels(image));
4152 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4153 }
4154 delta.x=x-x_offset;
4155 delta.y=y-y_offset;
4156 epsilon.x=1.0-delta.x;
4157 epsilon.y=1.0-delta.y;
4158 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4159 (epsilon.x*alpha[2]+delta.x*alpha[3])));
4160 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4161 *pixel=gamma*(epsilon.y*(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*
4162 (epsilon.x*pixels[2]+delta.x*pixels[3]));
4163 break;
4164 }
4165 case FilterInterpolatePixel:
4166 {
4167 CacheView
4168 *filter_view;
4169
4170 Image
4171 *excerpt_image,
4172 *filter_image;
4173
4174 RectangleInfo
4175 geometry;
4176
4177 geometry.width=4L;
4178 geometry.height=4L;
4179 geometry.x=x_offset-1;
4180 geometry.y=y_offset-1;
4181 excerpt_image=ExcerptImage(image,&geometry,exception);
4182 if (excerpt_image == (Image *) NULL)
4183 {
4184 status=MagickFalse;
4185 break;
4186 }
4187 filter_image=ResizeImage(excerpt_image,1,1,image->filter,image->blur,
4188 exception);
4189 excerpt_image=DestroyImage(excerpt_image);
4190 if (filter_image == (Image *) NULL)
4191 break;
4192 filter_view=AcquireCacheView(filter_image);
4193 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4194 if (p == (const Quantum *) NULL)
4195 status=MagickFalse;
4196 else
cristy0beccfa2011-09-25 20:47:53 +00004197 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004198 filter_view=DestroyCacheView(filter_view);
4199 filter_image=DestroyImage(filter_image);
4200 break;
4201 }
4202 case IntegerInterpolatePixel:
4203 {
4204 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
4205 if (p == (const Quantum *) NULL)
4206 {
4207 status=MagickFalse;
4208 break;
4209 }
cristy0beccfa2011-09-25 20:47:53 +00004210 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004211 break;
4212 }
4213 case NearestNeighborInterpolatePixel:
4214 {
4215 p=GetCacheViewVirtualPixels(image_view,NearestNeighbor(x),
4216 NearestNeighbor(y),1,1,exception);
4217 if (p == (const Quantum *) NULL)
4218 {
4219 status=MagickFalse;
4220 break;
4221 }
cristy0beccfa2011-09-25 20:47:53 +00004222 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004223 break;
4224 }
4225 case MeshInterpolatePixel:
4226 {
4227 PointInfo
4228 delta,
cristy94ea1632011-07-30 20:40:25 +00004229 luminance;
4230
4231 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4232 if (p == (const Quantum *) NULL)
4233 {
4234 status=MagickFalse;
4235 break;
4236 }
cristy222b19c2011-08-04 01:35:11 +00004237 if ((traits & BlendPixelTrait) == 0)
cristy94ea1632011-07-30 20:40:25 +00004238 for (i=0; i < 4; i++)
4239 {
4240 alpha[i]=1.0;
cristy884f6002011-07-31 00:51:45 +00004241 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
cristy94ea1632011-07-30 20:40:25 +00004242 }
4243 else
4244 for (i=0; i < 4; i++)
4245 {
4246 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4247 GetPixelChannels(image));
4248 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4249 }
cristy884f6002011-07-31 00:51:45 +00004250 delta.x=x-x_offset;
4251 delta.y=y-y_offset;
4252 luminance.x=GetPixelLuminance(image,p)-(double)
4253 GetPixelLuminance(image,p+3*GetPixelChannels(image));
cristy28474bf2011-09-11 23:32:52 +00004254 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
cristy884f6002011-07-31 00:51:45 +00004255 GetPixelLuminance(image,p+2*GetPixelChannels(image));
cristy94ea1632011-07-30 20:40:25 +00004256 if (fabs(luminance.x) < fabs(luminance.y))
4257 {
4258 /*
4259 Diagonal 0-3 NW-SE.
4260 */
4261 if (delta.x <= delta.y)
4262 {
4263 /*
4264 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4265 */
4266 delta.y=1.0-delta.y;
4267 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
4268 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4269 *pixel=gamma*MeshInterpolate(&delta,pixels[2],pixels[3],
4270 pixels[0]);
4271 }
4272 else
4273 {
4274 /*
4275 Top-right triangle (pixel: 1, diagonal: 0-3).
4276 */
4277 delta.x=1.0-delta.x;
4278 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
4279 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4280 *pixel=gamma*MeshInterpolate(&delta,pixels[1],pixels[0],
4281 pixels[3]);
4282 }
4283 }
4284 else
4285 {
4286 /*
4287 Diagonal 1-2 NE-SW.
4288 */
4289 if (delta.x <= (1.0-delta.y))
4290 {
4291 /*
4292 Top-left triangle (pixel: 0, diagonal: 1-2).
4293 */
4294 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
4295 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4296 *pixel=gamma*MeshInterpolate(&delta,pixels[0],pixels[1],
4297 pixels[2]);
4298 }
4299 else
4300 {
4301 /*
4302 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4303 */
4304 delta.x=1.0-delta.x;
4305 delta.y=1.0-delta.y;
4306 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
4307 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4308 *pixel=gamma*MeshInterpolate(&delta,pixels[3],pixels[2],
4309 pixels[1]);
4310 }
4311 }
cristya085a432011-07-30 01:39:32 +00004312 break;
4313 }
cristy884f6002011-07-31 00:51:45 +00004314 case SplineInterpolatePixel:
4315 {
4316 MagickRealType
4317 dx,
4318 dy;
4319
4320 PointInfo
4321 delta;
4322
4323 ssize_t
4324 j,
4325 n;
4326
4327 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4328 exception);
4329 if (p == (const Quantum *) NULL)
4330 {
4331 status=MagickFalse;
4332 break;
4333 }
cristy222b19c2011-08-04 01:35:11 +00004334 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004335 for (i=0; i < 16; i++)
4336 {
4337 alpha[i]=1.0;
4338 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4339 }
4340 else
4341 for (i=0; i < 16; i++)
4342 {
4343 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4344 GetPixelChannels(image));
4345 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4346 }
4347 delta.x=x-x_offset;
4348 delta.y=y-y_offset;
4349 n=0;
4350 for (i=(-1); i < 3L; i++)
4351 {
4352 dy=CubicWeightingFunction((MagickRealType) i-delta.y);
4353 for (j=(-1); j < 3L; j++)
4354 {
4355 dx=CubicWeightingFunction(delta.x-(MagickRealType) j);
4356 gamma=1.0/(fabs((double) alpha[n]) <= MagickEpsilon ? 1.0 : alpha[n]);
4357 *pixel+=gamma*dx*dy*pixels[n];
4358 n++;
4359 }
4360 }
4361 break;
4362 }
cristya085a432011-07-30 01:39:32 +00004363 }
4364 return(status);
4365}
4366
4367/*
4368%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4369% %
4370% %
4371% %
cristy5c4e2582011-09-11 19:21:03 +00004372% I n t e r p o l a t e P i x e l C h a n n e l s %
4373% %
4374% %
4375% %
4376%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4377%
4378% InterpolatePixelChannels() applies a pixel interpolation method between a
4379% floating point coordinate and the pixels surrounding that coordinate. No
4380% pixel area resampling, or scaling of the result is performed.
4381%
4382% The format of the InterpolatePixelChannels method is:
4383%
4384% MagickBooleanType InterpolatePixelChannels(const Image *source,
4385% const CacheView *source_view,const Image *destination,
4386% const PixelInterpolateMethod method,const double x,const double y,
4387% Quantum *pixel,ExceptionInfo *exception)
4388%
4389% A description of each parameter follows:
4390%
4391% o source: the source.
4392%
4393% o source_view: the source view.
4394%
4395% o destination: the destination image.
4396%
4397% o method: the pixel color interpolation method.
4398%
4399% o x,y: A double representing the current (x,y) position of the pixel.
4400%
4401% o pixel: return the interpolated pixel here.
4402%
4403% o exception: return any errors or warnings in this structure.
4404%
4405*/
4406MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
4407 const CacheView *source_view,const Image *destination,
4408 const PixelInterpolateMethod method,const double x,const double y,
4409 Quantum *pixel,ExceptionInfo *exception)
4410{
4411 MagickBooleanType
4412 status;
4413
4414 MagickRealType
4415 alpha[16],
4416 gamma,
4417 pixels[16];
4418
4419 PixelChannel
4420 channel;
4421
4422 PixelTrait
4423 destination_traits,
4424 traits;
4425
4426 register const Quantum
4427 *p;
4428
4429 register ssize_t
4430 i;
4431
4432 ssize_t
4433 x_offset,
4434 y_offset;
4435
4436 assert(source != (Image *) NULL);
4437 assert(source != (Image *) NULL);
4438 assert(source->signature == MagickSignature);
4439 assert(source_view != (CacheView *) NULL);
4440 status=MagickTrue;
4441 x_offset=(ssize_t) floor(x);
4442 y_offset=(ssize_t) floor(y);
4443 switch (method == UndefinedInterpolatePixel ? source->interpolate : method)
4444 {
4445 case AverageInterpolatePixel:
4446 {
4447 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4448 exception);
4449 if (p == (const Quantum *) NULL)
4450 {
4451 status=MagickFalse;
4452 break;
4453 }
4454 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4455 {
4456 double
4457 sum;
4458
4459 register ssize_t
4460 j;
4461
cristye2a912b2011-12-05 20:02:07 +00004462 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004463 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004464 destination_traits=GetPixelChannelMapTraits(destination,channel);
4465 if ((traits == UndefinedPixelTrait) ||
4466 (destination_traits == UndefinedPixelTrait))
4467 continue;
4468 for (j=0; j < 16; j++)
4469 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
cristy4a7ae692011-12-14 12:24:11 +00004470 sum=0.0;
cristy5c4e2582011-09-11 19:21:03 +00004471 if ((traits & BlendPixelTrait) == 0)
4472 {
4473 for (j=0; j < 16; j++)
cristy4a7ae692011-12-14 12:24:11 +00004474 sum+=0.0625*pixels[j];
4475 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004476 continue;
4477 }
cristy5c4e2582011-09-11 19:21:03 +00004478 for (j=0; j < 16; j++)
4479 {
4480 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4481 GetPixelChannels(source));
4482 pixels[j]*=alpha[j];
4483 gamma=1.0/(fabs((double) alpha[j]) <= MagickEpsilon ? 1.0 : alpha[j]);
4484 sum+=gamma*0.0625*pixels[j];
4485 }
cristy4a7ae692011-12-14 12:24:11 +00004486 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004487 }
4488 break;
4489 }
4490 case BicubicInterpolatePixel:
4491 {
4492 MagickRealType
4493 u[4],
4494 v[4];
4495
4496 PointInfo
4497 delta;
4498
4499 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4500 exception);
4501 if (p == (const Quantum *) NULL)
4502 {
4503 status=MagickFalse;
4504 break;
4505 }
4506 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4507 {
4508 register ssize_t
4509 j;
4510
cristye2a912b2011-12-05 20:02:07 +00004511 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004512 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004513 destination_traits=GetPixelChannelMapTraits(destination,channel);
4514 if ((traits == UndefinedPixelTrait) ||
4515 (destination_traits == UndefinedPixelTrait))
4516 continue;
4517 if ((traits & BlendPixelTrait) == 0)
4518 for (j=0; j < 16; j++)
4519 {
4520 alpha[j]=1.0;
4521 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
4522 }
4523 else
4524 for (j=0; j < 16; j++)
4525 {
4526 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4527 GetPixelChannels(source));
4528 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
4529 }
4530 delta.x=x-x_offset;
4531 delta.y=y-y_offset;
4532 for (j=0; j < 4; j++)
4533 {
4534 u[0]=(pixels[4*j+3]-pixels[4*j+2])-(pixels[4*j+0]-pixels[4*j+1]);
4535 u[1]=(pixels[4*j+0]-pixels[4*j+1])-u[0];
4536 u[2]=pixels[4*j+2]-pixels[4*j+0];
4537 u[3]=pixels[4*j+1];
4538 v[j]=(delta.x*delta.x*delta.x*u[0])+(delta.x*delta.x*u[1])+(delta.x*
4539 u[2])+u[3];
4540 }
4541 u[0]=(v[3]-v[2])-(v[0]-v[1]);
4542 u[1]=(v[0]-v[1])-u[0];
4543 u[2]=v[2]-v[0];
4544 u[3]=v[1];
cristy4a7ae692011-12-14 12:24:11 +00004545 SetPixelChannel(destination,channel,ClampToQuantum((delta.y*delta.y*
4546 delta.y*u[0])+(delta.y*delta.y*u[1])+(delta.y*u[2])+u[3]),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004547 }
4548 break;
4549 }
4550 case BilinearInterpolatePixel:
4551 default:
4552 {
4553 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4554 if (p == (const Quantum *) NULL)
4555 {
4556 status=MagickFalse;
4557 break;
4558 }
4559 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4560 {
4561 PointInfo
4562 delta,
4563 epsilon;
4564
cristye2a912b2011-12-05 20:02:07 +00004565 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004566 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004567 destination_traits=GetPixelChannelMapTraits(destination,channel);
4568 if ((traits == UndefinedPixelTrait) ||
4569 (destination_traits == UndefinedPixelTrait))
4570 continue;
4571 delta.x=x-x_offset;
4572 delta.y=y-y_offset;
4573 epsilon.x=1.0-delta.x;
4574 epsilon.y=1.0-delta.y;
cristy28474bf2011-09-11 23:32:52 +00004575 pixels[0]=(MagickRealType) p[i];
4576 pixels[1]=(MagickRealType) p[GetPixelChannels(source)+i];
cristy5c4e2582011-09-11 19:21:03 +00004577 pixels[2]=(MagickRealType) p[2*GetPixelChannels(source)+i];
4578 pixels[3]=(MagickRealType) p[3*GetPixelChannels(source)+i];
4579 if ((traits & BlendPixelTrait) == 0)
4580 {
4581 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
4582 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004583 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
4584 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*
4585 pixels[2]+delta.x*pixels[3]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004586 continue;
4587 }
cristy28474bf2011-09-11 23:32:52 +00004588 alpha[0]=QuantumScale*GetPixelAlpha(source,p);
4589 alpha[1]=QuantumScale*GetPixelAlpha(source,p+GetPixelChannels(source));
cristy5c4e2582011-09-11 19:21:03 +00004590 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
4591 GetPixelChannels(source));
4592 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
4593 GetPixelChannels(source));
4594 pixels[0]*=alpha[0];
4595 pixels[1]*=alpha[1];
4596 pixels[2]*=alpha[2];
4597 pixels[3]*=alpha[3];
4598 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4599 (epsilon.x*alpha[2]+delta.x*alpha[3])));
4600 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004601 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
4602 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*pixels[2]+
4603 delta.x*pixels[3]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004604 }
4605 break;
4606 }
4607 case FilterInterpolatePixel:
4608 {
4609 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4610 {
4611 CacheView
4612 *filter_view;
4613
4614 Image
4615 *excerpt_source,
4616 *filter_source;
4617
4618 RectangleInfo
4619 geometry;
4620
cristye2a912b2011-12-05 20:02:07 +00004621 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004622 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004623 destination_traits=GetPixelChannelMapTraits(destination,channel);
4624 if ((traits == UndefinedPixelTrait) ||
4625 (destination_traits == UndefinedPixelTrait))
4626 continue;
4627 geometry.width=4L;
4628 geometry.height=4L;
4629 geometry.x=x_offset-1;
4630 geometry.y=y_offset-1;
4631 excerpt_source=ExcerptImage(source,&geometry,exception);
4632 if (excerpt_source == (Image *) NULL)
4633 {
4634 status=MagickFalse;
4635 continue;
4636 }
4637 filter_source=ResizeImage(excerpt_source,1,1,source->filter,
4638 source->blur,exception);
4639 excerpt_source=DestroyImage(excerpt_source);
4640 if (filter_source == (Image *) NULL)
4641 continue;
4642 filter_view=AcquireCacheView(filter_source);
4643 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4644 if (p == (const Quantum *) NULL)
4645 status=MagickFalse;
4646 else
cristy1861c902011-12-14 02:30:00 +00004647 {
cristy4a7ae692011-12-14 12:24:11 +00004648 SetPixelChannel(destination,channel,p[i],pixel);
cristy1861c902011-12-14 02:30:00 +00004649 }
cristy5c4e2582011-09-11 19:21:03 +00004650 filter_view=DestroyCacheView(filter_view);
4651 filter_source=DestroyImage(filter_source);
4652 }
4653 break;
4654 }
4655 case IntegerInterpolatePixel:
4656 {
4657 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
4658 if (p == (const Quantum *) NULL)
4659 {
4660 status=MagickFalse;
4661 break;
4662 }
4663 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4664 {
cristye2a912b2011-12-05 20:02:07 +00004665 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004666 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004667 destination_traits=GetPixelChannelMapTraits(destination,channel);
4668 if ((traits == UndefinedPixelTrait) ||
4669 (destination_traits == UndefinedPixelTrait))
4670 continue;
cristy4a7ae692011-12-14 12:24:11 +00004671 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004672 }
4673 break;
4674 }
4675 case NearestNeighborInterpolatePixel:
4676 {
4677 p=GetCacheViewVirtualPixels(source_view,NearestNeighbor(x),
4678 NearestNeighbor(y),1,1,exception);
4679 if (p == (const Quantum *) NULL)
4680 {
4681 status=MagickFalse;
4682 break;
4683 }
4684 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4685 {
cristye2a912b2011-12-05 20:02:07 +00004686 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004687 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004688 destination_traits=GetPixelChannelMapTraits(destination,channel);
4689 if ((traits == UndefinedPixelTrait) ||
4690 (destination_traits == UndefinedPixelTrait))
4691 continue;
cristy4a7ae692011-12-14 12:24:11 +00004692 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004693 }
4694 break;
4695 }
4696 case MeshInterpolatePixel:
4697 {
4698 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4699 if (p == (const Quantum *) NULL)
4700 {
4701 status=MagickFalse;
4702 break;
4703 }
4704 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4705 {
4706 PointInfo
4707 delta,
4708 luminance;
4709
cristye2a912b2011-12-05 20:02:07 +00004710 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004711 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004712 destination_traits=GetPixelChannelMapTraits(destination,channel);
4713 if ((traits == UndefinedPixelTrait) ||
4714 (destination_traits == UndefinedPixelTrait))
4715 continue;
cristy1861c902011-12-14 02:30:00 +00004716 pixels[0]=(MagickRealType) p[i];
4717 pixels[1]=(MagickRealType) p[GetPixelChannels(source)+i];
4718 pixels[2]=(MagickRealType) p[2*GetPixelChannels(source)+i];
4719 pixels[3]=(MagickRealType) p[3*GetPixelChannels(source)+i];
4720 if ((traits & BlendPixelTrait) == 0)
4721 {
4722 alpha[0]=1.0;
4723 alpha[1]=1.0;
4724 alpha[2]=1.0;
4725 alpha[3]=1.0;
4726 }
4727 else
4728 {
4729 alpha[0]=QuantumScale*GetPixelAlpha(source,p);
4730 alpha[1]=QuantumScale*GetPixelAlpha(source,p+
4731 GetPixelChannels(source));
4732 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
4733 GetPixelChannels(source));
4734 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
4735 GetPixelChannels(source));
4736 }
4737 delta.x=x-x_offset;
4738 delta.y=y-y_offset;
4739 luminance.x=GetPixelLuminance(source,p)-(double)
4740 GetPixelLuminance(source,p+3*GetPixelChannels(source));
4741 luminance.y=GetPixelLuminance(source,p+GetPixelChannels(source))-
4742 (double) GetPixelLuminance(source,p+2*GetPixelChannels(source));
4743 if (fabs(luminance.x) < fabs(luminance.y))
4744 {
4745 /*
4746 Diagonal 0-3 NW-SE.
4747 */
4748 if (delta.x <= delta.y)
4749 {
4750 /*
4751 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4752 */
4753 delta.y=1.0-delta.y;
4754 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
4755 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004756 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4757 MeshInterpolate(&delta,pixels[2],pixels[3],pixels[0])),pixel);
cristy1861c902011-12-14 02:30:00 +00004758 }
4759 else
4760 {
4761 /*
4762 Top-right triangle (pixel: 1, diagonal: 0-3).
4763 */
4764 delta.x=1.0-delta.x;
4765 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
4766 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004767 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4768 MeshInterpolate(&delta,pixels[1],pixels[0],pixels[3])),pixel);
cristy1861c902011-12-14 02:30:00 +00004769 }
4770 }
4771 else
4772 {
4773 /*
4774 Diagonal 1-2 NE-SW.
4775 */
4776 if (delta.x <= (1.0-delta.y))
4777 {
4778 /*
4779 Top-left triangle (pixel: 0, diagonal: 1-2).
4780 */
4781 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
4782 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004783 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4784 MeshInterpolate(&delta,pixels[0],pixels[1],pixels[2])),pixel);
cristy1861c902011-12-14 02:30:00 +00004785 }
4786 else
4787 {
4788 /*
4789 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4790 */
4791 delta.x=1.0-delta.x;
4792 delta.y=1.0-delta.y;
4793 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
4794 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004795 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4796 MeshInterpolate(&delta,pixels[3],pixels[2],pixels[1])),pixel);
cristy1861c902011-12-14 02:30:00 +00004797 }
4798 }
cristy5c4e2582011-09-11 19:21:03 +00004799 }
4800 break;
4801 }
4802 case SplineInterpolatePixel:
4803 {
4804 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4805 exception);
4806 if (p == (const Quantum *) NULL)
4807 {
4808 status=MagickFalse;
4809 break;
4810 }
4811 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4812 {
4813 double
4814 sum;
4815
4816 MagickRealType
4817 dx,
4818 dy;
4819
4820 PointInfo
4821 delta;
4822
4823 register ssize_t
4824 j;
4825
4826 ssize_t
4827 k,
4828 n;
4829
cristye2a912b2011-12-05 20:02:07 +00004830 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004831 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004832 destination_traits=GetPixelChannelMapTraits(destination,channel);
4833 if ((traits == UndefinedPixelTrait) ||
4834 (destination_traits == UndefinedPixelTrait))
4835 continue;
4836 if ((traits & BlendPixelTrait) == 0)
4837 for (j=0; j < 16; j++)
4838 {
4839 alpha[j]=1.0;
4840 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
4841 }
4842 else
4843 for (j=0; j < 16; j++)
4844 {
4845 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4846 GetPixelChannels(source));
4847 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
4848 }
4849 delta.x=x-x_offset;
4850 delta.y=y-y_offset;
4851 sum=0.0;
4852 n=0;
4853 for (j=(-1); j < 3L; j++)
4854 {
4855 dy=CubicWeightingFunction((MagickRealType) j-delta.y);
4856 for (k=(-1); k < 3L; k++)
4857 {
4858 dx=CubicWeightingFunction(delta.x-(MagickRealType) k);
4859 gamma=1.0/(fabs((double) alpha[n]) <= MagickEpsilon ? 1.0 :
4860 alpha[n]);
4861 sum+=gamma*dx*dy*pixels[n];
4862 n++;
4863 }
4864 }
cristy4a7ae692011-12-14 12:24:11 +00004865 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004866 }
4867 break;
4868 }
4869 }
4870 return(status);
4871}
4872
4873/*
4874%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4875% %
4876% %
4877% %
cristy9075cdb2011-07-30 01:06:23 +00004878% 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 +00004879% %
4880% %
4881% %
4882%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4883%
cristy884f6002011-07-31 00:51:45 +00004884% InterpolatePixelInfo() applies a pixel interpolation method between a
4885% floating point coordinate and the pixels surrounding that coordinate. No
4886% pixel area resampling, or scaling of the result is performed.
cristy4c08aed2011-07-01 19:47:50 +00004887%
4888% The format of the InterpolatePixelInfo method is:
4889%
4890% MagickBooleanType InterpolatePixelInfo(const Image *image,
cristy5c4e2582011-09-11 19:21:03 +00004891% const CacheView *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00004892% const double x,const double y,PixelInfo *pixel,
4893% ExceptionInfo *exception)
4894%
4895% A description of each parameter follows:
4896%
4897% o image: the image.
4898%
4899% o image_view: the image view.
4900%
4901% o method: the pixel color interpolation method.
4902%
4903% o x,y: A double representing the current (x,y) position of the pixel.
4904%
4905% o pixel: return the interpolated pixel here.
4906%
4907% o exception: return any errors or warnings in this structure.
4908%
4909*/
4910
4911static inline void AlphaBlendPixelInfo(const Image *image,
4912 const Quantum *pixel,PixelInfo *pixel_info,MagickRealType *alpha)
4913{
4914 if (image->matte == MagickFalse)
4915 {
4916 *alpha=1.0;
4917 pixel_info->red=(MagickRealType) GetPixelRed(image,pixel);
4918 pixel_info->green=(MagickRealType) GetPixelGreen(image,pixel);
4919 pixel_info->blue=(MagickRealType) GetPixelBlue(image,pixel);
4920 pixel_info->black=0.0;
4921 if (image->colorspace == CMYKColorspace)
4922 pixel_info->black=(MagickRealType) GetPixelBlack(image,pixel);
4923 pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
4924 return;
4925 }
4926 *alpha=QuantumScale*GetPixelAlpha(image,pixel);
4927 pixel_info->red=(*alpha*GetPixelRed(image,pixel));
4928 pixel_info->green=(*alpha*GetPixelGreen(image,pixel));
4929 pixel_info->blue=(*alpha*GetPixelBlue(image,pixel));
4930 pixel_info->black=0.0;
4931 if (image->colorspace == CMYKColorspace)
4932 pixel_info->black=(*alpha*GetPixelBlack(image,pixel));
4933 pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
4934}
4935
4936static void BicubicInterpolate(const PixelInfo *pixels,const double dx,
4937 PixelInfo *pixel)
4938{
4939 MagickRealType
4940 dx2,
4941 p,
4942 q,
4943 r,
4944 s;
4945
4946 dx2=dx*dx;
4947 p=(pixels[3].red-pixels[2].red)-(pixels[0].red-pixels[1].red);
4948 q=(pixels[0].red-pixels[1].red)-p;
4949 r=pixels[2].red-pixels[0].red;
4950 s=pixels[1].red;
4951 pixel->red=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4952 p=(pixels[3].green-pixels[2].green)-(pixels[0].green-pixels[1].green);
4953 q=(pixels[0].green-pixels[1].green)-p;
4954 r=pixels[2].green-pixels[0].green;
4955 s=pixels[1].green;
4956 pixel->green=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4957 p=(pixels[3].blue-pixels[2].blue)-(pixels[0].blue-pixels[1].blue);
4958 q=(pixels[0].blue-pixels[1].blue)-p;
4959 r=pixels[2].blue-pixels[0].blue;
4960 s=pixels[1].blue;
4961 pixel->blue=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4962 p=(pixels[3].alpha-pixels[2].alpha)-(pixels[0].alpha-pixels[1].alpha);
4963 q=(pixels[0].alpha-pixels[1].alpha)-p;
4964 r=pixels[2].alpha-pixels[0].alpha;
4965 s=pixels[1].alpha;
4966 pixel->alpha=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4967 if (pixel->colorspace == CMYKColorspace)
4968 {
4969 p=(pixels[3].black-pixels[2].black)-(pixels[0].black-pixels[1].black);
4970 q=(pixels[0].black-pixels[1].black)-p;
4971 r=pixels[2].black-pixels[0].black;
4972 s=pixels[1].black;
4973 pixel->black=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4974 }
4975}
4976
cristy4c08aed2011-07-01 19:47:50 +00004977MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
cristy5c4e2582011-09-11 19:21:03 +00004978 const CacheView *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00004979 const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception)
4980{
4981 MagickBooleanType
4982 status;
4983
cristy4c08aed2011-07-01 19:47:50 +00004984 MagickRealType
4985 alpha[16],
4986 gamma;
4987
cristy865d58d2011-07-09 00:44:52 +00004988 PixelInfo
4989 pixels[16];
4990
cristy4c08aed2011-07-01 19:47:50 +00004991 register const Quantum
4992 *p;
4993
4994 register ssize_t
4995 i;
4996
4997 ssize_t
4998 x_offset,
4999 y_offset;
5000
5001 assert(image != (Image *) NULL);
5002 assert(image->signature == MagickSignature);
5003 assert(image_view != (CacheView *) NULL);
5004 status=MagickTrue;
5005 x_offset=(ssize_t) floor(x);
5006 y_offset=(ssize_t) floor(y);
5007 switch (method == UndefinedInterpolatePixel ? image->interpolate : method)
5008 {
5009 case AverageInterpolatePixel:
5010 {
5011 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5012 exception);
5013 if (p == (const Quantum *) NULL)
5014 {
5015 status=MagickFalse;
5016 break;
5017 }
cristy5ce8df82011-07-07 14:52:23 +00005018 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005019 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005020 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5021 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5022 AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
5023 AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
5024 AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
5025 AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
5026 AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
5027 AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
5028 AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
cristy865d58d2011-07-09 00:44:52 +00005029 10);
cristyed231572011-07-14 02:18:59 +00005030 AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
cristy865d58d2011-07-09 00:44:52 +00005031 11);
cristyed231572011-07-14 02:18:59 +00005032 AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
cristy865d58d2011-07-09 00:44:52 +00005033 12);
cristyed231572011-07-14 02:18:59 +00005034 AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
cristy865d58d2011-07-09 00:44:52 +00005035 13);
cristyed231572011-07-14 02:18:59 +00005036 AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
cristy865d58d2011-07-09 00:44:52 +00005037 14);
cristyed231572011-07-14 02:18:59 +00005038 AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
cristy865d58d2011-07-09 00:44:52 +00005039 15);
cristy4c08aed2011-07-01 19:47:50 +00005040 pixel->red=0.0;
5041 pixel->green=0.0;
5042 pixel->blue=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005043 pixel->black=0.0;
cristy865d58d2011-07-09 00:44:52 +00005044 pixel->alpha=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005045 for (i=0; i < 16L; i++)
5046 {
5047 gamma=1.0/(fabs((double) alpha[i]) <= MagickEpsilon ? 1.0 : alpha[i]);
5048 pixel->red+=gamma*0.0625*pixels[i].red;
5049 pixel->green+=gamma*0.0625*pixels[i].green;
5050 pixel->blue+=gamma*0.0625*pixels[i].blue;
cristy4c08aed2011-07-01 19:47:50 +00005051 if (image->colorspace == CMYKColorspace)
5052 pixel->black+=gamma*0.0625*pixels[i].black;
cristy865d58d2011-07-09 00:44:52 +00005053 pixel->alpha+=0.0625*pixels[i].alpha;
cristy4c08aed2011-07-01 19:47:50 +00005054 }
5055 break;
5056 }
5057 case BicubicInterpolatePixel:
5058 {
5059 PixelInfo
5060 u[4];
5061
5062 PointInfo
5063 delta;
5064
5065 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5066 exception);
5067 if (p == (const Quantum *) NULL)
5068 {
5069 status=MagickFalse;
5070 break;
5071 }
cristy5ce8df82011-07-07 14:52:23 +00005072 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005073 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005074 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5075 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5076 AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
5077 AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
5078 AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
5079 AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
5080 AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
5081 AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
5082 AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
cristy865d58d2011-07-09 00:44:52 +00005083 10);
cristyed231572011-07-14 02:18:59 +00005084 AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
cristy865d58d2011-07-09 00:44:52 +00005085 11);
cristyed231572011-07-14 02:18:59 +00005086 AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
cristy865d58d2011-07-09 00:44:52 +00005087 12);
cristyed231572011-07-14 02:18:59 +00005088 AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
cristy865d58d2011-07-09 00:44:52 +00005089 13);
cristyed231572011-07-14 02:18:59 +00005090 AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
cristy865d58d2011-07-09 00:44:52 +00005091 14);
cristyed231572011-07-14 02:18:59 +00005092 AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
cristy865d58d2011-07-09 00:44:52 +00005093 15);
cristy4c08aed2011-07-01 19:47:50 +00005094 delta.x=x-x_offset;
5095 delta.y=y-y_offset;
5096 for (i=0; i < 4L; i++)
5097 BicubicInterpolate(pixels+4*i,delta.x,u+i);
5098 BicubicInterpolate(u,delta.y,pixel);
5099 break;
5100 }
5101 case BilinearInterpolatePixel:
5102 default:
5103 {
5104 PointInfo
5105 delta,
5106 epsilon;
5107
5108 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5109 if (p == (const Quantum *) NULL)
5110 {
5111 status=MagickFalse;
5112 break;
5113 }
cristy5ce8df82011-07-07 14:52:23 +00005114 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005115 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005116 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5117 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
cristy4c08aed2011-07-01 19:47:50 +00005118 delta.x=x-x_offset;
5119 delta.y=y-y_offset;
5120 epsilon.x=1.0-delta.x;
5121 epsilon.y=1.0-delta.y;
5122 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
5123 (epsilon.x*alpha[2]+delta.x*alpha[3])));
5124 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
5125 pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x*
5126 pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red));
5127 pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x*
5128 pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x*
5129 pixels[3].green));
5130 pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x*
5131 pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x*
5132 pixels[3].blue));
cristy4c08aed2011-07-01 19:47:50 +00005133 if (image->colorspace == CMYKColorspace)
5134 pixel->black=gamma*(epsilon.y*(epsilon.x*pixels[0].black+delta.x*
5135 pixels[1].black)+delta.y*(epsilon.x*pixels[2].black+delta.x*
5136 pixels[3].black));
cristy884f6002011-07-31 00:51:45 +00005137 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
5138 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy865d58d2011-07-09 00:44:52 +00005139 pixel->alpha=(epsilon.y*(epsilon.x*pixels[0].alpha+delta.x*
5140 pixels[1].alpha)+delta.y*(epsilon.x*pixels[2].alpha+delta.x*
5141 pixels[3].alpha));
cristy4c08aed2011-07-01 19:47:50 +00005142 break;
5143 }
5144 case FilterInterpolatePixel:
5145 {
5146 CacheView
5147 *filter_view;
5148
5149 Image
5150 *excerpt_image,
5151 *filter_image;
5152
5153 RectangleInfo
5154 geometry;
5155
5156 geometry.width=4L;
5157 geometry.height=4L;
5158 geometry.x=x_offset-1;
5159 geometry.y=y_offset-1;
5160 excerpt_image=ExcerptImage(image,&geometry,exception);
5161 if (excerpt_image == (Image *) NULL)
5162 {
5163 status=MagickFalse;
5164 break;
5165 }
5166 filter_image=ResizeImage(excerpt_image,1,1,image->filter,image->blur,
5167 exception);
5168 excerpt_image=DestroyImage(excerpt_image);
5169 if (filter_image == (Image *) NULL)
5170 break;
5171 filter_view=AcquireCacheView(filter_image);
5172 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
5173 if (p != (const Quantum *) NULL)
cristy803640d2011-11-17 02:11:32 +00005174 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005175 filter_view=DestroyCacheView(filter_view);
5176 filter_image=DestroyImage(filter_image);
5177 break;
5178 }
5179 case IntegerInterpolatePixel:
5180 {
5181 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
5182 if (p == (const Quantum *) NULL)
5183 {
5184 status=MagickFalse;
5185 break;
5186 }
cristy803640d2011-11-17 02:11:32 +00005187 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005188 break;
5189 }
5190 case MeshInterpolatePixel:
5191 {
5192 PointInfo
5193 delta,
5194 luminance;
5195
cristy94ea1632011-07-30 20:40:25 +00005196 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
cristy4c08aed2011-07-01 19:47:50 +00005197 if (p == (const Quantum *) NULL)
5198 {
5199 status=MagickFalse;
5200 break;
5201 }
cristy94ea1632011-07-30 20:40:25 +00005202 delta.x=x-x_offset;
5203 delta.y=y-y_offset;
cristy884f6002011-07-31 00:51:45 +00005204 luminance.x=GetPixelLuminance(image,p)-(double)
cristy94ea1632011-07-30 20:40:25 +00005205 GetPixelLuminance(image,p+3*GetPixelChannels(image));
cristy28474bf2011-09-11 23:32:52 +00005206 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
cristy94ea1632011-07-30 20:40:25 +00005207 GetPixelLuminance(image,p+2*GetPixelChannels(image));
cristy5ce8df82011-07-07 14:52:23 +00005208 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005209 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005210 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5211 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
cristy4c08aed2011-07-01 19:47:50 +00005212 if (fabs(luminance.x) < fabs(luminance.y))
5213 {
5214 /*
5215 Diagonal 0-3 NW-SE.
5216 */
5217 if (delta.x <= delta.y)
5218 {
5219 /*
cristy94ea1632011-07-30 20:40:25 +00005220 Bottom-left triangle (pixel: 2, diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005221 */
5222 delta.y=1.0-delta.y;
5223 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
5224 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
5225 pixel->red=gamma*MeshInterpolate(&delta,pixels[2].red,
5226 pixels[3].red,pixels[0].red);
5227 pixel->green=gamma*MeshInterpolate(&delta,pixels[2].green,
5228 pixels[3].green,pixels[0].green);
5229 pixel->blue=gamma*MeshInterpolate(&delta,pixels[2].blue,
5230 pixels[3].blue,pixels[0].blue);
cristy4c08aed2011-07-01 19:47:50 +00005231 if (image->colorspace == CMYKColorspace)
5232 pixel->black=gamma*MeshInterpolate(&delta,pixels[2].black,
5233 pixels[3].black,pixels[0].black);
cristy94ea1632011-07-30 20:40:25 +00005234 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005235 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[2].alpha,
5236 pixels[3].alpha,pixels[0].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005237 }
5238 else
5239 {
5240 /*
cristy94ea1632011-07-30 20:40:25 +00005241 Top-right triangle (pixel:1 , diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005242 */
5243 delta.x=1.0-delta.x;
5244 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
5245 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
5246 pixel->red=gamma*MeshInterpolate(&delta,pixels[1].red,
5247 pixels[0].red,pixels[3].red);
5248 pixel->green=gamma*MeshInterpolate(&delta,pixels[1].green,
5249 pixels[0].green,pixels[3].green);
5250 pixel->blue=gamma*MeshInterpolate(&delta,pixels[1].blue,
5251 pixels[0].blue,pixels[3].blue);
cristy4c08aed2011-07-01 19:47:50 +00005252 if (image->colorspace == CMYKColorspace)
5253 pixel->black=gamma*MeshInterpolate(&delta,pixels[1].black,
5254 pixels[0].black,pixels[3].black);
cristy94ea1632011-07-30 20:40:25 +00005255 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005256 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[1].alpha,
5257 pixels[0].alpha,pixels[3].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005258 }
5259 }
5260 else
5261 {
5262 /*
5263 Diagonal 1-2 NE-SW.
5264 */
5265 if (delta.x <= (1.0-delta.y))
5266 {
5267 /*
cristy94ea1632011-07-30 20:40:25 +00005268 Top-left triangle (pixel: 0, diagonal: 1-2).
cristy4c08aed2011-07-01 19:47:50 +00005269 */
5270 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
5271 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
5272 pixel->red=gamma*MeshInterpolate(&delta,pixels[0].red,
5273 pixels[1].red,pixels[2].red);
5274 pixel->green=gamma*MeshInterpolate(&delta,pixels[0].green,
5275 pixels[1].green,pixels[2].green);
5276 pixel->blue=gamma*MeshInterpolate(&delta,pixels[0].blue,
5277 pixels[1].blue,pixels[2].blue);
cristy4c08aed2011-07-01 19:47:50 +00005278 if (image->colorspace == CMYKColorspace)
5279 pixel->black=gamma*MeshInterpolate(&delta,pixels[0].black,
5280 pixels[1].black,pixels[2].black);
cristy94ea1632011-07-30 20:40:25 +00005281 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005282 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[0].alpha,
5283 pixels[1].alpha,pixels[2].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005284 }
5285 else
5286 {
5287 /*
5288 Bottom-right triangle (pixel: 3, diagonal: 1-2).
5289 */
5290 delta.x=1.0-delta.x;
5291 delta.y=1.0-delta.y;
5292 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
5293 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
5294 pixel->red=gamma*MeshInterpolate(&delta,pixels[3].red,
5295 pixels[2].red,pixels[1].red);
5296 pixel->green=gamma*MeshInterpolate(&delta,pixels[3].green,
5297 pixels[2].green,pixels[1].green);
5298 pixel->blue=gamma*MeshInterpolate(&delta,pixels[3].blue,
5299 pixels[2].blue,pixels[1].blue);
cristy4c08aed2011-07-01 19:47:50 +00005300 if (image->colorspace == CMYKColorspace)
5301 pixel->black=gamma*MeshInterpolate(&delta,pixels[3].black,
5302 pixels[2].black,pixels[1].black);
cristy94ea1632011-07-30 20:40:25 +00005303 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005304 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[3].alpha,
5305 pixels[2].alpha,pixels[1].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005306 }
5307 }
5308 break;
5309 }
5310 case NearestNeighborInterpolatePixel:
5311 {
5312 p=GetCacheViewVirtualPixels(image_view,NearestNeighbor(x),
5313 NearestNeighbor(y),1,1,exception);
5314 if (p == (const Quantum *) NULL)
5315 {
5316 status=MagickFalse;
5317 break;
5318 }
cristy803640d2011-11-17 02:11:32 +00005319 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005320 break;
5321 }
5322 case SplineInterpolatePixel:
5323 {
5324 MagickRealType
5325 dx,
5326 dy;
5327
5328 PointInfo
5329 delta;
5330
5331 ssize_t
5332 j,
5333 n;
5334
5335 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5336 exception);
5337 if (p == (const Quantum *) NULL)
5338 {
5339 status=MagickFalse;
5340 break;
5341 }
cristy5ce8df82011-07-07 14:52:23 +00005342 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005343 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005344 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5345 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5346 AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
5347 AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
5348 AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
5349 AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
5350 AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
5351 AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
5352 AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
cristy865d58d2011-07-09 00:44:52 +00005353 10);
cristyed231572011-07-14 02:18:59 +00005354 AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
cristy865d58d2011-07-09 00:44:52 +00005355 11);
cristyed231572011-07-14 02:18:59 +00005356 AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
cristy865d58d2011-07-09 00:44:52 +00005357 12);
cristyed231572011-07-14 02:18:59 +00005358 AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
cristy865d58d2011-07-09 00:44:52 +00005359 13);
cristyed231572011-07-14 02:18:59 +00005360 AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
cristy865d58d2011-07-09 00:44:52 +00005361 14);
cristyed231572011-07-14 02:18:59 +00005362 AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
cristy865d58d2011-07-09 00:44:52 +00005363 15);
cristy4c08aed2011-07-01 19:47:50 +00005364 pixel->red=0.0;
5365 pixel->green=0.0;
5366 pixel->blue=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005367 pixel->black=0.0;
cristy865d58d2011-07-09 00:44:52 +00005368 pixel->alpha=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005369 delta.x=x-x_offset;
5370 delta.y=y-y_offset;
5371 n=0;
5372 for (i=(-1); i < 3L; i++)
5373 {
5374 dy=CubicWeightingFunction((MagickRealType) i-delta.y);
5375 for (j=(-1); j < 3L; j++)
5376 {
5377 dx=CubicWeightingFunction(delta.x-(MagickRealType) j);
5378 gamma=1.0/(fabs((double) alpha[n]) <= MagickEpsilon ? 1.0 : alpha[n]);
5379 pixel->red+=gamma*dx*dy*pixels[n].red;
5380 pixel->green+=gamma*dx*dy*pixels[n].green;
5381 pixel->blue+=gamma*dx*dy*pixels[n].blue;
5382 if (image->colorspace == CMYKColorspace)
5383 pixel->black+=gamma*dx*dy*pixels[n].black;
5384 pixel->alpha+=dx*dy*pixels[n].alpha;
5385 n++;
5386 }
5387 }
5388 break;
5389 }
5390 }
5391 return(status);
5392}
5393
5394/*
5395%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5396% %
5397% %
5398% %
5399+ I s F u z z y E q u i v a l e n c e P i x e l %
5400% %
5401% %
5402% %
5403%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5404%
5405% IsFuzzyEquivalencePixel() returns MagickTrue if the distance between two
5406% pixels is less than the specified distance in a linear three (or four)u
5407% dimensional color space.
5408%
5409% The format of the IsFuzzyEquivalencePixel method is:
5410%
cristye4a40472011-12-22 02:56:19 +00005411% void IsFuzzyEquivalencePixel(const Image *source,const Quantum *p,
5412% const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005413%
5414% A description of each parameter follows:
5415%
cristye4a40472011-12-22 02:56:19 +00005416% o source: the source image.
cristy4c08aed2011-07-01 19:47:50 +00005417%
5418% o p: Pixel p.
5419%
cristye4a40472011-12-22 02:56:19 +00005420% o destination: the destination image.
5421%
cristy4c08aed2011-07-01 19:47:50 +00005422% o q: Pixel q.
5423%
5424*/
cristye4a40472011-12-22 02:56:19 +00005425MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source,
5426 const Quantum *p,const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005427{
5428 MagickRealType
5429 fuzz,
5430 pixel;
5431
5432 register MagickRealType
5433 distance,
5434 scale;
5435
cristye4a40472011-12-22 02:56:19 +00005436 fuzz=MagickMax(source->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(
5437 destination->fuzz,(MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005438 scale=1.0;
5439 distance=0.0;
cristye4a40472011-12-22 02:56:19 +00005440 if (source->matte != MagickFalse)
cristy4c08aed2011-07-01 19:47:50 +00005441 {
5442 /*
5443 Transparencies are involved - set alpha distance
5444 */
cristy99abff32011-12-24 20:45:16 +00005445 pixel=GetPixelAlpha(source,p)-(MagickRealType)
5446 GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005447 distance=pixel*pixel;
5448 if (distance > fuzz)
5449 return(MagickFalse);
5450 /*
5451 Generate a alpha scaling factor to generate a 4D cone on colorspace
5452 Note that if one color is transparent, distance has no color component.
5453 */
cristye4a40472011-12-22 02:56:19 +00005454 scale=QuantumScale*GetPixelAlpha(source,p);
5455 scale*=QuantumScale*GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005456 if (scale <= MagickEpsilon)
5457 return(MagickTrue);
5458 }
5459 /*
5460 RGB or CMY color cube
5461 */
5462 distance*=3.0; /* rescale appropriately */
5463 fuzz*=3.0;
cristye4a40472011-12-22 02:56:19 +00005464 pixel=GetPixelRed(source,p)-(MagickRealType) GetPixelRed(destination,q);
5465 if ((source->colorspace == HSLColorspace) ||
5466 (source->colorspace == HSBColorspace) ||
5467 (source->colorspace == HWBColorspace))
cristy4c08aed2011-07-01 19:47:50 +00005468 {
5469 /*
5470 Compute an arc distance for hue. It should be a vector angle of
5471 'S'/'W' length with 'L'/'B' forming appropriate cones.
5472 */
5473 if (fabs((double) pixel) > (QuantumRange/2))
5474 pixel-=QuantumRange;
5475 pixel*=2;
5476 }
5477 distance+=scale*pixel*pixel;
5478 if (distance > fuzz)
5479 return(MagickFalse);
cristye4a40472011-12-22 02:56:19 +00005480 pixel=GetPixelGreen(source,p)-(MagickRealType) GetPixelGreen(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005481 distance+=scale*pixel*pixel;
5482 if (distance > fuzz)
5483 return(MagickFalse);
cristye4a40472011-12-22 02:56:19 +00005484 pixel=GetPixelBlue(source,p)-(MagickRealType) GetPixelBlue(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005485 distance+=scale*pixel*pixel;
5486 if (distance > fuzz)
5487 return(MagickFalse);
5488 return(MagickTrue);
5489}
5490
5491/*
5492%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5493% %
5494% %
5495% %
5496+ 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 %
5497% %
5498% %
5499% %
5500%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5501%
5502% IsFuzzyEquivalencePixelInfo() returns true if the distance between two
5503% colors is less than the specified distance in a linear three (or four)
5504% dimensional color space.
5505%
cristy5f95f4f2011-10-23 01:01:01 +00005506% This implements the equivalent of:
5507% fuzz < sqrt(color_distance^2 * u.a*v.a + alpha_distance^2)
cristy4c08aed2011-07-01 19:47:50 +00005508%
5509% Which produces a multi-dimensional cone for that colorspace along the
5510% transparency vector.
5511%
cristy5f95f4f2011-10-23 01:01:01 +00005512% For example for an RGB:
cristy4c08aed2011-07-01 19:47:50 +00005513% color_distance^2 = ( (u.r-v.r)^2 + (u.g-v.g)^2 + (u.b-v.b)^2 ) / 3
5514%
5515% See http://www.imagemagick.org/Usage/bugs/fuzz_distance/
5516%
5517% Hue colorspace distances need more work. Hue is not a distance, it is an
5518% angle!
5519%
5520% A check that q is in the same color space as p should be made and the
5521% appropriate mapping made. -- Anthony Thyssen 8 December 2010
5522%
5523% The format of the IsFuzzyEquivalencePixelInfo method is:
5524%
5525% MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5526% const PixelInfo *q)
5527%
5528% A description of each parameter follows:
5529%
5530% o p: Pixel p.
5531%
5532% o q: Pixel q.
5533%
5534*/
5535MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5536 const PixelInfo *q)
5537{
5538 MagickRealType
5539 fuzz,
5540 pixel;
5541
5542 register MagickRealType
5543 scale,
5544 distance;
5545
5546 if ((p->fuzz == 0.0) && (q->fuzz == 0.0))
5547 return(IsPixelInfoEquivalent(p,q));
5548 if (p->fuzz == 0.0)
cristy5f95f4f2011-10-23 01:01:01 +00005549 fuzz=MagickMax(q->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(q->fuzz,
5550 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005551 else if (q->fuzz == 0.0)
cristy5f95f4f2011-10-23 01:01:01 +00005552 fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(p->fuzz,
5553 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005554 else
cristy5f95f4f2011-10-23 01:01:01 +00005555 fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(q->fuzz,
5556 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005557 scale=1.0;
5558 distance=0.0;
5559 if ((p->matte != MagickFalse) || (q->matte != MagickFalse))
5560 {
5561 /*
5562 Transparencies are involved - set alpha distance.
5563 */
5564 pixel=(p->matte != MagickFalse ? p->alpha : OpaqueAlpha)-
5565 (q->matte != MagickFalse ? q->alpha : OpaqueAlpha);
5566 distance=pixel*pixel;
5567 if (distance > fuzz)
5568 return(MagickFalse);
5569 /*
5570 Generate a alpha scaling factor to generate a 4D cone on colorspace.
cristy5f95f4f2011-10-23 01:01:01 +00005571 If one color is transparent, distance has no color component.
cristy4c08aed2011-07-01 19:47:50 +00005572 */
5573 if (p->matte != MagickFalse)
5574 scale=(QuantumScale*p->alpha);
5575 if (q->matte != MagickFalse)
5576 scale*=(QuantumScale*q->alpha);
5577 if (scale <= MagickEpsilon )
5578 return(MagickTrue);
5579 }
5580 /*
5581 CMYK create a CMY cube with a multi-dimensional cone toward black.
5582 */
5583 if (p->colorspace == CMYKColorspace)
5584 {
5585 pixel=p->black-q->black;
5586 distance+=pixel*pixel*scale;
5587 if (distance > fuzz)
5588 return(MagickFalse);
5589 scale*=(MagickRealType) (QuantumScale*(QuantumRange-p->black));
5590 scale*=(MagickRealType) (QuantumScale*(QuantumRange-q->black));
5591 }
5592 /*
5593 RGB or CMY color cube.
5594 */
5595 distance*=3.0; /* rescale appropriately */
5596 fuzz*=3.0;
5597 pixel=p->red-q->red;
5598 if ((p->colorspace == HSLColorspace) || (p->colorspace == HSBColorspace) ||
5599 (p->colorspace == HWBColorspace))
5600 {
cristy5f95f4f2011-10-23 01:01:01 +00005601 /*
5602 This calculates a arc distance for hue-- it should be a vector angle
5603 of 'S'/'W' length with 'L'/'B' forming appropriate cones. In other
5604 words this is a hack - Anthony.
cristy4c08aed2011-07-01 19:47:50 +00005605 */
5606 if (fabs((double) pixel) > (QuantumRange/2))
5607 pixel-=QuantumRange;
5608 pixel*=2;
5609 }
5610 distance+=pixel*pixel*scale;
5611 if (distance > fuzz)
5612 return(MagickFalse);
5613 pixel=p->green-q->green;
5614 distance+=pixel*pixel*scale;
5615 if (distance > fuzz)
5616 return(MagickFalse);
5617 pixel=p->blue-q->blue;
5618 distance+=pixel*pixel*scale;
5619 if (distance > fuzz)
5620 return(MagickFalse);
5621 return(MagickTrue);
5622}
5623
5624/*
5625%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5626% %
5627% %
5628% %
cristye2a912b2011-12-05 20:02:07 +00005629% 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 +00005630% %
5631% %
5632% %
5633%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5634%
cristye2a912b2011-12-05 20:02:07 +00005635% SetPixelChannelMapMask() sets the pixel channel map from the specified
5636% channel mask.
cristy2b9582a2011-07-04 17:38:56 +00005637%
cristye2a912b2011-12-05 20:02:07 +00005638% The format of the SetPixelChannelMapMask method is:
cristy2b9582a2011-07-04 17:38:56 +00005639%
cristye2a912b2011-12-05 20:02:07 +00005640% void SetPixelChannelMapMask(Image *image,const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005641%
5642% A description of each parameter follows:
5643%
5644% o image: the image.
5645%
cristy44261462011-08-09 13:34:47 +00005646% o mask: the channel mask.
cristy2b9582a2011-07-04 17:38:56 +00005647%
5648*/
cristye2a912b2011-12-05 20:02:07 +00005649MagickExport void SetPixelChannelMapMask(Image *image,
cristy07a67852011-08-26 13:25:03 +00005650 const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005651{
cristy6a917d62011-08-24 17:31:30 +00005652#define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01)
cristydafd2872011-07-24 22:06:13 +00005653
cristy2b9582a2011-07-04 17:38:56 +00005654 register ssize_t
5655 i;
5656
cristy3c309812011-11-08 02:40:43 +00005657 image->channel_mask=channel_mask;
cristydafd2872011-07-24 22:06:13 +00005658 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
cristye2a912b2011-12-05 20:02:07 +00005659 {
5660 PixelChannel
5661 channel;
5662
5663 channel=GetPixelChannelMapChannel(image,i);
5664 SetPixelChannelMapTraits(image,channel,
5665 GetChannelBit(channel_mask,channel) == 0 ? CopyPixelTrait :
cristy0bbd87c2011-12-13 19:34:45 +00005666 image->matte == MagickFalse || (channel == AlphaPixelChannel) ?
5667 UpdatePixelTrait : (PixelTrait) (UpdatePixelTrait | BlendPixelTrait));
cristye2a912b2011-12-05 20:02:07 +00005668 }
cristy1685e722011-09-06 00:04:19 +00005669 if (image->storage_class == PseudoClass)
5670 SetPixelChannelMapTraits(image,IndexPixelChannel,CopyPixelTrait);
cristy183a5c72012-01-30 01:40:35 +00005671 if (image->mask != MagickFalse)
cristy10a6c612012-01-29 21:41:05 +00005672 SetPixelChannelMapTraits(image,MaskPixelChannel,CopyPixelTrait);
cristy6dcb9b82011-10-23 23:21:25 +00005673 if (image->debug != MagickFalse)
5674 LogPixelChannels(image);
cristy2b9582a2011-07-04 17:38:56 +00005675}
5676
5677/*
5678%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5679% %
5680% %
5681% %
cristybd5a96c2011-08-21 00:04:26 +00005682% 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 +00005683% %
5684% %
5685% %
5686%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5687%
cristy5f95f4f2011-10-23 01:01:01 +00005688% SetPixelChannelMask() sets the pixel channel mask from the specified channel
5689% mask.
cristy2b9582a2011-07-04 17:38:56 +00005690%
cristybd5a96c2011-08-21 00:04:26 +00005691% The format of the SetPixelChannelMask method is:
cristy2b9582a2011-07-04 17:38:56 +00005692%
cristybd5a96c2011-08-21 00:04:26 +00005693% ChannelType SetPixelChannelMask(Image *image,
5694% const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005695%
5696% A description of each parameter follows:
5697%
5698% o image: the image.
5699%
cristybd5a96c2011-08-21 00:04:26 +00005700% o channel_mask: the channel mask.
5701%
cristy2b9582a2011-07-04 17:38:56 +00005702*/
cristybd5a96c2011-08-21 00:04:26 +00005703MagickExport ChannelType SetPixelChannelMask(Image *image,
5704 const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005705{
cristybd5a96c2011-08-21 00:04:26 +00005706 ChannelType
5707 mask;
cristy222b19c2011-08-04 01:35:11 +00005708
cristybd5a96c2011-08-21 00:04:26 +00005709 mask=image->channel_mask;
5710 image->channel_mask=channel_mask;
cristye2a912b2011-12-05 20:02:07 +00005711 SetPixelChannelMapMask(image,channel_mask);
cristybd5a96c2011-08-21 00:04:26 +00005712 return(mask);
cristy2b9582a2011-07-04 17:38:56 +00005713}