blob: 5d14e2c2d819f1a619526887daf7772bbb44a051 [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
311% encountered. The data is returned as char, short int, int, ssize_t, float,
312% or double in the order specified by map.
313%
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%
321% MagickBooleanType ExportImagePixels(const Image *image,
322% const ssize_t x_offset,const ssize_t y_offset,const size_t columns,
cristy46f4be22012-01-07 00:26:39 +0000323% const size_t rows,const char *map,const StorageType type,void *pixels,
324% ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +0000325%
326% A description of each parameter follows:
327%
328% o image: the image.
329%
330% o x_offset,y_offset,columns,rows: These values define the perimeter
331% 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 *),
342% LongPixel (unsigned int *), LongLongPixel (unsigned long *),
343% 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
353static void ExportCharPixel(const Image *image,const ssize_t x_offset,
354 const ssize_t y_offset,const size_t columns,const size_t rows,
cristy46f4be22012-01-07 00:26:39 +0000355 const char *restrict map,const QuantumType *quantum_map,void *pixels,
356 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000357{
358 register const Quantum
359 *restrict p;
360
361 register ssize_t
362 x;
363
364 register unsigned char
cristy3fe11452012-01-09 01:27:42 +0000365 *restrict q;
cristye5370942012-01-06 03:49:31 +0000366
367 ssize_t
368 y;
369
cristy46f4be22012-01-07 00:26:39 +0000370 q=(unsigned char *) pixels;
cristye5370942012-01-06 03:49:31 +0000371 if (LocaleCompare(map,"BGR") == 0)
372 {
373 for (y=0; y < (ssize_t) rows; y++)
374 {
375 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
376 if (p == (const Quantum *) NULL)
377 break;
378 for (x=0; x < (ssize_t) columns; x++)
379 {
380 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
381 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
382 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
383 p+=GetPixelChannels(image);
384 }
385 }
386 return;
387 }
388 if (LocaleCompare(map,"BGRA") == 0)
389 {
390 for (y=0; y < (ssize_t) rows; y++)
391 {
392 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
393 if (p == (const Quantum *) NULL)
394 break;
395 for (x=0; x < (ssize_t) columns; x++)
396 {
397 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
398 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
399 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
400 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
401 p+=GetPixelChannels(image);
402 }
403 }
404 return;
405 }
406 if (LocaleCompare(map,"BGRP") == 0)
407 {
408 for (y=0; y < (ssize_t) rows; y++)
409 {
410 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
411 if (p == (const Quantum *) NULL)
412 break;
413 for (x=0; x < (ssize_t) columns; x++)
414 {
415 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
416 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
417 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
418 *q++=ScaleQuantumToChar((Quantum) 0);
419 p+=GetPixelChannels(image);
420 }
421 }
422 return;
423 }
424 if (LocaleCompare(map,"I") == 0)
425 {
426 for (y=0; y < (ssize_t) rows; y++)
427 {
428 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
429 if (p == (const Quantum *) NULL)
430 break;
431 for (x=0; x < (ssize_t) columns; x++)
432 {
433 *q++=ScaleQuantumToChar(GetPixelIntensity(image,p));
434 p+=GetPixelChannels(image);
435 }
436 }
437 return;
438 }
439 if (LocaleCompare(map,"RGB") == 0)
440 {
441 for (y=0; y < (ssize_t) rows; y++)
442 {
443 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
444 if (p == (const Quantum *) NULL)
445 break;
446 for (x=0; x < (ssize_t) columns; x++)
447 {
448 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
449 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
450 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
451 p+=GetPixelChannels(image);
452 }
453 }
454 return;
455 }
456 if (LocaleCompare(map,"RGBA") == 0)
457 {
458 for (y=0; y < (ssize_t) rows; y++)
459 {
460 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
461 if (p == (const Quantum *) NULL)
462 break;
463 for (x=0; x < (ssize_t) columns; x++)
464 {
465 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
466 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
467 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
468 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
469 p+=GetPixelChannels(image);
470 }
471 }
472 return;
473 }
474 if (LocaleCompare(map,"RGBP") == 0)
475 {
476 for (y=0; y < (ssize_t) rows; y++)
477 {
478 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
479 if (p == (const Quantum *) NULL)
480 break;
481 for (x=0; x < (ssize_t) columns; x++)
482 {
483 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
484 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
485 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
486 *q++=ScaleQuantumToChar((Quantum) 0);
487 p+=GetPixelChannels(image);
488 }
489 }
490 return;
491 }
492 for (y=0; y < (ssize_t) rows; y++)
493 {
494 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
495 if (p == (const Quantum *) NULL)
496 break;
497 for (x=0; x < (ssize_t) columns; x++)
498 {
499 register ssize_t
500 i;
501
502 for (i=0; i < (ssize_t) strlen(map); i++)
503 {
504 *q=0;
505 switch (quantum_map[i])
506 {
507 case RedQuantum:
508 case CyanQuantum:
509 {
510 *q=ScaleQuantumToChar(GetPixelRed(image,p));
511 break;
512 }
513 case GreenQuantum:
514 case MagentaQuantum:
515 {
516 *q=ScaleQuantumToChar(GetPixelGreen(image,p));
517 break;
518 }
519 case BlueQuantum:
520 case YellowQuantum:
521 {
522 *q=ScaleQuantumToChar(GetPixelBlue(image,p));
523 break;
524 }
525 case AlphaQuantum:
526 {
527 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
528 break;
529 }
530 case OpacityQuantum:
531 {
532 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
533 break;
534 }
535 case BlackQuantum:
536 {
537 if (image->colorspace == CMYKColorspace)
538 *q=ScaleQuantumToChar(GetPixelBlack(image,p));
539 break;
540 }
541 case IndexQuantum:
542 {
543 *q=ScaleQuantumToChar(GetPixelIntensity(image,p));
544 break;
545 }
546 default:
547 break;
548 }
549 q++;
550 }
551 p+=GetPixelChannels(image);
552 }
553 }
554}
555
556static void ExportDoublePixel(const Image *image,const ssize_t x_offset,
557 const ssize_t y_offset,const size_t columns,const size_t rows,
cristy46f4be22012-01-07 00:26:39 +0000558 const char *restrict map,const QuantumType *quantum_map,void *pixels,
559 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000560{
561 register const Quantum
562 *restrict p;
563
564 register double
cristy3fe11452012-01-09 01:27:42 +0000565 *restrict q;
cristye5370942012-01-06 03:49:31 +0000566
567 register ssize_t
568 x;
569
570 ssize_t
571 y;
572
573 q=(double *) pixels;
574 if (LocaleCompare(map,"BGR") == 0)
575 {
576 for (y=0; y < (ssize_t) rows; y++)
577 {
578 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
579 if (p == (const Quantum *) NULL)
580 break;
581 for (x=0; x < (ssize_t) columns; x++)
582 {
583 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
584 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
585 *q++=(double) (QuantumScale*GetPixelRed(image,p));
586 p+=GetPixelChannels(image);
587 }
588 }
589 return;
590 }
591 if (LocaleCompare(map,"BGRA") == 0)
592 {
593 for (y=0; y < (ssize_t) rows; y++)
594 {
595 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
596 if (p == (const Quantum *) NULL)
597 break;
598 for (x=0; x < (ssize_t) columns; x++)
599 {
600 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
601 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
602 *q++=(double) (QuantumScale*GetPixelRed(image,p));
603 *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
604 p+=GetPixelChannels(image);
605 }
606 }
607 return;
608 }
609 if (LocaleCompare(map,"BGRP") == 0)
610 {
611 for (y=0; y < (ssize_t) rows; y++)
612 {
613 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
614 if (p == (const Quantum *) NULL)
615 break;
616 for (x=0; x < (ssize_t) columns; x++)
617 {
618 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
619 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
620 *q++=(double) (QuantumScale*GetPixelRed(image,p));
621 *q++=0.0;
622 p+=GetPixelChannels(image);
623 }
624 }
625 return;
626 }
627 if (LocaleCompare(map,"I") == 0)
628 {
629 for (y=0; y < (ssize_t) rows; y++)
630 {
631 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
632 if (p == (const Quantum *) NULL)
633 break;
634 for (x=0; x < (ssize_t) columns; x++)
635 {
636 *q++=(double) (QuantumScale*GetPixelIntensity(image,p));
637 p+=GetPixelChannels(image);
638 }
639 }
640 return;
641 }
642 if (LocaleCompare(map,"RGB") == 0)
643 {
644 for (y=0; y < (ssize_t) rows; y++)
645 {
646 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
647 if (p == (const Quantum *) NULL)
648 break;
649 for (x=0; x < (ssize_t) columns; x++)
650 {
651 *q++=(double) (QuantumScale*GetPixelRed(image,p));
652 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
653 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
654 p+=GetPixelChannels(image);
655 }
656 }
657 return;
658 }
659 if (LocaleCompare(map,"RGBA") == 0)
660 {
661 for (y=0; y < (ssize_t) rows; y++)
662 {
663 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
664 if (p == (const Quantum *) NULL)
665 break;
666 for (x=0; x < (ssize_t) columns; x++)
667 {
668 *q++=(double) (QuantumScale*GetPixelRed(image,p));
669 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
670 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
671 *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
672 p+=GetPixelChannels(image);
673 }
674 }
675 return;
676 }
677 if (LocaleCompare(map,"RGBP") == 0)
678 {
679 for (y=0; y < (ssize_t) rows; y++)
680 {
681 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
682 if (p == (const Quantum *) NULL)
683 break;
684 for (x=0; x < (ssize_t) columns; x++)
685 {
686 *q++=(double) (QuantumScale*GetPixelRed(image,p));
687 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
688 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
689 *q++=0.0;
690 p+=GetPixelChannels(image);
691 }
692 }
693 return;
694 }
695 for (y=0; y < (ssize_t) rows; y++)
696 {
697 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
698 if (p == (const Quantum *) NULL)
699 break;
700 for (x=0; x < (ssize_t) columns; x++)
701 {
702 register ssize_t
703 i;
704
705 for (i=0; i < (ssize_t) strlen(map); i++)
706 {
707 *q=0;
708 switch (quantum_map[i])
709 {
710 case RedQuantum:
711 case CyanQuantum:
712 {
713 *q=(double) (QuantumScale*GetPixelRed(image,p));
714 break;
715 }
716 case GreenQuantum:
717 case MagentaQuantum:
718 {
719 *q=(double) (QuantumScale*GetPixelGreen(image,p));
720 break;
721 }
722 case BlueQuantum:
723 case YellowQuantum:
724 {
725 *q=(double) (QuantumScale*GetPixelBlue(image,p));
726 break;
727 }
728 case AlphaQuantum:
729 {
730 *q=(double) (QuantumScale*GetPixelAlpha(image,p));
731 break;
732 }
733 case OpacityQuantum:
734 {
735 *q=(double) (QuantumScale*GetPixelAlpha(image,p));
736 break;
737 }
738 case BlackQuantum:
739 {
740 if (image->colorspace == CMYKColorspace)
741 *q=(double) (QuantumScale*
742 GetPixelBlack(image,p));
743 break;
744 }
745 case IndexQuantum:
746 {
747 *q=(double) (QuantumScale*GetPixelIntensity(image,p));
748 break;
749 }
750 default:
751 *q=0;
752 }
753 q++;
754 }
755 p+=GetPixelChannels(image);
756 }
757 }
758}
759
760static void ExportFloatPixel(const Image *image,const ssize_t x_offset,
761 const ssize_t y_offset,const size_t columns,const size_t rows,
cristy46f4be22012-01-07 00:26:39 +0000762 const char *restrict map,const QuantumType *quantum_map,void *pixels,
763 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000764{
765 register const Quantum
766 *restrict p;
767
768 register float
cristy3fe11452012-01-09 01:27:42 +0000769 *restrict q;
cristye5370942012-01-06 03:49:31 +0000770
771 register ssize_t
772 x;
773
774 ssize_t
775 y;
776
777 q=(float *) pixels;
778 if (LocaleCompare(map,"BGR") == 0)
779 {
780 for (y=0; y < (ssize_t) rows; y++)
781 {
782 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
783 if (p == (const Quantum *) NULL)
784 break;
785 for (x=0; x < (ssize_t) columns; x++)
786 {
787 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
788 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
789 *q++=(float) (QuantumScale*GetPixelRed(image,p));
790 p+=GetPixelChannels(image);
791 }
792 }
793 return;
794 }
795 if (LocaleCompare(map,"BGRA") == 0)
796 {
797 for (y=0; y < (ssize_t) rows; y++)
798 {
799 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
800 if (p == (const Quantum *) NULL)
801 break;
802 for (x=0; x < (ssize_t) columns; x++)
803 {
804 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
805 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
806 *q++=(float) (QuantumScale*GetPixelRed(image,p));
807 *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
808 p+=GetPixelChannels(image);
809 }
810 }
811 return;
812 }
813 if (LocaleCompare(map,"BGRP") == 0)
814 {
815 for (y=0; y < (ssize_t) rows; y++)
816 {
817 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
818 if (p == (const Quantum *) NULL)
819 break;
820 for (x=0; x < (ssize_t) columns; x++)
821 {
822 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
823 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
824 *q++=(float) (QuantumScale*GetPixelRed(image,p));
825 *q++=0.0;
826 p+=GetPixelChannels(image);
827 }
828 }
829 return;
830 }
831 if (LocaleCompare(map,"I") == 0)
832 {
833 for (y=0; y < (ssize_t) rows; y++)
834 {
835 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
836 if (p == (const Quantum *) NULL)
837 break;
838 for (x=0; x < (ssize_t) columns; x++)
839 {
840 *q++=(float) (QuantumScale*GetPixelIntensity(image,p));
841 p+=GetPixelChannels(image);
842 }
843 }
844 return;
845 }
846 if (LocaleCompare(map,"RGB") == 0)
847 {
848 for (y=0; y < (ssize_t) rows; y++)
849 {
850 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
851 if (p == (const Quantum *) NULL)
852 break;
853 for (x=0; x < (ssize_t) columns; x++)
854 {
855 *q++=(float) (QuantumScale*GetPixelRed(image,p));
856 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
857 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
858 p+=GetPixelChannels(image);
859 }
860 }
861 return;
862 }
863 if (LocaleCompare(map,"RGBA") == 0)
864 {
865 for (y=0; y < (ssize_t) rows; y++)
866 {
867 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
868 if (p == (const Quantum *) NULL)
869 break;
870 for (x=0; x < (ssize_t) columns; x++)
871 {
872 *q++=(float) (QuantumScale*GetPixelRed(image,p));
873 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
874 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
875 *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
876 p+=GetPixelChannels(image);
877 }
878 }
879 return;
880 }
881 if (LocaleCompare(map,"RGBP") == 0)
882 {
883 for (y=0; y < (ssize_t) rows; y++)
884 {
885 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
886 if (p == (const Quantum *) NULL)
887 break;
888 for (x=0; x < (ssize_t) columns; x++)
889 {
890 *q++=(float) (QuantumScale*GetPixelRed(image,p));
891 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
892 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
893 *q++=0.0;
894 p+=GetPixelChannels(image);
895 }
896 }
897 return;
898 }
899 for (y=0; y < (ssize_t) rows; y++)
900 {
901 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
902 if (p == (const Quantum *) NULL)
903 break;
904 for (x=0; x < (ssize_t) columns; x++)
905 {
906 register ssize_t
907 i;
908
909 for (i=0; i < (ssize_t) strlen(map); i++)
910 {
911 *q=0;
912 switch (quantum_map[i])
913 {
914 case RedQuantum:
915 case CyanQuantum:
916 {
917 *q=(float) (QuantumScale*GetPixelRed(image,p));
918 break;
919 }
920 case GreenQuantum:
921 case MagentaQuantum:
922 {
923 *q=(float) (QuantumScale*GetPixelGreen(image,p));
924 break;
925 }
926 case BlueQuantum:
927 case YellowQuantum:
928 {
929 *q=(float) (QuantumScale*GetPixelBlue(image,p));
930 break;
931 }
932 case AlphaQuantum:
933 {
934 *q=(float) (QuantumScale*((Quantum) (GetPixelAlpha(image,p))));
935 break;
936 }
937 case OpacityQuantum:
938 {
939 *q=(float) (QuantumScale*GetPixelAlpha(image,p));
940 break;
941 }
942 case BlackQuantum:
943 {
944 if (image->colorspace == CMYKColorspace)
945 *q=(float) (QuantumScale* GetPixelBlack(image,p));
946 break;
947 }
948 case IndexQuantum:
949 {
950 *q=(float) (QuantumScale*GetPixelIntensity(image,p));
951 break;
952 }
953 default:
954 *q=0;
955 }
956 q++;
957 }
958 p+=GetPixelChannels(image);
959 }
960 }
961}
962
cristy6c9e1682012-01-07 21:37:44 +0000963static void ExportLongPixel(const Image *image,const ssize_t x_offset,
cristye5370942012-01-06 03:49:31 +0000964 const ssize_t y_offset,const size_t columns,const size_t rows,
cristy46f4be22012-01-07 00:26:39 +0000965 const char *restrict map,const QuantumType *quantum_map,void *pixels,
966 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000967{
968 register const Quantum
969 *restrict p;
970
971 register ssize_t
972 x;
973
974 register unsigned int
cristy3fe11452012-01-09 01:27:42 +0000975 *restrict q;
cristye5370942012-01-06 03:49:31 +0000976
977 ssize_t
978 y;
979
980 q=(unsigned int *) pixels;
981 if (LocaleCompare(map,"BGR") == 0)
982 {
983 for (y=0; y < (ssize_t) rows; y++)
984 {
985 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
986 if (p == (const Quantum *) NULL)
987 break;
988 for (x=0; x < (ssize_t) columns; x++)
989 {
cristy6c9e1682012-01-07 21:37:44 +0000990 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
991 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
992 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +0000993 p+=GetPixelChannels(image);
994 }
995 }
996 return;
997 }
998 if (LocaleCompare(map,"BGRA") == 0)
999 {
1000 for (y=0; y < (ssize_t) rows; y++)
1001 {
1002 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1003 if (p == (const Quantum *) NULL)
1004 break;
1005 for (x=0; x < (ssize_t) columns; x++)
1006 {
cristy6c9e1682012-01-07 21:37:44 +00001007 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1008 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1009 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1010 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001011 p+=GetPixelChannels(image);
1012 }
1013 }
1014 return;
1015 }
1016 if (LocaleCompare(map,"BGRP") == 0)
1017 {
1018 for (y=0; y < (ssize_t) rows; y++)
1019 {
1020 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1021 if (p == (const Quantum *) NULL)
1022 break;
1023 for (x=0; x < (ssize_t) columns; x++)
1024 {
cristy6c9e1682012-01-07 21:37:44 +00001025 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1026 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1027 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1028 *q++=0;
cristye5370942012-01-06 03:49:31 +00001029 p+=GetPixelChannels(image);
1030 }
1031 }
1032 return;
1033 }
1034 if (LocaleCompare(map,"I") == 0)
1035 {
1036 for (y=0; y < (ssize_t) rows; y++)
1037 {
1038 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1039 if (p == (const Quantum *) NULL)
1040 break;
1041 for (x=0; x < (ssize_t) columns; x++)
1042 {
cristy6c9e1682012-01-07 21:37:44 +00001043 *q++=ScaleQuantumToLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001044 p+=GetPixelChannels(image);
1045 }
1046 }
1047 return;
1048 }
1049 if (LocaleCompare(map,"RGB") == 0)
1050 {
1051 for (y=0; y < (ssize_t) rows; y++)
1052 {
1053 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1054 if (p == (const Quantum *) NULL)
1055 break;
1056 for (x=0; x < (ssize_t) columns; x++)
1057 {
cristy6c9e1682012-01-07 21:37:44 +00001058 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1059 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1060 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001061 p+=GetPixelChannels(image);
1062 }
1063 }
1064 return;
1065 }
1066 if (LocaleCompare(map,"RGBA") == 0)
1067 {
1068 for (y=0; y < (ssize_t) rows; y++)
1069 {
1070 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1071 if (p == (const Quantum *) NULL)
1072 break;
1073 for (x=0; x < (ssize_t) columns; x++)
1074 {
cristy6c9e1682012-01-07 21:37:44 +00001075 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1076 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1077 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1078 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001079 p+=GetPixelChannels(image);
1080 }
1081 }
1082 return;
1083 }
1084 if (LocaleCompare(map,"RGBP") == 0)
1085 {
1086 for (y=0; y < (ssize_t) rows; y++)
1087 {
1088 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1089 if (p == (const Quantum *) NULL)
1090 break;
1091 for (x=0; x < (ssize_t) columns; x++)
1092 {
cristy6c9e1682012-01-07 21:37:44 +00001093 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1094 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1095 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1096 *q++=0;
cristye5370942012-01-06 03:49:31 +00001097 p+=GetPixelChannels(image);
1098 }
1099 }
1100 return;
1101 }
1102 for (y=0; y < (ssize_t) rows; y++)
1103 {
1104 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1105 if (p == (const Quantum *) NULL)
1106 break;
1107 for (x=0; x < (ssize_t) columns; x++)
1108 {
1109 register ssize_t
1110 i;
1111
1112 for (i=0; i < (ssize_t) strlen(map); i++)
1113 {
1114 *q=0;
1115 switch (quantum_map[i])
1116 {
1117 case RedQuantum:
1118 case CyanQuantum:
1119 {
cristy6c9e1682012-01-07 21:37:44 +00001120 *q=ScaleQuantumToLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001121 break;
1122 }
1123 case GreenQuantum:
1124 case MagentaQuantum:
1125 {
cristy6c9e1682012-01-07 21:37:44 +00001126 *q=ScaleQuantumToLong(GetPixelGreen(image,p));
cristye5370942012-01-06 03:49:31 +00001127 break;
1128 }
1129 case BlueQuantum:
1130 case YellowQuantum:
1131 {
cristy6c9e1682012-01-07 21:37:44 +00001132 *q=ScaleQuantumToLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001133 break;
1134 }
1135 case AlphaQuantum:
1136 {
cristy6c9e1682012-01-07 21:37:44 +00001137 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001138 break;
1139 }
1140 case OpacityQuantum:
1141 {
cristy6c9e1682012-01-07 21:37:44 +00001142 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001143 break;
1144 }
1145 case BlackQuantum:
1146 {
1147 if (image->colorspace == CMYKColorspace)
cristy6c9e1682012-01-07 21:37:44 +00001148 *q=ScaleQuantumToLong(GetPixelBlack(image,p));
cristye5370942012-01-06 03:49:31 +00001149 break;
1150 }
1151 case IndexQuantum:
1152 {
cristy6c9e1682012-01-07 21:37:44 +00001153 *q=ScaleQuantumToLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001154 break;
1155 }
1156 default:
cristy6c9e1682012-01-07 21:37:44 +00001157 break;
cristye5370942012-01-06 03:49:31 +00001158 }
1159 q++;
1160 }
1161 p+=GetPixelChannels(image);
1162 }
1163 }
1164}
1165
cristy6c9e1682012-01-07 21:37:44 +00001166static void ExportLongLongPixel(const Image *image,const ssize_t x_offset,
cristye5370942012-01-06 03:49:31 +00001167 const ssize_t y_offset,const size_t columns,const size_t rows,
cristy46f4be22012-01-07 00:26:39 +00001168 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1169 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001170{
1171 register const Quantum
1172 *restrict p;
1173
1174 register ssize_t
1175 x;
1176
cristyb13e12a2012-01-06 21:48:27 +00001177 register MagickSizeType
cristy3fe11452012-01-09 01:27:42 +00001178 *restrict q;
cristye5370942012-01-06 03:49:31 +00001179
1180 ssize_t
1181 y;
1182
cristyb13e12a2012-01-06 21:48:27 +00001183 q=(MagickSizeType *) pixels;
cristye5370942012-01-06 03:49:31 +00001184 if (LocaleCompare(map,"BGR") == 0)
1185 {
1186 for (y=0; y < (ssize_t) rows; y++)
1187 {
1188 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1189 if (p == (const Quantum *) NULL)
1190 break;
1191 for (x=0; x < (ssize_t) columns; x++)
1192 {
cristyb13e12a2012-01-06 21:48:27 +00001193 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1194 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1195 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001196 p+=GetPixelChannels(image);
1197 }
1198 }
1199 return;
1200 }
1201 if (LocaleCompare(map,"BGRA") == 0)
1202 {
1203 for (y=0; y < (ssize_t) rows; y++)
1204 {
1205 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1206 if (p == (const Quantum *) NULL)
1207 break;
1208 for (x=0; x < (ssize_t) columns; x++)
1209 {
cristyb13e12a2012-01-06 21:48:27 +00001210 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1211 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1212 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1213 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001214 p+=GetPixelChannels(image);
1215 }
1216 }
1217 return;
1218 }
1219 if (LocaleCompare(map,"BGRP") == 0)
1220 {
1221 for (y=0; y < (ssize_t) rows; y++)
1222 {
1223 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1224 if (p == (const Quantum *) NULL)
1225 break;
1226 for (x=0; x < (ssize_t) columns; x++)
1227 {
cristyb13e12a2012-01-06 21:48:27 +00001228 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1229 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1230 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001231 *q++=0;
1232 p+=GetPixelChannels(image);
1233 }
1234 }
1235 return;
1236 }
1237 if (LocaleCompare(map,"I") == 0)
1238 {
1239 for (y=0; y < (ssize_t) rows; y++)
1240 {
1241 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1242 if (p == (const Quantum *) NULL)
1243 break;
1244 for (x=0; x < (ssize_t) columns; x++)
1245 {
cristyb13e12a2012-01-06 21:48:27 +00001246 *q++=ScaleQuantumToLongLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001247 p+=GetPixelChannels(image);
1248 }
1249 }
1250 return;
1251 }
1252 if (LocaleCompare(map,"RGB") == 0)
1253 {
1254 for (y=0; y < (ssize_t) rows; y++)
1255 {
1256 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1257 if (p == (const Quantum *) NULL)
1258 break;
1259 for (x=0; x < (ssize_t) columns; x++)
1260 {
cristyb13e12a2012-01-06 21:48:27 +00001261 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1262 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1263 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001264 p+=GetPixelChannels(image);
1265 }
1266 }
1267 return;
1268 }
1269 if (LocaleCompare(map,"RGBA") == 0)
1270 {
1271 for (y=0; y < (ssize_t) rows; y++)
1272 {
1273 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1274 if (p == (const Quantum *) NULL)
1275 break;
1276 for (x=0; x < (ssize_t) columns; x++)
1277 {
cristyb13e12a2012-01-06 21:48:27 +00001278 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1279 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1280 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1281 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001282 p+=GetPixelChannels(image);
1283 }
1284 }
1285 return;
1286 }
1287 if (LocaleCompare(map,"RGBP") == 0)
1288 {
1289 for (y=0; y < (ssize_t) rows; y++)
1290 {
1291 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1292 if (p == (const Quantum *) NULL)
1293 break;
1294 for (x=0; x < (ssize_t) columns; x++)
1295 {
cristyb13e12a2012-01-06 21:48:27 +00001296 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1297 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1298 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001299 *q++=0;
1300 p+=GetPixelChannels(image);
1301 }
1302 }
1303 return;
1304 }
1305 for (y=0; y < (ssize_t) rows; y++)
1306 {
1307 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1308 if (p == (const Quantum *) NULL)
1309 break;
1310 for (x=0; x < (ssize_t) columns; x++)
1311 {
1312 register ssize_t
1313 i;
1314
1315 for (i=0; i < (ssize_t) strlen(map); i++)
1316 {
1317 *q=0;
1318 switch (quantum_map[i])
1319 {
1320 case RedQuantum:
1321 case CyanQuantum:
1322 {
cristyb13e12a2012-01-06 21:48:27 +00001323 *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001324 break;
1325 }
1326 case GreenQuantum:
1327 case MagentaQuantum:
1328 {
cristyb13e12a2012-01-06 21:48:27 +00001329 *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
cristye5370942012-01-06 03:49:31 +00001330 break;
1331 }
1332 case BlueQuantum:
1333 case YellowQuantum:
1334 {
cristyb13e12a2012-01-06 21:48:27 +00001335 *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001336 break;
1337 }
1338 case AlphaQuantum:
1339 {
cristyb13e12a2012-01-06 21:48:27 +00001340 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001341 break;
1342 }
1343 case OpacityQuantum:
1344 {
cristyb13e12a2012-01-06 21:48:27 +00001345 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001346 break;
1347 }
1348 case BlackQuantum:
1349 {
1350 if (image->colorspace == CMYKColorspace)
cristyb13e12a2012-01-06 21:48:27 +00001351 *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
cristye5370942012-01-06 03:49:31 +00001352 break;
1353 }
1354 case IndexQuantum:
1355 {
cristyb13e12a2012-01-06 21:48:27 +00001356 *q=ScaleQuantumToLongLong(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001357 break;
1358 }
1359 default:
1360 break;
1361 }
1362 q++;
1363 }
1364 p+=GetPixelChannels(image);
1365 }
1366 }
1367}
1368
1369static void ExportQuantumPixel(const Image *image,const ssize_t x_offset,
1370 const ssize_t y_offset,const size_t columns,const size_t rows,
cristy46f4be22012-01-07 00:26:39 +00001371 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1372 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001373{
1374 register const Quantum
1375 *restrict p;
1376
1377 register Quantum
cristy3fe11452012-01-09 01:27:42 +00001378 *restrict q;
cristye5370942012-01-06 03:49:31 +00001379
1380 register ssize_t
1381 x;
1382
1383 ssize_t
1384 y;
1385
1386 q=(Quantum *) pixels;
1387 if (LocaleCompare(map,"BGR") == 0)
1388 {
1389 for (y=0; y < (ssize_t) rows; y++)
1390 {
1391 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1392 if (p == (const Quantum *) NULL)
1393 break;
1394 for (x=0; x < (ssize_t) columns; x++)
1395 {
1396 *q++=GetPixelBlue(image,p);
1397 *q++=GetPixelGreen(image,p);
1398 *q++=GetPixelRed(image,p);
1399 p+=GetPixelChannels(image);
1400 }
1401 }
1402 return;
1403 }
1404 if (LocaleCompare(map,"BGRA") == 0)
1405 {
1406 for (y=0; y < (ssize_t) rows; y++)
1407 {
1408 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1409 if (p == (const Quantum *) NULL)
1410 break;
1411 for (x=0; x < (ssize_t) columns; x++)
1412 {
1413 *q++=GetPixelBlue(image,p);
1414 *q++=GetPixelGreen(image,p);
1415 *q++=GetPixelRed(image,p);
1416 *q++=(Quantum) (GetPixelAlpha(image,p));
1417 p+=GetPixelChannels(image);
1418 }
1419 }
1420 return;
1421 }
1422 if (LocaleCompare(map,"BGRP") == 0)
1423 {
1424 for (y=0; y < (ssize_t) rows; y++)
1425 {
1426 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1427 if (p == (const Quantum *) NULL)
1428 break;
1429 for (x=0; x < (ssize_t) columns; x++)
1430 {
1431 *q++=GetPixelBlue(image,p);
1432 *q++=GetPixelGreen(image,p);
1433 *q++=GetPixelRed(image,p);
1434 *q++=(Quantum) 0;
1435 p+=GetPixelChannels(image);
1436 }
1437 }
1438 return;
1439 }
1440 if (LocaleCompare(map,"I") == 0)
1441 {
1442 for (y=0; y < (ssize_t) rows; y++)
1443 {
1444 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1445 if (p == (const Quantum *) NULL)
1446 break;
1447 for (x=0; x < (ssize_t) columns; x++)
1448 {
1449 *q++=GetPixelIntensity(image,p);
1450 p+=GetPixelChannels(image);
1451 }
1452 }
1453 return;
1454 }
1455 if (LocaleCompare(map,"RGB") == 0)
1456 {
1457 for (y=0; y < (ssize_t) rows; y++)
1458 {
1459 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1460 if (p == (const Quantum *) NULL)
1461 break;
1462 for (x=0; x < (ssize_t) columns; x++)
1463 {
1464 *q++=GetPixelRed(image,p);
1465 *q++=GetPixelGreen(image,p);
1466 *q++=GetPixelBlue(image,p);
1467 p+=GetPixelChannels(image);
1468 }
1469 }
1470 return;
1471 }
1472 if (LocaleCompare(map,"RGBA") == 0)
1473 {
1474 for (y=0; y < (ssize_t) rows; y++)
1475 {
1476 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1477 if (p == (const Quantum *) NULL)
1478 break;
1479 for (x=0; x < (ssize_t) columns; x++)
1480 {
1481 *q++=GetPixelRed(image,p);
1482 *q++=GetPixelGreen(image,p);
1483 *q++=GetPixelBlue(image,p);
1484 *q++=(Quantum) (GetPixelAlpha(image,p));
1485 p+=GetPixelChannels(image);
1486 }
1487 }
1488 return;
1489 }
1490 if (LocaleCompare(map,"RGBP") == 0)
1491 {
1492 for (y=0; y < (ssize_t) rows; y++)
1493 {
1494 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1495 if (p == (const Quantum *) NULL)
1496 break;
1497 for (x=0; x < (ssize_t) columns; x++)
1498 {
1499 *q++=GetPixelRed(image,p);
1500 *q++=GetPixelGreen(image,p);
1501 *q++=GetPixelBlue(image,p);
1502 *q++=(Quantum) 0;
1503 p+=GetPixelChannels(image);
1504 }
1505 }
1506 return;
1507 }
1508 for (y=0; y < (ssize_t) rows; y++)
1509 {
1510 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1511 if (p == (const Quantum *) NULL)
1512 break;
1513 for (x=0; x < (ssize_t) columns; x++)
1514 {
1515 register ssize_t
1516 i;
1517
1518 for (i=0; i < (ssize_t) strlen(map); i++)
1519 {
1520 *q=(Quantum) 0;
1521 switch (quantum_map[i])
1522 {
1523 case RedQuantum:
1524 case CyanQuantum:
1525 {
1526 *q=GetPixelRed(image,p);
1527 break;
1528 }
1529 case GreenQuantum:
1530 case MagentaQuantum:
1531 {
1532 *q=GetPixelGreen(image,p);
1533 break;
1534 }
1535 case BlueQuantum:
1536 case YellowQuantum:
1537 {
1538 *q=GetPixelBlue(image,p);
1539 break;
1540 }
1541 case AlphaQuantum:
1542 {
1543 *q=GetPixelAlpha(image,p);
1544 break;
1545 }
1546 case OpacityQuantum:
1547 {
1548 *q=GetPixelAlpha(image,p);
1549 break;
1550 }
1551 case BlackQuantum:
1552 {
1553 if (image->colorspace == CMYKColorspace)
1554 *q=GetPixelBlack(image,p);
1555 break;
1556 }
1557 case IndexQuantum:
1558 {
1559 *q=(GetPixelIntensity(image,p));
1560 break;
1561 }
1562 default:
1563 {
1564 *q=(Quantum) 0;
1565 break;
1566 }
1567 }
1568 q++;
1569 }
1570 p+=GetPixelChannels(image);
1571 }
1572 }
1573}
1574
1575static void ExportShortPixel(const Image *image,const ssize_t x_offset,
1576 const ssize_t y_offset,const size_t columns,const size_t rows,
cristy46f4be22012-01-07 00:26:39 +00001577 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1578 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001579{
1580 register const Quantum
1581 *restrict p;
1582
1583 register ssize_t
1584 x;
1585
1586 ssize_t
1587 y;
1588
1589 register unsigned short
cristy3fe11452012-01-09 01:27:42 +00001590 *restrict q;
cristye5370942012-01-06 03:49:31 +00001591
1592 q=(unsigned short *) pixels;
1593 if (LocaleCompare(map,"BGR") == 0)
1594 {
1595 for (y=0; y < (ssize_t) rows; y++)
1596 {
1597 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1598 if (p == (const Quantum *) NULL)
1599 break;
1600 for (x=0; x < (ssize_t) columns; x++)
1601 {
1602 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1603 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1604 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1605 p+=GetPixelChannels(image);
1606 }
1607 }
1608 return;
1609 }
1610 if (LocaleCompare(map,"BGRA") == 0)
1611 {
1612 for (y=0; y < (ssize_t) rows; y++)
1613 {
1614 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1615 if (p == (const Quantum *) NULL)
1616 break;
1617 for (x=0; x < (ssize_t) columns; x++)
1618 {
1619 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1620 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1621 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1622 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1623 p+=GetPixelChannels(image);
1624 }
1625 }
1626 return;
1627 }
1628 if (LocaleCompare(map,"BGRP") == 0)
1629 {
1630 for (y=0; y < (ssize_t) rows; y++)
1631 {
1632 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1633 if (p == (const Quantum *) NULL)
1634 break;
1635 for (x=0; x < (ssize_t) columns; x++)
1636 {
1637 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1638 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1639 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1640 *q++=0;
1641 p+=GetPixelChannels(image);
1642 }
1643 }
1644 return;
1645 }
1646 if (LocaleCompare(map,"I") == 0)
1647 {
1648 for (y=0; y < (ssize_t) rows; y++)
1649 {
1650 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1651 if (p == (const Quantum *) NULL)
1652 break;
1653 for (x=0; x < (ssize_t) columns; x++)
1654 {
1655 *q++=ScaleQuantumToShort(GetPixelIntensity(image,p));
1656 p+=GetPixelChannels(image);
1657 }
1658 }
1659 return;
1660 }
1661 if (LocaleCompare(map,"RGB") == 0)
1662 {
1663 for (y=0; y < (ssize_t) rows; y++)
1664 {
1665 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1666 if (p == (const Quantum *) NULL)
1667 break;
1668 for (x=0; x < (ssize_t) columns; x++)
1669 {
1670 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1671 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1672 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1673 p+=GetPixelChannels(image);
1674 }
1675 }
1676 return;
1677 }
1678 if (LocaleCompare(map,"RGBA") == 0)
1679 {
1680 for (y=0; y < (ssize_t) rows; y++)
1681 {
1682 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1683 if (p == (const Quantum *) NULL)
1684 break;
1685 for (x=0; x < (ssize_t) columns; x++)
1686 {
1687 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1688 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1689 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1690 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1691 p+=GetPixelChannels(image);
1692 }
1693 }
1694 return;
1695 }
1696 if (LocaleCompare(map,"RGBP") == 0)
1697 {
1698 for (y=0; y < (ssize_t) rows; y++)
1699 {
1700 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1701 if (p == (const Quantum *) NULL)
1702 break;
1703 for (x=0; x < (ssize_t) columns; x++)
1704 {
1705 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1706 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1707 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1708 *q++=0;
1709 p+=GetPixelChannels(image);
1710 }
1711 }
1712 return;
1713 }
1714 for (y=0; y < (ssize_t) rows; y++)
1715 {
1716 p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1717 if (p == (const Quantum *) NULL)
1718 break;
1719 for (x=0; x < (ssize_t) columns; x++)
1720 {
1721 register ssize_t
1722 i;
1723
1724 for (i=0; i < (ssize_t) strlen(map); i++)
1725 {
1726 *q=0;
1727 switch (quantum_map[i])
1728 {
1729 case RedQuantum:
1730 case CyanQuantum:
1731 {
1732 *q=ScaleQuantumToShort(GetPixelRed(image,p));
1733 break;
1734 }
1735 case GreenQuantum:
1736 case MagentaQuantum:
1737 {
1738 *q=ScaleQuantumToShort(GetPixelGreen(image,p));
1739 break;
1740 }
1741 case BlueQuantum:
1742 case YellowQuantum:
1743 {
1744 *q=ScaleQuantumToShort(GetPixelBlue(image,p));
1745 break;
1746 }
1747 case AlphaQuantum:
1748 {
1749 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1750 break;
1751 }
1752 case OpacityQuantum:
1753 {
1754 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1755 break;
1756 }
1757 case BlackQuantum:
1758 {
1759 if (image->colorspace == CMYKColorspace)
1760 *q=ScaleQuantumToShort(GetPixelBlack(image,p));
1761 break;
1762 }
1763 case IndexQuantum:
1764 {
1765 *q=ScaleQuantumToShort(GetPixelIntensity(image,p));
1766 break;
1767 }
1768 default:
1769 break;
1770 }
1771 q++;
1772 }
1773 p+=GetPixelChannels(image);
1774 }
1775 }
1776}
1777
cristy4c08aed2011-07-01 19:47:50 +00001778MagickExport MagickBooleanType ExportImagePixels(const Image *image,
1779 const ssize_t x_offset,const ssize_t y_offset,const size_t columns,
1780 const size_t rows,const char *map,const StorageType type,void *pixels,
1781 ExceptionInfo *exception)
1782{
1783 QuantumType
1784 *quantum_map;
1785
1786 register ssize_t
cristye5370942012-01-06 03:49:31 +00001787 i;
cristy4c08aed2011-07-01 19:47:50 +00001788
1789 assert(image != (Image *) NULL);
1790 assert(image->signature == MagickSignature);
1791 if (image->debug != MagickFalse)
1792 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristye5370942012-01-06 03:49:31 +00001793 quantum_map=(QuantumType *) AcquireQuantumMemory(strlen(map),
1794 sizeof(*quantum_map));
cristy4c08aed2011-07-01 19:47:50 +00001795 if (quantum_map == (QuantumType *) NULL)
1796 {
1797 (void) ThrowMagickException(exception,GetMagickModule(),
1798 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1799 return(MagickFalse);
1800 }
cristye5370942012-01-06 03:49:31 +00001801 for (i=0; i < (ssize_t) strlen(map); i++)
cristy4c08aed2011-07-01 19:47:50 +00001802 {
1803 switch (map[i])
1804 {
1805 case 'A':
1806 case 'a':
1807 {
1808 quantum_map[i]=AlphaQuantum;
1809 break;
1810 }
1811 case 'B':
1812 case 'b':
1813 {
1814 quantum_map[i]=BlueQuantum;
1815 break;
1816 }
1817 case 'C':
1818 case 'c':
1819 {
1820 quantum_map[i]=CyanQuantum;
1821 if (image->colorspace == CMYKColorspace)
1822 break;
1823 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1824 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1825 "ColorSeparatedImageRequired","`%s'",map);
1826 return(MagickFalse);
1827 }
1828 case 'g':
1829 case 'G':
1830 {
1831 quantum_map[i]=GreenQuantum;
1832 break;
1833 }
1834 case 'I':
1835 case 'i':
1836 {
1837 quantum_map[i]=IndexQuantum;
1838 break;
1839 }
1840 case 'K':
1841 case 'k':
1842 {
1843 quantum_map[i]=BlackQuantum;
1844 if (image->colorspace == CMYKColorspace)
1845 break;
1846 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1847 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1848 "ColorSeparatedImageRequired","`%s'",map);
1849 return(MagickFalse);
1850 }
1851 case 'M':
1852 case 'm':
1853 {
1854 quantum_map[i]=MagentaQuantum;
1855 if (image->colorspace == CMYKColorspace)
1856 break;
1857 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1858 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1859 "ColorSeparatedImageRequired","`%s'",map);
1860 return(MagickFalse);
1861 }
1862 case 'o':
1863 case 'O':
1864 {
1865 quantum_map[i]=OpacityQuantum;
1866 break;
1867 }
1868 case 'P':
1869 case 'p':
1870 {
1871 quantum_map[i]=UndefinedQuantum;
1872 break;
1873 }
1874 case 'R':
1875 case 'r':
1876 {
1877 quantum_map[i]=RedQuantum;
1878 break;
1879 }
1880 case 'Y':
1881 case 'y':
1882 {
1883 quantum_map[i]=YellowQuantum;
1884 if (image->colorspace == CMYKColorspace)
1885 break;
1886 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1887 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1888 "ColorSeparatedImageRequired","`%s'",map);
1889 return(MagickFalse);
1890 }
1891 default:
1892 {
1893 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1894 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
1895 "UnrecognizedPixelMap","`%s'",map);
1896 return(MagickFalse);
1897 }
1898 }
1899 }
1900 switch (type)
1901 {
1902 case CharPixel:
1903 {
cristye5370942012-01-06 03:49:31 +00001904 ExportCharPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
1905 pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001906 break;
1907 }
1908 case DoublePixel:
1909 {
cristye5370942012-01-06 03:49:31 +00001910 ExportDoublePixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
1911 pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001912 break;
1913 }
1914 case FloatPixel:
1915 {
cristye5370942012-01-06 03:49:31 +00001916 ExportFloatPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
1917 pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001918 break;
1919 }
cristy4c08aed2011-07-01 19:47:50 +00001920 case LongPixel:
1921 {
cristye5370942012-01-06 03:49:31 +00001922 ExportLongPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
1923 pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001924 break;
1925 }
cristy6c9e1682012-01-07 21:37:44 +00001926 case LongLongPixel:
1927 {
1928 ExportLongLongPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
1929 pixels,exception);
1930 break;
1931 }
cristy4c08aed2011-07-01 19:47:50 +00001932 case QuantumPixel:
1933 {
cristye5370942012-01-06 03:49:31 +00001934 ExportQuantumPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
1935 pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001936 break;
1937 }
1938 case ShortPixel:
1939 {
cristye5370942012-01-06 03:49:31 +00001940 ExportShortPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
1941 pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00001942 break;
1943 }
1944 default:
1945 {
1946 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1947 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
1948 "UnrecognizedPixelMap","`%s'",map);
1949 break;
1950 }
1951 }
1952 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1953 return(MagickTrue);
1954}
1955
1956/*
1957%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1958% %
1959% %
1960% %
cristyaa8634f2011-10-01 13:25:12 +00001961% G e t P i x e l I n f o %
cristy4c08aed2011-07-01 19:47:50 +00001962% %
1963% %
1964% %
1965%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1966%
1967% GetPixelInfo() initializes the PixelInfo structure.
1968%
1969% The format of the GetPixelInfo method is:
1970%
1971% GetPixelInfo(const Image *image,PixelInfo *pixel)
1972%
1973% A description of each parameter follows:
1974%
1975% o image: the image.
1976%
cristy101ab702011-10-13 13:06:32 +00001977% o pixel: Specifies a pointer to a PixelInfo structure.
cristy4c08aed2011-07-01 19:47:50 +00001978%
1979*/
cristyaa8634f2011-10-01 13:25:12 +00001980MagickExport void GetPixelInfo(const Image *image,PixelInfo *pixel)
cristy4c08aed2011-07-01 19:47:50 +00001981{
1982 pixel->storage_class=DirectClass;
1983 pixel->colorspace=RGBColorspace;
1984 pixel->matte=MagickFalse;
1985 pixel->fuzz=0.0;
1986 pixel->depth=MAGICKCORE_QUANTUM_DEPTH;
1987 pixel->red=0.0;
1988 pixel->green=0.0;
1989 pixel->blue=0.0;
1990 pixel->black=0.0;
1991 pixel->alpha=(MagickRealType) OpaqueAlpha;
1992 pixel->index=0.0;
1993 if (image == (const Image *) NULL)
1994 return;
1995 pixel->storage_class=image->storage_class;
1996 pixel->colorspace=image->colorspace;
1997 pixel->matte=image->matte;
1998 pixel->depth=image->depth;
1999 pixel->fuzz=image->fuzz;
2000}
2001
2002/*
2003%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2004% %
2005% %
2006% %
2007% I m p o r t I m a g e P i x e l s %
2008% %
2009% %
2010% %
2011%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2012%
2013% ImportImagePixels() accepts pixel data and stores in the image at the
2014% location you specify. The method returns MagickTrue on success otherwise
2015% MagickFalse if an error is encountered. The pixel data can be either char,
2016% short int, int, ssize_t, float, or double in the order specified by map.
2017%
2018% Suppose your want to upload the first scanline of a 640x480 image from
2019% character data in red-green-blue order:
2020%
2021% ImportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels);
2022%
2023% The format of the ImportImagePixels method is:
2024%
2025% MagickBooleanType ImportImagePixels(Image *image,const ssize_t x_offset,
2026% const ssize_t y_offset,const size_t columns,
2027% const size_t rows,const char *map,const StorageType type,
cristy018f07f2011-09-04 21:15:19 +00002028% const void *pixels,ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00002029%
2030% A description of each parameter follows:
2031%
2032% o image: the image.
2033%
2034% o x_offset,y_offset,columns,rows: These values define the perimeter
2035% of a region of pixels you want to define.
2036%
2037% o map: This string reflects the expected ordering of the pixel array.
2038% It can be any combination or order of R = red, G = green, B = blue,
2039% A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
2040% Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
2041% P = pad.
2042%
2043% o type: Define the data type of the pixels. Float and double types are
2044% normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
cristy6c9e1682012-01-07 21:37:44 +00002045% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
2046% LongPixel (unsigned int *), LongLongPixel (unsigned long *),
2047% QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
cristy4c08aed2011-07-01 19:47:50 +00002048%
2049% o pixels: This array of values contain the pixel components as defined by
2050% map and type. You must preallocate this array where the expected
2051% length varies depending on the values of width, height, map, and type.
2052%
cristy018f07f2011-09-04 21:15:19 +00002053% o exception: return any errors or warnings in this structure.
2054%
cristy4c08aed2011-07-01 19:47:50 +00002055*/
cristye5370942012-01-06 03:49:31 +00002056
2057static void ImportCharPixel(Image *image,const ssize_t x_offset,
2058 const ssize_t y_offset,const size_t columns,const size_t rows,
cristy46f4be22012-01-07 00:26:39 +00002059 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2060 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002061{
2062 register const unsigned char
2063 *restrict p;
2064
2065 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002066 *restrict q;
cristye5370942012-01-06 03:49:31 +00002067
2068 register ssize_t
2069 x;
2070
2071 ssize_t
2072 y;
2073
2074 p=(const unsigned char *) pixels;
2075 if (LocaleCompare(map,"BGR") == 0)
2076 {
2077 for (y=0; y < (ssize_t) rows; y++)
2078 {
2079 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2080 if (q == (Quantum *) NULL)
2081 break;
2082 for (x=0; x < (ssize_t) columns; x++)
2083 {
2084 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2085 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2086 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2087 q+=GetPixelChannels(image);
2088 }
2089 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2090 break;
2091 }
2092 return;
2093 }
2094 if (LocaleCompare(map,"BGRA") == 0)
2095 {
2096 for (y=0; y < (ssize_t) rows; y++)
2097 {
2098 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2099 if (q == (Quantum *) NULL)
2100 break;
2101 for (x=0; x < (ssize_t) columns; x++)
2102 {
2103 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2104 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2105 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2106 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2107 q+=GetPixelChannels(image);
2108 }
2109 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2110 break;
2111 }
2112 return;
2113 }
2114 if (LocaleCompare(map,"BGRO") == 0)
2115 {
2116 for (y=0; y < (ssize_t) rows; y++)
2117 {
2118 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2119 if (q == (Quantum *) NULL)
2120 break;
2121 for (x=0; x < (ssize_t) columns; x++)
2122 {
2123 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2124 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2125 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2126 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2127 q+=GetPixelChannels(image);
2128 }
2129 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2130 break;
2131 }
2132 return;
2133 }
2134 if (LocaleCompare(map,"BGRP") == 0)
2135 {
2136 for (y=0; y < (ssize_t) rows; y++)
2137 {
2138 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2139 if (q == (Quantum *) NULL)
2140 break;
2141 for (x=0; x < (ssize_t) columns; x++)
2142 {
2143 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2144 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2145 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2146 p++;
2147 q+=GetPixelChannels(image);
2148 }
2149 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2150 break;
2151 }
2152 return;
2153 }
2154 if (LocaleCompare(map,"I") == 0)
2155 {
2156 for (y=0; y < (ssize_t) rows; y++)
2157 {
2158 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2159 if (q == (Quantum *) NULL)
2160 break;
2161 for (x=0; x < (ssize_t) columns; x++)
2162 {
2163 SetPixelGray(image,ScaleCharToQuantum(*p++),q);
2164 q+=GetPixelChannels(image);
2165 }
2166 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2167 break;
2168 }
2169 return;
2170 }
2171 if (LocaleCompare(map,"RGB") == 0)
2172 {
2173 for (y=0; y < (ssize_t) rows; y++)
2174 {
2175 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2176 if (q == (Quantum *) NULL)
2177 break;
2178 for (x=0; x < (ssize_t) columns; x++)
2179 {
2180 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2181 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2182 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2183 q+=GetPixelChannels(image);
2184 }
2185 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2186 break;
2187 }
2188 return;
2189 }
2190 if (LocaleCompare(map,"RGBA") == 0)
2191 {
2192 for (y=0; y < (ssize_t) rows; y++)
2193 {
2194 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2195 if (q == (Quantum *) NULL)
2196 break;
2197 for (x=0; x < (ssize_t) columns; x++)
2198 {
2199 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2200 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2201 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2202 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2203 q+=GetPixelChannels(image);
2204 }
2205 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2206 break;
2207 }
2208 return;
2209 }
2210 if (LocaleCompare(map,"RGBO") == 0)
2211 {
2212 for (y=0; y < (ssize_t) rows; y++)
2213 {
2214 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2215 if (q == (Quantum *) NULL)
2216 break;
2217 for (x=0; x < (ssize_t) columns; x++)
2218 {
2219 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2220 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2221 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2222 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2223 q+=GetPixelChannels(image);
2224 }
2225 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2226 break;
2227 }
2228 return;
2229 }
2230 if (LocaleCompare(map,"RGBP") == 0)
2231 {
2232 for (y=0; y < (ssize_t) rows; y++)
2233 {
2234 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2235 if (q == (Quantum *) NULL)
2236 break;
2237 for (x=0; x < (ssize_t) columns; x++)
2238 {
2239 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2240 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2241 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2242 p++;
2243 q+=GetPixelChannels(image);
2244 }
2245 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2246 break;
2247 }
2248 return;
2249 }
2250 for (y=0; y < (ssize_t) rows; y++)
2251 {
2252 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2253 if (q == (Quantum *) NULL)
2254 break;
2255 for (x=0; x < (ssize_t) columns; x++)
2256 {
2257 register ssize_t
2258 i;
2259
2260 for (i=0; i < (ssize_t) strlen(map); i++)
2261 {
2262 switch (quantum_map[i])
2263 {
2264 case RedQuantum:
2265 case CyanQuantum:
2266 {
2267 SetPixelRed(image,ScaleCharToQuantum(*p),q);
2268 break;
2269 }
2270 case GreenQuantum:
2271 case MagentaQuantum:
2272 {
2273 SetPixelGreen(image,ScaleCharToQuantum(*p),q);
2274 break;
2275 }
2276 case BlueQuantum:
2277 case YellowQuantum:
2278 {
2279 SetPixelBlue(image,ScaleCharToQuantum(*p),q);
2280 break;
2281 }
2282 case AlphaQuantum:
2283 {
2284 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2285 break;
2286 }
2287 case OpacityQuantum:
2288 {
2289 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2290 break;
2291 }
2292 case BlackQuantum:
2293 {
2294 SetPixelBlack(image,ScaleCharToQuantum(*p),q);
2295 break;
2296 }
2297 case IndexQuantum:
2298 {
2299 SetPixelGray(image,ScaleCharToQuantum(*p),q);
2300 break;
2301 }
2302 default:
2303 break;
2304 }
2305 p++;
2306 }
2307 q+=GetPixelChannels(image);
2308 }
2309 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2310 break;
2311 }
2312}
2313
2314static void ImportDoublePixel(Image *image,const ssize_t x_offset,
2315 const ssize_t y_offset,const size_t columns,const size_t rows,
cristy46f4be22012-01-07 00:26:39 +00002316 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2317 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002318{
2319 register const double
2320 *restrict p;
2321
2322 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002323 *restrict q;
cristye5370942012-01-06 03:49:31 +00002324
2325 register ssize_t
2326 x;
2327
2328 ssize_t
2329 y;
2330
2331 p=(const double *) pixels;
2332 if (LocaleCompare(map,"BGR") == 0)
2333 {
2334 for (y=0; y < (ssize_t) rows; y++)
2335 {
2336 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2337 if (q == (Quantum *) NULL)
2338 break;
2339 for (x=0; x < (ssize_t) columns; x++)
2340 {
2341 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2342 (*p)),q);
2343 p++;
2344 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2345 (*p)),q);
2346 p++;
2347 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2348 (*p)),q);
2349 p++;
2350 q+=GetPixelChannels(image);
2351 }
2352 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2353 break;
2354 }
2355 return;
2356 }
2357 if (LocaleCompare(map,"BGRA") == 0)
2358 {
2359 for (y=0; y < (ssize_t) rows; y++)
2360 {
2361 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2362 if (q == (Quantum *) NULL)
2363 break;
2364 for (x=0; x < (ssize_t) columns; x++)
2365 {
2366 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2367 (*p)),q);
2368 p++;
2369 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2370 (*p)),q);
2371 p++;
2372 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2373 (*p)),q);
2374 p++;
2375 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2376 (*p)),q);
2377 p++;
2378 q+=GetPixelChannels(image);
2379 }
2380 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2381 break;
2382 }
2383 return;
2384 }
2385 if (LocaleCompare(map,"BGRP") == 0)
2386 {
2387 for (y=0; y < (ssize_t) rows; y++)
2388 {
2389 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2390 if (q == (Quantum *) NULL)
2391 break;
2392 for (x=0; x < (ssize_t) columns; x++)
2393 {
2394 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2395 (*p)),q);
2396 p++;
2397 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2398 (*p)),q);
2399 p++;
2400 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2401 (*p)),q);
2402 p++;
2403 p++;
2404 q+=GetPixelChannels(image);
2405 }
2406 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2407 break;
2408 }
2409 return;
2410 }
2411 if (LocaleCompare(map,"I") == 0)
2412 {
2413 for (y=0; y < (ssize_t) rows; y++)
2414 {
2415 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2416 if (q == (Quantum *) NULL)
2417 break;
2418 for (x=0; x < (ssize_t) columns; x++)
2419 {
2420 SetPixelGray(image,ClampToQuantum((MagickRealType) QuantumRange*
2421 (*p)),q);
2422 p++;
2423 q+=GetPixelChannels(image);
2424 }
2425 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2426 break;
2427 }
2428 return;
2429 }
2430 if (LocaleCompare(map,"RGB") == 0)
2431 {
2432 for (y=0; y < (ssize_t) rows; y++)
2433 {
2434 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2435 if (q == (Quantum *) NULL)
2436 break;
2437 for (x=0; x < (ssize_t) columns; x++)
2438 {
2439 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2440 (*p)),q);
2441 p++;
2442 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2443 (*p)),q);
2444 p++;
2445 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2446 (*p)),q);
2447 p++;
2448 q+=GetPixelChannels(image);
2449 }
2450 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2451 break;
2452 }
2453 return;
2454 }
2455 if (LocaleCompare(map,"RGBA") == 0)
2456 {
2457 for (y=0; y < (ssize_t) rows; y++)
2458 {
2459 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2460 if (q == (Quantum *) NULL)
2461 break;
2462 for (x=0; x < (ssize_t) columns; x++)
2463 {
2464 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2465 (*p)),q);
2466 p++;
2467 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2468 (*p)),q);
2469 p++;
2470 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2471 (*p)),q);
2472 p++;
2473 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2474 (*p)),q);
2475 p++;
2476 q+=GetPixelChannels(image);
2477 }
2478 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2479 break;
2480 }
2481 return;
2482 }
2483 if (LocaleCompare(map,"RGBP") == 0)
2484 {
2485 for (y=0; y < (ssize_t) rows; y++)
2486 {
2487 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2488 if (q == (Quantum *) NULL)
2489 break;
2490 for (x=0; x < (ssize_t) columns; x++)
2491 {
2492 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2493 (*p)),q);
2494 p++;
2495 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2496 (*p)),q);
2497 p++;
2498 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2499 (*p)),q);
2500 p++;
2501 q+=GetPixelChannels(image);
2502 }
2503 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2504 break;
2505 }
2506 return;
2507 }
2508 for (y=0; y < (ssize_t) rows; y++)
2509 {
2510 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2511 if (q == (Quantum *) NULL)
2512 break;
2513 for (x=0; x < (ssize_t) columns; x++)
2514 {
2515 register ssize_t
2516 i;
2517
2518 for (i=0; i < (ssize_t) strlen(map); i++)
2519 {
2520 switch (quantum_map[i])
2521 {
2522 case RedQuantum:
2523 case CyanQuantum:
2524 {
2525 SetPixelRed(image,ClampToQuantum((MagickRealType)
2526 QuantumRange*(*p)),q);
2527 break;
2528 }
2529 case GreenQuantum:
2530 case MagentaQuantum:
2531 {
2532 SetPixelGreen(image,ClampToQuantum((MagickRealType)
2533 QuantumRange*(*p)),q);
2534 break;
2535 }
2536 case BlueQuantum:
2537 case YellowQuantum:
2538 {
2539 SetPixelBlue(image,ClampToQuantum((MagickRealType)
2540 QuantumRange*(*p)),q);
2541 break;
2542 }
2543 case AlphaQuantum:
2544 {
2545 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2546 QuantumRange*(*p)),q);
2547 break;
2548 }
2549 case OpacityQuantum:
2550 {
2551 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2552 QuantumRange*(*p)),q);
2553 break;
2554 }
2555 case BlackQuantum:
2556 {
2557 SetPixelBlack(image,ClampToQuantum((MagickRealType)
2558 QuantumRange*(*p)),q);
2559 break;
2560 }
2561 case IndexQuantum:
2562 {
2563 SetPixelGray(image,ClampToQuantum((MagickRealType)
2564 QuantumRange*(*p)),q);
2565 break;
2566 }
2567 default:
2568 break;
2569 }
2570 p++;
2571 }
2572 q+=GetPixelChannels(image);
2573 }
2574 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2575 break;
2576 }
2577}
2578
2579static void ImportFloatPixel(Image *image,const ssize_t x_offset,
2580 const ssize_t y_offset,const size_t columns,const size_t rows,
cristy46f4be22012-01-07 00:26:39 +00002581 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2582 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002583{
2584 register const float
2585 *restrict p;
2586
2587 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002588 *restrict q;
cristye5370942012-01-06 03:49:31 +00002589
2590 register ssize_t
2591 x;
2592
2593 ssize_t
2594 y;
2595
2596 p=(const float *) pixels;
2597 if (LocaleCompare(map,"BGR") == 0)
2598 {
2599 for (y=0; y < (ssize_t) rows; y++)
2600 {
2601 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2602 if (q == (Quantum *) NULL)
2603 break;
2604 for (x=0; x < (ssize_t) columns; x++)
2605 {
2606 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2607 (*p)),q);
2608 p++;
2609 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2610 (*p)),q);
2611 p++;
2612 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2613 (*p)),q);
2614 p++;
2615 q+=GetPixelChannels(image);
2616 }
2617 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2618 break;
2619 }
2620 return;
2621 }
2622 if (LocaleCompare(map,"BGRA") == 0)
2623 {
2624 for (y=0; y < (ssize_t) rows; y++)
2625 {
2626 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2627 if (q == (Quantum *) NULL)
2628 break;
2629 for (x=0; x < (ssize_t) columns; x++)
2630 {
2631 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2632 (*p)),q);
2633 p++;
2634 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2635 (*p)),q);
2636 p++;
2637 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2638 (*p)),q);
2639 p++;
2640 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2641 (*p)),q);
2642 p++;
2643 q+=GetPixelChannels(image);
2644 }
2645 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2646 break;
2647 }
2648 return;
2649 }
2650 if (LocaleCompare(map,"BGRP") == 0)
2651 {
2652 for (y=0; y < (ssize_t) rows; y++)
2653 {
2654 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2655 if (q == (Quantum *) NULL)
2656 break;
2657 for (x=0; x < (ssize_t) columns; x++)
2658 {
2659 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2660 (*p)),q);
2661 p++;
2662 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2663 (*p)),q);
2664 p++;
2665 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2666 (*p)),q);
2667 p++;
2668 p++;
2669 q+=GetPixelChannels(image);
2670 }
2671 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2672 break;
2673 }
2674 return;
2675 }
2676 if (LocaleCompare(map,"I") == 0)
2677 {
2678 for (y=0; y < (ssize_t) rows; y++)
2679 {
2680 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2681 if (q == (Quantum *) NULL)
2682 break;
2683 for (x=0; x < (ssize_t) columns; x++)
2684 {
2685 SetPixelGray(image,ClampToQuantum((MagickRealType) QuantumRange*
2686 (*p)),q);
2687 p++;
2688 q+=GetPixelChannels(image);
2689 }
2690 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2691 break;
2692 }
2693 return;
2694 }
2695 if (LocaleCompare(map,"RGB") == 0)
2696 {
2697 for (y=0; y < (ssize_t) rows; y++)
2698 {
2699 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2700 if (q == (Quantum *) NULL)
2701 break;
2702 for (x=0; x < (ssize_t) columns; x++)
2703 {
2704 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2705 (*p)),q);
2706 p++;
2707 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2708 (*p)),q);
2709 p++;
2710 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2711 (*p)),q);
2712 p++;
2713 q+=GetPixelChannels(image);
2714 }
2715 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2716 break;
2717 }
2718 return;
2719 }
2720 if (LocaleCompare(map,"RGBA") == 0)
2721 {
2722 for (y=0; y < (ssize_t) rows; y++)
2723 {
2724 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2725 if (q == (Quantum *) NULL)
2726 break;
2727 for (x=0; x < (ssize_t) columns; x++)
2728 {
2729 SetPixelRed(image,ClampToQuantum((MagickRealType)
2730 QuantumRange*(*p)),q);
2731 p++;
2732 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2733 (*p)),q);
2734 p++;
2735 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2736 (*p)),q);
2737 p++;
2738 SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2739 (*p)),q);
2740 p++;
2741 q+=GetPixelChannels(image);
2742 }
2743 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2744 break;
2745 }
2746 return;
2747 }
2748 if (LocaleCompare(map,"RGBP") == 0)
2749 {
2750 for (y=0; y < (ssize_t) rows; y++)
2751 {
2752 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2753 if (q == (Quantum *) NULL)
2754 break;
2755 for (x=0; x < (ssize_t) columns; x++)
2756 {
2757 SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2758 (*p)),q);
2759 p++;
2760 SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2761 (*p)),q);
2762 p++;
2763 SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2764 (*p)),q);
2765 p++;
2766 q+=GetPixelChannels(image);
2767 }
2768 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2769 break;
2770 }
2771 return;
2772 }
2773 for (y=0; y < (ssize_t) rows; y++)
2774 {
2775 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2776 if (q == (Quantum *) NULL)
2777 break;
2778 for (x=0; x < (ssize_t) columns; x++)
2779 {
2780 register ssize_t
2781 i;
2782
2783 for (i=0; i < (ssize_t) strlen(map); i++)
2784 {
2785 switch (quantum_map[i])
2786 {
2787 case RedQuantum:
2788 case CyanQuantum:
2789 {
2790 SetPixelRed(image,ClampToQuantum((MagickRealType)
2791 QuantumRange*(*p)),q);
2792 break;
2793 }
2794 case GreenQuantum:
2795 case MagentaQuantum:
2796 {
2797 SetPixelGreen(image,ClampToQuantum((MagickRealType)
2798 QuantumRange*(*p)),q);
2799 break;
2800 }
2801 case BlueQuantum:
2802 case YellowQuantum:
2803 {
2804 SetPixelBlue(image,ClampToQuantum((MagickRealType)
2805 QuantumRange*(*p)),q);
2806 break;
2807 }
2808 case AlphaQuantum:
2809 {
2810 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2811 QuantumRange*(*p)),q);
2812 break;
2813 }
2814 case OpacityQuantum:
2815 {
2816 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2817 QuantumRange*(*p)),q);
2818 break;
2819 }
2820 case BlackQuantum:
2821 {
2822 SetPixelBlack(image,ClampToQuantum((MagickRealType)
2823 QuantumRange*(*p)),q);
2824 break;
2825 }
2826 case IndexQuantum:
2827 {
2828 SetPixelGray(image,ClampToQuantum((MagickRealType)
2829 QuantumRange*(*p)),q);
2830 break;
2831 }
2832 default:
2833 break;
2834 }
2835 p++;
2836 }
2837 q+=GetPixelChannels(image);
2838 }
2839 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2840 break;
2841 }
2842}
2843
cristy6c9e1682012-01-07 21:37:44 +00002844static void ImportLongPixel(Image *image,const ssize_t x_offset,
cristye5370942012-01-06 03:49:31 +00002845 const ssize_t y_offset,const size_t columns,const size_t rows,
cristy46f4be22012-01-07 00:26:39 +00002846 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2847 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002848{
2849 register const unsigned int
2850 *restrict p;
2851
2852 register Quantum
cristy3fe11452012-01-09 01:27:42 +00002853 *restrict q;
cristye5370942012-01-06 03:49:31 +00002854
2855 register ssize_t
2856 x;
2857
2858 ssize_t
2859 y;
2860
2861 p=(const unsigned int *) pixels;
2862 if (LocaleCompare(map,"BGR") == 0)
2863 {
2864 for (y=0; y < (ssize_t) rows; y++)
2865 {
2866 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2867 if (q == (Quantum *) NULL)
2868 break;
2869 for (x=0; x < (ssize_t) columns; x++)
2870 {
2871 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2872 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2873 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2874 q+=GetPixelChannels(image);
2875 }
2876 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2877 break;
2878 }
2879 return;
2880 }
2881 if (LocaleCompare(map,"BGRA") == 0)
2882 {
2883 for (y=0; y < (ssize_t) rows; y++)
2884 {
2885 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2886 if (q == (Quantum *) NULL)
2887 break;
2888 for (x=0; x < (ssize_t) columns; x++)
2889 {
2890 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2891 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2892 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2893 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
2894 q+=GetPixelChannels(image);
2895 }
2896 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2897 break;
2898 }
2899 return;
2900 }
2901 if (LocaleCompare(map,"BGRP") == 0)
2902 {
2903 for (y=0; y < (ssize_t) rows; y++)
2904 {
2905 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2906 if (q == (Quantum *) NULL)
2907 break;
2908 for (x=0; x < (ssize_t) columns; x++)
2909 {
2910 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2911 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2912 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2913 p++;
2914 q+=GetPixelChannels(image);
2915 }
2916 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2917 break;
2918 }
2919 return;
2920 }
2921 if (LocaleCompare(map,"I") == 0)
2922 {
2923 for (y=0; y < (ssize_t) rows; y++)
2924 {
2925 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2926 if (q == (Quantum *) NULL)
2927 break;
2928 for (x=0; x < (ssize_t) columns; x++)
2929 {
2930 SetPixelGray(image,ScaleLongToQuantum(*p++),q);
2931 q+=GetPixelChannels(image);
2932 }
2933 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2934 break;
2935 }
2936 return;
2937 }
2938 if (LocaleCompare(map,"RGB") == 0)
2939 {
2940 for (y=0; y < (ssize_t) rows; y++)
2941 {
2942 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2943 if (q == (Quantum *) NULL)
2944 break;
2945 for (x=0; x < (ssize_t) columns; x++)
2946 {
2947 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2948 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2949 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2950 q+=GetPixelChannels(image);
2951 }
2952 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2953 break;
2954 }
2955 return;
2956 }
2957 if (LocaleCompare(map,"RGBA") == 0)
2958 {
2959 for (y=0; y < (ssize_t) rows; y++)
2960 {
2961 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2962 if (q == (Quantum *) NULL)
2963 break;
2964 for (x=0; x < (ssize_t) columns; x++)
2965 {
2966 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2967 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2968 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2969 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
2970 q+=GetPixelChannels(image);
2971 }
2972 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2973 break;
2974 }
2975 return;
2976 }
2977 if (LocaleCompare(map,"RGBP") == 0)
2978 {
2979 for (y=0; y < (ssize_t) rows; y++)
2980 {
2981 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2982 if (q == (Quantum *) NULL)
2983 break;
2984 for (x=0; x < (ssize_t) columns; x++)
2985 {
2986 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2987 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2988 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2989 p++;
2990 q+=GetPixelChannels(image);
2991 }
2992 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2993 break;
2994 }
2995 return;
2996 }
2997 for (y=0; y < (ssize_t) rows; y++)
2998 {
2999 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3000 if (q == (Quantum *) NULL)
3001 break;
3002 for (x=0; x < (ssize_t) columns; x++)
3003 {
3004 register ssize_t
3005 i;
3006
3007 for (i=0; i < (ssize_t) strlen(map); i++)
3008 {
3009 switch (quantum_map[i])
3010 {
3011 case RedQuantum:
3012 case CyanQuantum:
3013 {
3014 SetPixelRed(image,ScaleLongToQuantum(*p),q);
3015 break;
3016 }
3017 case GreenQuantum:
3018 case MagentaQuantum:
3019 {
3020 SetPixelGreen(image,ScaleLongToQuantum(*p),q);
3021 break;
3022 }
3023 case BlueQuantum:
3024 case YellowQuantum:
3025 {
3026 SetPixelBlue(image,ScaleLongToQuantum(*p),q);
3027 break;
3028 }
3029 case AlphaQuantum:
3030 {
3031 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3032 break;
3033 }
3034 case OpacityQuantum:
3035 {
3036 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3037 break;
3038 }
3039 case BlackQuantum:
3040 {
3041 SetPixelBlack(image,ScaleLongToQuantum(*p),q);
3042 break;
3043 }
3044 case IndexQuantum:
3045 {
3046 SetPixelGray(image,ScaleLongToQuantum(*p),q);
3047 break;
3048 }
3049 default:
3050 break;
3051 }
3052 p++;
3053 }
3054 q+=GetPixelChannels(image);
3055 }
3056 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3057 break;
3058 }
3059}
3060
cristy6c9e1682012-01-07 21:37:44 +00003061static void ImportLongLongPixel(Image *image,const ssize_t x_offset,
cristye5370942012-01-06 03:49:31 +00003062 const ssize_t y_offset,const size_t columns,const size_t rows,
cristy46f4be22012-01-07 00:26:39 +00003063 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3064 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003065{
cristyb13e12a2012-01-06 21:48:27 +00003066 register const MagickSizeType
cristye5370942012-01-06 03:49:31 +00003067 *restrict p;
3068
3069 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003070 *restrict q;
cristye5370942012-01-06 03:49:31 +00003071
3072 register ssize_t
3073 x;
3074
3075 ssize_t
3076 y;
3077
cristyb13e12a2012-01-06 21:48:27 +00003078 p=(const MagickSizeType *) pixels;
cristye5370942012-01-06 03:49:31 +00003079 if (LocaleCompare(map,"BGR") == 0)
3080 {
3081 for (y=0; y < (ssize_t) rows; y++)
3082 {
3083 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3084 if (q == (Quantum *) NULL)
3085 break;
3086 for (x=0; x < (ssize_t) columns; x++)
3087 {
cristyb13e12a2012-01-06 21:48:27 +00003088 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3089 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3090 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003091 q+=GetPixelChannels(image);
3092 }
3093 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3094 break;
3095 }
3096 return;
3097 }
3098 if (LocaleCompare(map,"BGRA") == 0)
3099 {
3100 for (y=0; y < (ssize_t) rows; y++)
3101 {
3102 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3103 if (q == (Quantum *) NULL)
3104 break;
3105 for (x=0; x < (ssize_t) columns; x++)
3106 {
cristyb13e12a2012-01-06 21:48:27 +00003107 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3108 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3109 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3110 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003111 q+=GetPixelChannels(image);
3112 }
3113 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3114 break;
3115 }
3116 return;
3117 }
3118 if (LocaleCompare(map,"BGRP") == 0)
3119 {
3120 for (y=0; y < (ssize_t) rows; y++)
3121 {
3122 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3123 if (q == (Quantum *) NULL)
3124 break;
3125 for (x=0; x < (ssize_t) columns; x++)
3126 {
cristyb13e12a2012-01-06 21:48:27 +00003127 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3128 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3129 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003130 p++;
3131 q+=GetPixelChannels(image);
3132 }
3133 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3134 break;
3135 }
3136 return;
3137 }
3138 if (LocaleCompare(map,"I") == 0)
3139 {
3140 for (y=0; y < (ssize_t) rows; y++)
3141 {
3142 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3143 if (q == (Quantum *) NULL)
3144 break;
3145 for (x=0; x < (ssize_t) columns; x++)
3146 {
cristyb13e12a2012-01-06 21:48:27 +00003147 SetPixelGray(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003148 q+=GetPixelChannels(image);
3149 }
3150 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3151 break;
3152 }
3153 return;
3154 }
3155 if (LocaleCompare(map,"RGB") == 0)
3156 {
3157 for (y=0; y < (ssize_t) rows; y++)
3158 {
3159 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3160 if (q == (Quantum *) NULL)
3161 break;
3162 for (x=0; x < (ssize_t) columns; x++)
3163 {
cristyb13e12a2012-01-06 21:48:27 +00003164 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3165 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3166 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003167 q+=GetPixelChannels(image);
3168 }
3169 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3170 break;
3171 }
3172 return;
3173 }
3174 if (LocaleCompare(map,"RGBA") == 0)
3175 {
3176 for (y=0; y < (ssize_t) rows; y++)
3177 {
3178 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3179 if (q == (Quantum *) NULL)
3180 break;
3181 for (x=0; x < (ssize_t) columns; x++)
3182 {
cristyb13e12a2012-01-06 21:48:27 +00003183 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3184 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3185 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3186 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003187 q+=GetPixelChannels(image);
3188 }
3189 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3190 break;
3191 }
3192 return;
3193 }
3194 if (LocaleCompare(map,"RGBP") == 0)
3195 {
3196 for (y=0; y < (ssize_t) rows; y++)
3197 {
3198 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3199 if (q == (Quantum *) NULL)
3200 break;
3201 for (x=0; x < (ssize_t) columns; x++)
3202 {
cristyb13e12a2012-01-06 21:48:27 +00003203 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3204 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3205 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003206 p++;
3207 q+=GetPixelChannels(image);
3208 }
3209 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3210 break;
3211 }
3212 return;
3213 }
3214 for (y=0; y < (ssize_t) rows; y++)
3215 {
3216 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3217 if (q == (Quantum *) NULL)
3218 break;
3219 for (x=0; x < (ssize_t) columns; x++)
3220 {
3221 register ssize_t
3222 i;
3223
3224 for (i=0; i < (ssize_t) strlen(map); i++)
3225 {
3226 switch (quantum_map[i])
3227 {
3228 case RedQuantum:
3229 case CyanQuantum:
3230 {
cristyb13e12a2012-01-06 21:48:27 +00003231 SetPixelRed(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003232 break;
3233 }
3234 case GreenQuantum:
3235 case MagentaQuantum:
3236 {
cristyb13e12a2012-01-06 21:48:27 +00003237 SetPixelGreen(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003238 break;
3239 }
3240 case BlueQuantum:
3241 case YellowQuantum:
3242 {
cristyb13e12a2012-01-06 21:48:27 +00003243 SetPixelBlue(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003244 break;
3245 }
3246 case AlphaQuantum:
3247 {
cristyb13e12a2012-01-06 21:48:27 +00003248 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003249 break;
3250 }
3251 case OpacityQuantum:
3252 {
cristyb13e12a2012-01-06 21:48:27 +00003253 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003254 break;
3255 }
3256 case BlackQuantum:
3257 {
cristyb13e12a2012-01-06 21:48:27 +00003258 SetPixelBlack(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003259 break;
3260 }
3261 case IndexQuantum:
3262 {
cristyb13e12a2012-01-06 21:48:27 +00003263 SetPixelGray(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003264 break;
3265 }
3266 default:
3267 break;
3268 }
3269 p++;
3270 }
3271 q+=GetPixelChannels(image);
3272 }
3273 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3274 break;
3275 }
3276}
3277
3278static void ImportQuantumPixel(Image *image,const ssize_t x_offset,
3279 const ssize_t y_offset,const size_t columns,const size_t rows,
cristy46f4be22012-01-07 00:26:39 +00003280 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3281 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003282{
3283 register const Quantum
3284 *restrict p;
3285
3286 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003287 *restrict q;
cristye5370942012-01-06 03:49:31 +00003288
3289 register ssize_t
3290 x;
3291
3292 ssize_t
3293 y;
3294
3295 p=(const Quantum *) pixels;
3296 if (LocaleCompare(map,"BGR") == 0)
3297 {
3298 for (y=0; y < (ssize_t) rows; y++)
3299 {
3300 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3301 if (q == (Quantum *) NULL)
3302 break;
3303 for (x=0; x < (ssize_t) columns; x++)
3304 {
3305 SetPixelBlue(image,*p++,q);
3306 SetPixelGreen(image,*p++,q);
3307 SetPixelRed(image,*p++,q);
3308 q+=GetPixelChannels(image);
3309 }
3310 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3311 break;
3312 }
3313 return;
3314 }
3315 if (LocaleCompare(map,"BGRA") == 0)
3316 {
3317 for (y=0; y < (ssize_t) rows; y++)
3318 {
3319 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3320 if (q == (Quantum *) NULL)
3321 break;
3322 for (x=0; x < (ssize_t) columns; x++)
3323 {
3324 SetPixelBlue(image,*p++,q);
3325 SetPixelGreen(image,*p++,q);
3326 SetPixelRed(image,*p++,q);
3327 SetPixelAlpha(image,*p++,q);
3328 q+=GetPixelChannels(image);
3329 }
3330 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3331 break;
3332 }
3333 return;
3334 }
3335 if (LocaleCompare(map,"BGRP") == 0)
3336 {
3337 for (y=0; y < (ssize_t) rows; y++)
3338 {
3339 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3340 if (q == (Quantum *) NULL)
3341 break;
3342 for (x=0; x < (ssize_t) columns; x++)
3343 {
3344 SetPixelBlue(image,*p++,q);
3345 SetPixelGreen(image,*p++,q);
3346 SetPixelRed(image,*p++,q);
3347 p++;
3348 q+=GetPixelChannels(image);
3349 }
3350 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3351 break;
3352 }
3353 return;
3354 }
3355 if (LocaleCompare(map,"I") == 0)
3356 {
3357 for (y=0; y < (ssize_t) rows; y++)
3358 {
3359 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3360 if (q == (Quantum *) NULL)
3361 break;
3362 for (x=0; x < (ssize_t) columns; x++)
3363 {
3364 SetPixelGray(image,*p++,q);
3365 q+=GetPixelChannels(image);
3366 }
3367 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3368 break;
3369 }
3370 return;
3371 }
3372 if (LocaleCompare(map,"RGB") == 0)
3373 {
3374 for (y=0; y < (ssize_t) rows; y++)
3375 {
3376 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3377 if (q == (Quantum *) NULL)
3378 break;
3379 for (x=0; x < (ssize_t) columns; x++)
3380 {
3381 SetPixelRed(image,*p++,q);
3382 SetPixelGreen(image,*p++,q);
3383 SetPixelBlue(image,*p++,q);
3384 q+=GetPixelChannels(image);
3385 }
3386 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3387 break;
3388 }
3389 return;
3390 }
3391 if (LocaleCompare(map,"RGBA") == 0)
3392 {
3393 for (y=0; y < (ssize_t) rows; y++)
3394 {
3395 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3396 if (q == (Quantum *) NULL)
3397 break;
3398 for (x=0; x < (ssize_t) columns; x++)
3399 {
3400 SetPixelRed(image,*p++,q);
3401 SetPixelGreen(image,*p++,q);
3402 SetPixelBlue(image,*p++,q);
3403 SetPixelAlpha(image,*p++,q);
3404 q+=GetPixelChannels(image);
3405 }
3406 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3407 break;
3408 }
3409 return;
3410 }
3411 if (LocaleCompare(map,"RGBP") == 0)
3412 {
3413 for (y=0; y < (ssize_t) rows; y++)
3414 {
3415 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3416 if (q == (Quantum *) NULL)
3417 break;
3418 for (x=0; x < (ssize_t) columns; x++)
3419 {
3420 SetPixelRed(image,*p++,q);
3421 SetPixelGreen(image,*p++,q);
3422 SetPixelBlue(image,*p++,q);
3423 p++;
3424 q+=GetPixelChannels(image);
3425 }
3426 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3427 break;
3428 }
3429 return;
3430 }
3431 for (y=0; y < (ssize_t) rows; y++)
3432 {
3433 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3434 if (q == (Quantum *) NULL)
3435 break;
3436 for (x=0; x < (ssize_t) columns; x++)
3437 {
3438 register ssize_t
3439 i;
3440
3441 for (i=0; i < (ssize_t) strlen(map); i++)
3442 {
3443 switch (quantum_map[i])
3444 {
3445 case RedQuantum:
3446 case CyanQuantum:
3447 {
3448 SetPixelRed(image,*p,q);
3449 break;
3450 }
3451 case GreenQuantum:
3452 case MagentaQuantum:
3453 {
3454 SetPixelGreen(image,*p,q);
3455 break;
3456 }
3457 case BlueQuantum:
3458 case YellowQuantum:
3459 {
3460 SetPixelBlue(image,*p,q);
3461 break;
3462 }
3463 case AlphaQuantum:
3464 {
3465 SetPixelAlpha(image,*p,q);
3466 break;
3467 }
3468 case OpacityQuantum:
3469 {
3470 SetPixelAlpha(image,*p,q);
3471 break;
3472 }
3473 case BlackQuantum:
3474 {
3475 SetPixelBlack(image,*p,q);
3476 break;
3477 }
3478 case IndexQuantum:
3479 {
3480 SetPixelGray(image,*p,q);
3481 break;
3482 }
3483 default:
3484 break;
3485 }
3486 p++;
3487 }
3488 q+=GetPixelChannels(image);
3489 }
3490 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3491 break;
3492 }
3493}
3494
3495static void ImportShortPixel(Image *image,const ssize_t x_offset,
3496 const ssize_t y_offset,const size_t columns,const size_t rows,
cristy46f4be22012-01-07 00:26:39 +00003497 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3498 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003499{
3500 register const unsigned short
3501 *restrict p;
3502
3503 register Quantum
cristy3fe11452012-01-09 01:27:42 +00003504 *restrict q;
cristye5370942012-01-06 03:49:31 +00003505
3506 register ssize_t
3507 x;
3508
3509 ssize_t
3510 y;
3511
3512 p=(const unsigned short *) pixels;
3513 if (LocaleCompare(map,"BGR") == 0)
3514 {
3515 for (y=0; y < (ssize_t) rows; y++)
3516 {
3517 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3518 if (q == (Quantum *) NULL)
3519 break;
3520 for (x=0; x < (ssize_t) columns; x++)
3521 {
3522 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3523 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3524 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3525 q+=GetPixelChannels(image);
3526 }
3527 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3528 break;
3529 }
3530 return;
3531 }
3532 if (LocaleCompare(map,"BGRA") == 0)
3533 {
3534 for (y=0; y < (ssize_t) rows; y++)
3535 {
3536 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3537 if (q == (Quantum *) NULL)
3538 break;
3539 for (x=0; x < (ssize_t) columns; x++)
3540 {
3541 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3542 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3543 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3544 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3545 q+=GetPixelChannels(image);
3546 }
3547 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3548 break;
3549 }
3550 return;
3551 }
3552 if (LocaleCompare(map,"BGRP") == 0)
3553 {
3554 for (y=0; y < (ssize_t) rows; y++)
3555 {
3556 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3557 if (q == (Quantum *) NULL)
3558 break;
3559 for (x=0; x < (ssize_t) columns; x++)
3560 {
3561 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3562 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3563 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3564 p++;
3565 q+=GetPixelChannels(image);
3566 }
3567 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3568 break;
3569 }
3570 return;
3571 }
3572 if (LocaleCompare(map,"I") == 0)
3573 {
3574 for (y=0; y < (ssize_t) rows; y++)
3575 {
3576 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3577 if (q == (Quantum *) NULL)
3578 break;
3579 for (x=0; x < (ssize_t) columns; x++)
3580 {
3581 SetPixelGray(image,ScaleShortToQuantum(*p++),q);
3582 q+=GetPixelChannels(image);
3583 }
3584 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3585 break;
3586 }
3587 return;
3588 }
3589 if (LocaleCompare(map,"RGB") == 0)
3590 {
3591 for (y=0; y < (ssize_t) rows; y++)
3592 {
3593 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3594 if (q == (Quantum *) NULL)
3595 break;
3596 for (x=0; x < (ssize_t) columns; x++)
3597 {
3598 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3599 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3600 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3601 q+=GetPixelChannels(image);
3602 }
3603 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3604 break;
3605 }
3606 return;
3607 }
3608 if (LocaleCompare(map,"RGBA") == 0)
3609 {
3610 for (y=0; y < (ssize_t) rows; y++)
3611 {
3612 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3613 if (q == (Quantum *) NULL)
3614 break;
3615 for (x=0; x < (ssize_t) columns; x++)
3616 {
3617 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3618 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3619 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3620 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3621 q+=GetPixelChannels(image);
3622 }
3623 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3624 break;
3625 }
3626 return;
3627 }
3628 if (LocaleCompare(map,"RGBP") == 0)
3629 {
3630 for (y=0; y < (ssize_t) rows; y++)
3631 {
3632 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3633 if (q == (Quantum *) NULL)
3634 break;
3635 for (x=0; x < (ssize_t) columns; x++)
3636 {
3637 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3638 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3639 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3640 p++;
3641 q+=GetPixelChannels(image);
3642 }
3643 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3644 break;
3645 }
3646 return;
3647 }
3648 for (y=0; y < (ssize_t) rows; y++)
3649 {
3650 q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3651 if (q == (Quantum *) NULL)
3652 break;
3653 for (x=0; x < (ssize_t) columns; x++)
3654 {
3655 register ssize_t
3656 i;
3657
3658 for (i=0; i < (ssize_t) strlen(map); i++)
3659 {
3660 switch (quantum_map[i])
3661 {
3662 case RedQuantum:
3663 case CyanQuantum:
3664 {
3665 SetPixelRed(image,ScaleShortToQuantum(*p),q);
3666 break;
3667 }
3668 case GreenQuantum:
3669 case MagentaQuantum:
3670 {
3671 SetPixelGreen(image,ScaleShortToQuantum(*p),q);
3672 break;
3673 }
3674 case BlueQuantum:
3675 case YellowQuantum:
3676 {
3677 SetPixelBlue(image,ScaleShortToQuantum(*p),q);
3678 break;
3679 }
3680 case AlphaQuantum:
3681 {
3682 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
3683 break;
3684 }
3685 case OpacityQuantum:
3686 {
3687 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
3688 break;
3689 }
3690 case BlackQuantum:
3691 {
3692 SetPixelBlack(image,ScaleShortToQuantum(*p),q);
3693 break;
3694 }
3695 case IndexQuantum:
3696 {
3697 SetPixelGray(image,ScaleShortToQuantum(*p),q);
3698 break;
3699 }
3700 default:
3701 break;
3702 }
3703 p++;
3704 }
3705 q+=GetPixelChannels(image);
3706 }
3707 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3708 break;
3709 }
3710}
3711
cristy4c08aed2011-07-01 19:47:50 +00003712MagickExport MagickBooleanType ImportImagePixels(Image *image,
3713 const ssize_t x_offset,const ssize_t y_offset,const size_t columns,
3714 const size_t rows,const char *map,const StorageType type,
cristy018f07f2011-09-04 21:15:19 +00003715 const void *pixels,ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00003716{
cristy4c08aed2011-07-01 19:47:50 +00003717 QuantumType
3718 *quantum_map;
3719
cristy4c08aed2011-07-01 19:47:50 +00003720 register ssize_t
cristye5370942012-01-06 03:49:31 +00003721 i;
cristy4c08aed2011-07-01 19:47:50 +00003722
3723 /*
3724 Allocate image structure.
3725 */
3726 assert(image != (Image *) NULL);
3727 assert(image->signature == MagickSignature);
3728 if (image->debug != MagickFalse)
3729 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristye5370942012-01-06 03:49:31 +00003730 quantum_map=(QuantumType *) AcquireQuantumMemory(strlen(map),
3731 sizeof(*quantum_map));
cristy4c08aed2011-07-01 19:47:50 +00003732 if (quantum_map == (QuantumType *) NULL)
3733 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
3734 image->filename);
cristye5370942012-01-06 03:49:31 +00003735 for (i=0; i < (ssize_t) strlen(map); i++)
cristy4c08aed2011-07-01 19:47:50 +00003736 {
3737 switch (map[i])
3738 {
3739 case 'a':
3740 case 'A':
3741 {
3742 quantum_map[i]=AlphaQuantum;
3743 image->matte=MagickTrue;
3744 break;
3745 }
3746 case 'B':
3747 case 'b':
3748 {
3749 quantum_map[i]=BlueQuantum;
3750 break;
3751 }
3752 case 'C':
3753 case 'c':
3754 {
3755 quantum_map[i]=CyanQuantum;
cristy63240882011-08-05 19:05:27 +00003756 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003757 break;
3758 }
3759 case 'g':
3760 case 'G':
3761 {
3762 quantum_map[i]=GreenQuantum;
3763 break;
3764 }
3765 case 'K':
3766 case 'k':
3767 {
3768 quantum_map[i]=BlackQuantum;
cristy63240882011-08-05 19:05:27 +00003769 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003770 break;
3771 }
3772 case 'I':
3773 case 'i':
3774 {
3775 quantum_map[i]=IndexQuantum;
3776 break;
3777 }
3778 case 'm':
3779 case 'M':
3780 {
3781 quantum_map[i]=MagentaQuantum;
cristy63240882011-08-05 19:05:27 +00003782 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003783 break;
3784 }
3785 case 'O':
3786 case 'o':
3787 {
3788 quantum_map[i]=OpacityQuantum;
3789 image->matte=MagickTrue;
3790 break;
3791 }
3792 case 'P':
3793 case 'p':
3794 {
3795 quantum_map[i]=UndefinedQuantum;
3796 break;
3797 }
3798 case 'R':
3799 case 'r':
3800 {
3801 quantum_map[i]=RedQuantum;
3802 break;
3803 }
3804 case 'Y':
3805 case 'y':
3806 {
3807 quantum_map[i]=YellowQuantum;
cristy63240882011-08-05 19:05:27 +00003808 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00003809 break;
3810 }
3811 default:
3812 {
3813 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
cristy63240882011-08-05 19:05:27 +00003814 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
3815 "UnrecognizedPixelMap","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00003816 return(MagickFalse);
3817 }
3818 }
3819 }
cristy63240882011-08-05 19:05:27 +00003820 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
cristy4c08aed2011-07-01 19:47:50 +00003821 return(MagickFalse);
3822 /*
cristye5370942012-01-06 03:49:31 +00003823 Transfer the pixels from the pixel data to the image.
cristy4c08aed2011-07-01 19:47:50 +00003824 */
cristy4c08aed2011-07-01 19:47:50 +00003825 switch (type)
3826 {
3827 case CharPixel:
3828 {
cristye5370942012-01-06 03:49:31 +00003829 ImportCharPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
3830 pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003831 break;
3832 }
3833 case DoublePixel:
3834 {
cristye5370942012-01-06 03:49:31 +00003835 ImportDoublePixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
3836 pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003837 break;
3838 }
3839 case FloatPixel:
3840 {
cristye5370942012-01-06 03:49:31 +00003841 ImportFloatPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
3842 pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003843 break;
3844 }
cristy4c08aed2011-07-01 19:47:50 +00003845 case LongPixel:
3846 {
cristye5370942012-01-06 03:49:31 +00003847 ImportLongPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
3848 pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003849 break;
3850 }
cristy6c9e1682012-01-07 21:37:44 +00003851 case LongLongPixel:
3852 {
3853 ImportLongLongPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
3854 pixels,exception);
3855 break;
3856 }
cristy4c08aed2011-07-01 19:47:50 +00003857 case QuantumPixel:
3858 {
cristye5370942012-01-06 03:49:31 +00003859 ImportQuantumPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
3860 pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003861 break;
3862 }
3863 case ShortPixel:
3864 {
cristye5370942012-01-06 03:49:31 +00003865 ImportShortPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
3866 pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00003867 break;
3868 }
3869 default:
3870 {
3871 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
cristyc82a27b2011-10-21 01:07:16 +00003872 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
3873 "UnrecognizedPixelMap","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00003874 break;
3875 }
3876 }
3877 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
3878 return(MagickTrue);
3879}
3880
3881/*
3882%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3883% %
3884% %
3885% %
cristybd5a96c2011-08-21 00:04:26 +00003886+ 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 %
3887% %
3888% %
3889% %
3890%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3891%
3892% InitializePixelChannelMap() defines the standard pixel component map.
3893%
3894% The format of the InitializePixelChannelMap() method is:
3895%
3896% void InitializePixelChannelMap(Image *image)
3897%
3898% A description of each parameter follows:
3899%
3900% o image: the image.
3901%
3902*/
cristye2a912b2011-12-05 20:02:07 +00003903MagickExport void InitializePixelChannelMap(Image *image)
cristy77c30f52011-10-24 18:56:57 +00003904{
cristye2a912b2011-12-05 20:02:07 +00003905 PixelTrait
3906 trait;
3907
cristy77c30f52011-10-24 18:56:57 +00003908 register ssize_t
3909 i;
3910
cristyd26338f2011-12-14 02:39:30 +00003911 ssize_t
cristy77c30f52011-10-24 18:56:57 +00003912 n;
3913
3914 assert(image != (Image *) NULL);
3915 assert(image->signature == MagickSignature);
cristye2a912b2011-12-05 20:02:07 +00003916 (void) ResetMagickMemory(image->channel_map,0,MaxPixelChannels*
3917 sizeof(*image->channel_map));
3918 trait=UpdatePixelTrait;
3919 if (image->matte != MagickFalse)
cristy61f18ad2011-12-08 21:12:37 +00003920 trait=(PixelTrait) (trait | BlendPixelTrait);
cristy77c30f52011-10-24 18:56:57 +00003921 n=0;
cristyc06c5802011-12-31 23:36:16 +00003922 if (image->colorspace == GRAYColorspace)
cristy77c30f52011-10-24 18:56:57 +00003923 {
cristy3c316282011-12-15 15:43:24 +00003924 SetPixelChannelMap(image,BluePixelChannel,trait,n);
cristye2a912b2011-12-05 20:02:07 +00003925 SetPixelChannelMap(image,GreenPixelChannel,trait,n);
cristy3c316282011-12-15 15:43:24 +00003926 SetPixelChannelMap(image,RedPixelChannel,trait,n++);
3927 }
3928 else
3929 {
3930 SetPixelChannelMap(image,RedPixelChannel,trait,n++);
3931 SetPixelChannelMap(image,GreenPixelChannel,trait,n++);
cristye2a912b2011-12-05 20:02:07 +00003932 SetPixelChannelMap(image,BluePixelChannel,trait,n++);
cristy77c30f52011-10-24 18:56:57 +00003933 }
3934 if (image->colorspace == CMYKColorspace)
cristye2a912b2011-12-05 20:02:07 +00003935 SetPixelChannelMap(image,BlackPixelChannel,trait,n++);
cristy77c30f52011-10-24 18:56:57 +00003936 if (image->matte != MagickFalse)
cristye2a912b2011-12-05 20:02:07 +00003937 SetPixelChannelMap(image,AlphaPixelChannel,CopyPixelTrait,n++);
3938 if (image->storage_class == PseudoClass)
3939 SetPixelChannelMap(image,IndexPixelChannel,CopyPixelTrait,n++);
3940 assert((n+image->number_meta_channels) < MaxPixelChannels);
3941 for (i=0; i < (ssize_t) image->number_meta_channels; i++)
cristy61f18ad2011-12-08 21:12:37 +00003942 SetPixelChannelMap(image,(PixelChannel) (MetaPixelChannel+i),CopyPixelTrait,
cristye2a912b2011-12-05 20:02:07 +00003943 n++);
cristyd26338f2011-12-14 02:39:30 +00003944 image->number_channels=(size_t) n;
cristy77c30f52011-10-24 18:56:57 +00003945 if (image->debug != MagickFalse)
3946 LogPixelChannels(image);
3947 (void) SetPixelChannelMask(image,image->channel_mask);
3948}
cristybd5a96c2011-08-21 00:04:26 +00003949
3950/*
3951%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3952% %
3953% %
3954% %
cristya085a432011-07-30 01:39:32 +00003955% I n t e r p o l a t e P i x e l C h a n n e l %
3956% %
3957% %
3958% %
3959%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3960%
cristy884f6002011-07-31 00:51:45 +00003961% InterpolatePixelChannel() applies a pixel interpolation method between a
3962% floating point coordinate and the pixels surrounding that coordinate. No
3963% pixel area resampling, or scaling of the result is performed.
cristya085a432011-07-30 01:39:32 +00003964%
3965% The format of the InterpolatePixelChannel method is:
3966%
3967% MagickBooleanType InterpolatePixelChannel(const Image *image,
cristy444eda62011-08-10 02:07:46 +00003968% const CacheView *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00003969% const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00003970% double *pixel,ExceptionInfo *exception)
3971%
3972% A description of each parameter follows:
3973%
3974% o image: the image.
3975%
3976% o image_view: the image view.
3977%
3978% o channel: the pixel channel to interpolate.
3979%
3980% o method: the pixel color interpolation method.
3981%
3982% o x,y: A double representing the current (x,y) position of the pixel.
3983%
3984% o pixel: return the interpolated pixel here.
3985%
3986% o exception: return any errors or warnings in this structure.
3987%
3988*/
cristy94ea1632011-07-30 20:40:25 +00003989
cristy884f6002011-07-31 00:51:45 +00003990static inline double MagickMax(const MagickRealType x,const MagickRealType y)
3991{
3992 if (x > y)
3993 return(x);
3994 return(y);
3995}
3996
3997static inline MagickRealType CubicWeightingFunction(const MagickRealType x)
3998{
3999 MagickRealType
4000 alpha,
4001 gamma;
4002
4003 alpha=MagickMax(x+2.0,0.0);
4004 gamma=1.0*alpha*alpha*alpha;
4005 alpha=MagickMax(x+1.0,0.0);
4006 gamma-=4.0*alpha*alpha*alpha;
4007 alpha=MagickMax(x+0.0,0.0);
4008 gamma+=6.0*alpha*alpha*alpha;
4009 alpha=MagickMax(x-1.0,0.0);
4010 gamma-=4.0*alpha*alpha*alpha;
4011 return(gamma/6.0);
4012}
4013
cristy94ea1632011-07-30 20:40:25 +00004014static inline double MeshInterpolate(const PointInfo *delta,const double p,
4015 const double x,const double y)
4016{
4017 return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p);
4018}
4019
cristy884f6002011-07-31 00:51:45 +00004020static inline ssize_t NearestNeighbor(const MagickRealType x)
4021{
4022 if (x >= 0.0)
4023 return((ssize_t) (x+0.5));
4024 return((ssize_t) (x-0.5));
4025}
4026
cristya085a432011-07-30 01:39:32 +00004027MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
4028 const CacheView *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00004029 const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00004030 double *pixel,ExceptionInfo *exception)
4031{
4032 MagickBooleanType
4033 status;
4034
cristy94ea1632011-07-30 20:40:25 +00004035 MagickRealType
4036 alpha[16],
cristy884f6002011-07-31 00:51:45 +00004037 gamma,
4038 pixels[16];
cristy94ea1632011-07-30 20:40:25 +00004039
4040 PixelTrait
4041 traits;
4042
cristy94ea1632011-07-30 20:40:25 +00004043 register const Quantum
4044 *p;
4045
4046 register ssize_t
4047 i;
4048
cristya085a432011-07-30 01:39:32 +00004049 ssize_t
4050 x_offset,
4051 y_offset;
4052
4053 assert(image != (Image *) NULL);
4054 assert(image != (Image *) NULL);
4055 assert(image->signature == MagickSignature);
4056 assert(image_view != (CacheView *) NULL);
4057 status=MagickTrue;
cristy884f6002011-07-31 00:51:45 +00004058 *pixel=0.0;
cristy94ea1632011-07-30 20:40:25 +00004059 traits=GetPixelChannelMapTraits(image,channel);
cristya085a432011-07-30 01:39:32 +00004060 x_offset=(ssize_t) floor(x);
4061 y_offset=(ssize_t) floor(y);
4062 switch (method == UndefinedInterpolatePixel ? image->interpolate : method)
4063 {
cristy884f6002011-07-31 00:51:45 +00004064 case AverageInterpolatePixel:
4065 {
4066 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4067 exception);
4068 if (p == (const Quantum *) NULL)
4069 {
4070 status=MagickFalse;
4071 break;
4072 }
cristy222b19c2011-08-04 01:35:11 +00004073 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004074 for (i=0; i < 16; i++)
4075 {
4076 alpha[i]=1.0;
4077 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4078 }
4079 else
4080 for (i=0; i < 16; i++)
4081 {
4082 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4083 GetPixelChannels(image));
4084 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4085 }
4086 for (i=0; i < 16; i++)
4087 {
4088 gamma=1.0/(fabs((double) alpha[i]) <= MagickEpsilon ? 1.0 : alpha[i]);
4089 *pixel+=gamma*0.0625*pixels[i];
4090 }
4091 break;
4092 }
4093 case BicubicInterpolatePixel:
4094 {
4095 MagickRealType
4096 u[4],
4097 v[4];
4098
4099 PointInfo
4100 delta;
4101
4102 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4103 exception);
4104 if (p == (const Quantum *) NULL)
4105 {
4106 status=MagickFalse;
4107 break;
4108 }
cristy222b19c2011-08-04 01:35:11 +00004109 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004110 for (i=0; i < 16; i++)
4111 {
4112 alpha[i]=1.0;
4113 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4114 }
4115 else
4116 for (i=0; i < 16; i++)
4117 {
4118 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4119 GetPixelChannels(image));
4120 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4121 }
4122 delta.x=x-x_offset;
4123 delta.y=y-y_offset;
4124 for (i=0; i < 4; i++)
4125 {
4126 u[0]=(pixels[4*i+3]-pixels[4*i+2])-(pixels[4*i+0]-pixels[4*i+1]);
4127 u[1]=(pixels[4*i+0]-pixels[4*i+1])-u[0];
4128 u[2]=pixels[4*i+2]-pixels[4*i+0];
4129 u[3]=pixels[4*i+1];
4130 v[i]=(delta.x*delta.x*delta.x*u[0])+(delta.x*delta.x*u[1])+(delta.x*
4131 u[2])+u[3];
4132 }
4133 u[0]=(v[3]-v[2])-(v[0]-v[1]);
4134 u[1]=(v[0]-v[1])-u[0];
4135 u[2]=v[2]-v[0];
4136 u[3]=v[1];
4137 *pixel=(delta.y*delta.y*delta.y*u[0])+(delta.y*delta.y*u[1])+(delta.y*
4138 u[2])+u[3];
4139 break;
4140 }
4141 case BilinearInterpolatePixel:
cristy94ea1632011-07-30 20:40:25 +00004142 default:
cristya085a432011-07-30 01:39:32 +00004143 {
cristy94ea1632011-07-30 20:40:25 +00004144 PointInfo
4145 delta,
cristy884f6002011-07-31 00:51:45 +00004146 epsilon;
4147
4148 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4149 if (p == (const Quantum *) NULL)
4150 {
4151 status=MagickFalse;
4152 break;
4153 }
cristy222b19c2011-08-04 01:35:11 +00004154 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004155 for (i=0; i < 4; i++)
4156 {
4157 alpha[i]=1.0;
4158 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4159 }
4160 else
4161 for (i=0; i < 4; i++)
4162 {
4163 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4164 GetPixelChannels(image));
4165 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4166 }
4167 delta.x=x-x_offset;
4168 delta.y=y-y_offset;
4169 epsilon.x=1.0-delta.x;
4170 epsilon.y=1.0-delta.y;
4171 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4172 (epsilon.x*alpha[2]+delta.x*alpha[3])));
4173 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4174 *pixel=gamma*(epsilon.y*(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*
4175 (epsilon.x*pixels[2]+delta.x*pixels[3]));
4176 break;
4177 }
4178 case FilterInterpolatePixel:
4179 {
4180 CacheView
4181 *filter_view;
4182
4183 Image
4184 *excerpt_image,
4185 *filter_image;
4186
4187 RectangleInfo
4188 geometry;
4189
4190 geometry.width=4L;
4191 geometry.height=4L;
4192 geometry.x=x_offset-1;
4193 geometry.y=y_offset-1;
4194 excerpt_image=ExcerptImage(image,&geometry,exception);
4195 if (excerpt_image == (Image *) NULL)
4196 {
4197 status=MagickFalse;
4198 break;
4199 }
4200 filter_image=ResizeImage(excerpt_image,1,1,image->filter,image->blur,
4201 exception);
4202 excerpt_image=DestroyImage(excerpt_image);
4203 if (filter_image == (Image *) NULL)
4204 break;
4205 filter_view=AcquireCacheView(filter_image);
4206 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4207 if (p == (const Quantum *) NULL)
4208 status=MagickFalse;
4209 else
cristy0beccfa2011-09-25 20:47:53 +00004210 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004211 filter_view=DestroyCacheView(filter_view);
4212 filter_image=DestroyImage(filter_image);
4213 break;
4214 }
4215 case IntegerInterpolatePixel:
4216 {
4217 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
4218 if (p == (const Quantum *) NULL)
4219 {
4220 status=MagickFalse;
4221 break;
4222 }
cristy0beccfa2011-09-25 20:47:53 +00004223 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004224 break;
4225 }
4226 case NearestNeighborInterpolatePixel:
4227 {
4228 p=GetCacheViewVirtualPixels(image_view,NearestNeighbor(x),
4229 NearestNeighbor(y),1,1,exception);
4230 if (p == (const Quantum *) NULL)
4231 {
4232 status=MagickFalse;
4233 break;
4234 }
cristy0beccfa2011-09-25 20:47:53 +00004235 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004236 break;
4237 }
4238 case MeshInterpolatePixel:
4239 {
4240 PointInfo
4241 delta,
cristy94ea1632011-07-30 20:40:25 +00004242 luminance;
4243
4244 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4245 if (p == (const Quantum *) NULL)
4246 {
4247 status=MagickFalse;
4248 break;
4249 }
cristy222b19c2011-08-04 01:35:11 +00004250 if ((traits & BlendPixelTrait) == 0)
cristy94ea1632011-07-30 20:40:25 +00004251 for (i=0; i < 4; i++)
4252 {
4253 alpha[i]=1.0;
cristy884f6002011-07-31 00:51:45 +00004254 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
cristy94ea1632011-07-30 20:40:25 +00004255 }
4256 else
4257 for (i=0; i < 4; i++)
4258 {
4259 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4260 GetPixelChannels(image));
4261 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4262 }
cristy884f6002011-07-31 00:51:45 +00004263 delta.x=x-x_offset;
4264 delta.y=y-y_offset;
4265 luminance.x=GetPixelLuminance(image,p)-(double)
4266 GetPixelLuminance(image,p+3*GetPixelChannels(image));
cristy28474bf2011-09-11 23:32:52 +00004267 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
cristy884f6002011-07-31 00:51:45 +00004268 GetPixelLuminance(image,p+2*GetPixelChannels(image));
cristy94ea1632011-07-30 20:40:25 +00004269 if (fabs(luminance.x) < fabs(luminance.y))
4270 {
4271 /*
4272 Diagonal 0-3 NW-SE.
4273 */
4274 if (delta.x <= delta.y)
4275 {
4276 /*
4277 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4278 */
4279 delta.y=1.0-delta.y;
4280 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
4281 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4282 *pixel=gamma*MeshInterpolate(&delta,pixels[2],pixels[3],
4283 pixels[0]);
4284 }
4285 else
4286 {
4287 /*
4288 Top-right triangle (pixel: 1, diagonal: 0-3).
4289 */
4290 delta.x=1.0-delta.x;
4291 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
4292 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4293 *pixel=gamma*MeshInterpolate(&delta,pixels[1],pixels[0],
4294 pixels[3]);
4295 }
4296 }
4297 else
4298 {
4299 /*
4300 Diagonal 1-2 NE-SW.
4301 */
4302 if (delta.x <= (1.0-delta.y))
4303 {
4304 /*
4305 Top-left triangle (pixel: 0, diagonal: 1-2).
4306 */
4307 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
4308 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4309 *pixel=gamma*MeshInterpolate(&delta,pixels[0],pixels[1],
4310 pixels[2]);
4311 }
4312 else
4313 {
4314 /*
4315 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4316 */
4317 delta.x=1.0-delta.x;
4318 delta.y=1.0-delta.y;
4319 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
4320 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4321 *pixel=gamma*MeshInterpolate(&delta,pixels[3],pixels[2],
4322 pixels[1]);
4323 }
4324 }
cristya085a432011-07-30 01:39:32 +00004325 break;
4326 }
cristy884f6002011-07-31 00:51:45 +00004327 case SplineInterpolatePixel:
4328 {
4329 MagickRealType
4330 dx,
4331 dy;
4332
4333 PointInfo
4334 delta;
4335
4336 ssize_t
4337 j,
4338 n;
4339
4340 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4341 exception);
4342 if (p == (const Quantum *) NULL)
4343 {
4344 status=MagickFalse;
4345 break;
4346 }
cristy222b19c2011-08-04 01:35:11 +00004347 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004348 for (i=0; i < 16; i++)
4349 {
4350 alpha[i]=1.0;
4351 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4352 }
4353 else
4354 for (i=0; i < 16; i++)
4355 {
4356 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4357 GetPixelChannels(image));
4358 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4359 }
4360 delta.x=x-x_offset;
4361 delta.y=y-y_offset;
4362 n=0;
4363 for (i=(-1); i < 3L; i++)
4364 {
4365 dy=CubicWeightingFunction((MagickRealType) i-delta.y);
4366 for (j=(-1); j < 3L; j++)
4367 {
4368 dx=CubicWeightingFunction(delta.x-(MagickRealType) j);
4369 gamma=1.0/(fabs((double) alpha[n]) <= MagickEpsilon ? 1.0 : alpha[n]);
4370 *pixel+=gamma*dx*dy*pixels[n];
4371 n++;
4372 }
4373 }
4374 break;
4375 }
cristya085a432011-07-30 01:39:32 +00004376 }
4377 return(status);
4378}
4379
4380/*
4381%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4382% %
4383% %
4384% %
cristy5c4e2582011-09-11 19:21:03 +00004385% I n t e r p o l a t e P i x e l C h a n n e l s %
4386% %
4387% %
4388% %
4389%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4390%
4391% InterpolatePixelChannels() applies a pixel interpolation method between a
4392% floating point coordinate and the pixels surrounding that coordinate. No
4393% pixel area resampling, or scaling of the result is performed.
4394%
4395% The format of the InterpolatePixelChannels method is:
4396%
4397% MagickBooleanType InterpolatePixelChannels(const Image *source,
4398% const CacheView *source_view,const Image *destination,
4399% const PixelInterpolateMethod method,const double x,const double y,
4400% Quantum *pixel,ExceptionInfo *exception)
4401%
4402% A description of each parameter follows:
4403%
4404% o source: the source.
4405%
4406% o source_view: the source view.
4407%
4408% o destination: the destination image.
4409%
4410% o method: the pixel color interpolation method.
4411%
4412% o x,y: A double representing the current (x,y) position of the pixel.
4413%
4414% o pixel: return the interpolated pixel here.
4415%
4416% o exception: return any errors or warnings in this structure.
4417%
4418*/
4419MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
4420 const CacheView *source_view,const Image *destination,
4421 const PixelInterpolateMethod method,const double x,const double y,
4422 Quantum *pixel,ExceptionInfo *exception)
4423{
4424 MagickBooleanType
4425 status;
4426
4427 MagickRealType
4428 alpha[16],
4429 gamma,
4430 pixels[16];
4431
4432 PixelChannel
4433 channel;
4434
4435 PixelTrait
4436 destination_traits,
4437 traits;
4438
4439 register const Quantum
4440 *p;
4441
4442 register ssize_t
4443 i;
4444
4445 ssize_t
4446 x_offset,
4447 y_offset;
4448
4449 assert(source != (Image *) NULL);
4450 assert(source != (Image *) NULL);
4451 assert(source->signature == MagickSignature);
4452 assert(source_view != (CacheView *) NULL);
4453 status=MagickTrue;
4454 x_offset=(ssize_t) floor(x);
4455 y_offset=(ssize_t) floor(y);
4456 switch (method == UndefinedInterpolatePixel ? source->interpolate : method)
4457 {
4458 case AverageInterpolatePixel:
4459 {
4460 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4461 exception);
4462 if (p == (const Quantum *) NULL)
4463 {
4464 status=MagickFalse;
4465 break;
4466 }
4467 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4468 {
4469 double
4470 sum;
4471
4472 register ssize_t
4473 j;
4474
cristye2a912b2011-12-05 20:02:07 +00004475 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004476 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004477 destination_traits=GetPixelChannelMapTraits(destination,channel);
4478 if ((traits == UndefinedPixelTrait) ||
4479 (destination_traits == UndefinedPixelTrait))
4480 continue;
4481 for (j=0; j < 16; j++)
4482 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
cristy4a7ae692011-12-14 12:24:11 +00004483 sum=0.0;
cristy5c4e2582011-09-11 19:21:03 +00004484 if ((traits & BlendPixelTrait) == 0)
4485 {
4486 for (j=0; j < 16; j++)
cristy4a7ae692011-12-14 12:24:11 +00004487 sum+=0.0625*pixels[j];
4488 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004489 continue;
4490 }
cristy5c4e2582011-09-11 19:21:03 +00004491 for (j=0; j < 16; j++)
4492 {
4493 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4494 GetPixelChannels(source));
4495 pixels[j]*=alpha[j];
4496 gamma=1.0/(fabs((double) alpha[j]) <= MagickEpsilon ? 1.0 : alpha[j]);
4497 sum+=gamma*0.0625*pixels[j];
4498 }
cristy4a7ae692011-12-14 12:24:11 +00004499 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004500 }
4501 break;
4502 }
4503 case BicubicInterpolatePixel:
4504 {
4505 MagickRealType
4506 u[4],
4507 v[4];
4508
4509 PointInfo
4510 delta;
4511
4512 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4513 exception);
4514 if (p == (const Quantum *) NULL)
4515 {
4516 status=MagickFalse;
4517 break;
4518 }
4519 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4520 {
4521 register ssize_t
4522 j;
4523
cristye2a912b2011-12-05 20:02:07 +00004524 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004525 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004526 destination_traits=GetPixelChannelMapTraits(destination,channel);
4527 if ((traits == UndefinedPixelTrait) ||
4528 (destination_traits == UndefinedPixelTrait))
4529 continue;
4530 if ((traits & BlendPixelTrait) == 0)
4531 for (j=0; j < 16; j++)
4532 {
4533 alpha[j]=1.0;
4534 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
4535 }
4536 else
4537 for (j=0; j < 16; j++)
4538 {
4539 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4540 GetPixelChannels(source));
4541 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
4542 }
4543 delta.x=x-x_offset;
4544 delta.y=y-y_offset;
4545 for (j=0; j < 4; j++)
4546 {
4547 u[0]=(pixels[4*j+3]-pixels[4*j+2])-(pixels[4*j+0]-pixels[4*j+1]);
4548 u[1]=(pixels[4*j+0]-pixels[4*j+1])-u[0];
4549 u[2]=pixels[4*j+2]-pixels[4*j+0];
4550 u[3]=pixels[4*j+1];
4551 v[j]=(delta.x*delta.x*delta.x*u[0])+(delta.x*delta.x*u[1])+(delta.x*
4552 u[2])+u[3];
4553 }
4554 u[0]=(v[3]-v[2])-(v[0]-v[1]);
4555 u[1]=(v[0]-v[1])-u[0];
4556 u[2]=v[2]-v[0];
4557 u[3]=v[1];
cristy4a7ae692011-12-14 12:24:11 +00004558 SetPixelChannel(destination,channel,ClampToQuantum((delta.y*delta.y*
4559 delta.y*u[0])+(delta.y*delta.y*u[1])+(delta.y*u[2])+u[3]),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004560 }
4561 break;
4562 }
4563 case BilinearInterpolatePixel:
4564 default:
4565 {
4566 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4567 if (p == (const Quantum *) NULL)
4568 {
4569 status=MagickFalse;
4570 break;
4571 }
4572 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4573 {
4574 PointInfo
4575 delta,
4576 epsilon;
4577
cristye2a912b2011-12-05 20:02:07 +00004578 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004579 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004580 destination_traits=GetPixelChannelMapTraits(destination,channel);
4581 if ((traits == UndefinedPixelTrait) ||
4582 (destination_traits == UndefinedPixelTrait))
4583 continue;
4584 delta.x=x-x_offset;
4585 delta.y=y-y_offset;
4586 epsilon.x=1.0-delta.x;
4587 epsilon.y=1.0-delta.y;
cristy28474bf2011-09-11 23:32:52 +00004588 pixels[0]=(MagickRealType) p[i];
4589 pixels[1]=(MagickRealType) p[GetPixelChannels(source)+i];
cristy5c4e2582011-09-11 19:21:03 +00004590 pixels[2]=(MagickRealType) p[2*GetPixelChannels(source)+i];
4591 pixels[3]=(MagickRealType) p[3*GetPixelChannels(source)+i];
4592 if ((traits & BlendPixelTrait) == 0)
4593 {
4594 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
4595 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004596 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
4597 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*
4598 pixels[2]+delta.x*pixels[3]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004599 continue;
4600 }
cristy28474bf2011-09-11 23:32:52 +00004601 alpha[0]=QuantumScale*GetPixelAlpha(source,p);
4602 alpha[1]=QuantumScale*GetPixelAlpha(source,p+GetPixelChannels(source));
cristy5c4e2582011-09-11 19:21:03 +00004603 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
4604 GetPixelChannels(source));
4605 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
4606 GetPixelChannels(source));
4607 pixels[0]*=alpha[0];
4608 pixels[1]*=alpha[1];
4609 pixels[2]*=alpha[2];
4610 pixels[3]*=alpha[3];
4611 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4612 (epsilon.x*alpha[2]+delta.x*alpha[3])));
4613 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004614 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
4615 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*pixels[2]+
4616 delta.x*pixels[3]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004617 }
4618 break;
4619 }
4620 case FilterInterpolatePixel:
4621 {
4622 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4623 {
4624 CacheView
4625 *filter_view;
4626
4627 Image
4628 *excerpt_source,
4629 *filter_source;
4630
4631 RectangleInfo
4632 geometry;
4633
cristye2a912b2011-12-05 20:02:07 +00004634 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004635 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004636 destination_traits=GetPixelChannelMapTraits(destination,channel);
4637 if ((traits == UndefinedPixelTrait) ||
4638 (destination_traits == UndefinedPixelTrait))
4639 continue;
4640 geometry.width=4L;
4641 geometry.height=4L;
4642 geometry.x=x_offset-1;
4643 geometry.y=y_offset-1;
4644 excerpt_source=ExcerptImage(source,&geometry,exception);
4645 if (excerpt_source == (Image *) NULL)
4646 {
4647 status=MagickFalse;
4648 continue;
4649 }
4650 filter_source=ResizeImage(excerpt_source,1,1,source->filter,
4651 source->blur,exception);
4652 excerpt_source=DestroyImage(excerpt_source);
4653 if (filter_source == (Image *) NULL)
4654 continue;
4655 filter_view=AcquireCacheView(filter_source);
4656 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4657 if (p == (const Quantum *) NULL)
4658 status=MagickFalse;
4659 else
cristy1861c902011-12-14 02:30:00 +00004660 {
cristy4a7ae692011-12-14 12:24:11 +00004661 SetPixelChannel(destination,channel,p[i],pixel);
cristy1861c902011-12-14 02:30:00 +00004662 }
cristy5c4e2582011-09-11 19:21:03 +00004663 filter_view=DestroyCacheView(filter_view);
4664 filter_source=DestroyImage(filter_source);
4665 }
4666 break;
4667 }
4668 case IntegerInterpolatePixel:
4669 {
4670 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
4671 if (p == (const Quantum *) NULL)
4672 {
4673 status=MagickFalse;
4674 break;
4675 }
4676 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4677 {
cristye2a912b2011-12-05 20:02:07 +00004678 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004679 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004680 destination_traits=GetPixelChannelMapTraits(destination,channel);
4681 if ((traits == UndefinedPixelTrait) ||
4682 (destination_traits == UndefinedPixelTrait))
4683 continue;
cristy4a7ae692011-12-14 12:24:11 +00004684 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004685 }
4686 break;
4687 }
4688 case NearestNeighborInterpolatePixel:
4689 {
4690 p=GetCacheViewVirtualPixels(source_view,NearestNeighbor(x),
4691 NearestNeighbor(y),1,1,exception);
4692 if (p == (const Quantum *) NULL)
4693 {
4694 status=MagickFalse;
4695 break;
4696 }
4697 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4698 {
cristye2a912b2011-12-05 20:02:07 +00004699 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004700 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004701 destination_traits=GetPixelChannelMapTraits(destination,channel);
4702 if ((traits == UndefinedPixelTrait) ||
4703 (destination_traits == UndefinedPixelTrait))
4704 continue;
cristy4a7ae692011-12-14 12:24:11 +00004705 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004706 }
4707 break;
4708 }
4709 case MeshInterpolatePixel:
4710 {
4711 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4712 if (p == (const Quantum *) NULL)
4713 {
4714 status=MagickFalse;
4715 break;
4716 }
4717 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4718 {
4719 PointInfo
4720 delta,
4721 luminance;
4722
cristye2a912b2011-12-05 20:02:07 +00004723 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004724 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004725 destination_traits=GetPixelChannelMapTraits(destination,channel);
4726 if ((traits == UndefinedPixelTrait) ||
4727 (destination_traits == UndefinedPixelTrait))
4728 continue;
cristy1861c902011-12-14 02:30:00 +00004729 pixels[0]=(MagickRealType) p[i];
4730 pixels[1]=(MagickRealType) p[GetPixelChannels(source)+i];
4731 pixels[2]=(MagickRealType) p[2*GetPixelChannels(source)+i];
4732 pixels[3]=(MagickRealType) p[3*GetPixelChannels(source)+i];
4733 if ((traits & BlendPixelTrait) == 0)
4734 {
4735 alpha[0]=1.0;
4736 alpha[1]=1.0;
4737 alpha[2]=1.0;
4738 alpha[3]=1.0;
4739 }
4740 else
4741 {
4742 alpha[0]=QuantumScale*GetPixelAlpha(source,p);
4743 alpha[1]=QuantumScale*GetPixelAlpha(source,p+
4744 GetPixelChannels(source));
4745 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
4746 GetPixelChannels(source));
4747 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
4748 GetPixelChannels(source));
4749 }
4750 delta.x=x-x_offset;
4751 delta.y=y-y_offset;
4752 luminance.x=GetPixelLuminance(source,p)-(double)
4753 GetPixelLuminance(source,p+3*GetPixelChannels(source));
4754 luminance.y=GetPixelLuminance(source,p+GetPixelChannels(source))-
4755 (double) GetPixelLuminance(source,p+2*GetPixelChannels(source));
4756 if (fabs(luminance.x) < fabs(luminance.y))
4757 {
4758 /*
4759 Diagonal 0-3 NW-SE.
4760 */
4761 if (delta.x <= delta.y)
4762 {
4763 /*
4764 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4765 */
4766 delta.y=1.0-delta.y;
4767 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
4768 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004769 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4770 MeshInterpolate(&delta,pixels[2],pixels[3],pixels[0])),pixel);
cristy1861c902011-12-14 02:30:00 +00004771 }
4772 else
4773 {
4774 /*
4775 Top-right triangle (pixel: 1, diagonal: 0-3).
4776 */
4777 delta.x=1.0-delta.x;
4778 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
4779 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004780 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4781 MeshInterpolate(&delta,pixels[1],pixels[0],pixels[3])),pixel);
cristy1861c902011-12-14 02:30:00 +00004782 }
4783 }
4784 else
4785 {
4786 /*
4787 Diagonal 1-2 NE-SW.
4788 */
4789 if (delta.x <= (1.0-delta.y))
4790 {
4791 /*
4792 Top-left triangle (pixel: 0, diagonal: 1-2).
4793 */
4794 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
4795 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004796 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4797 MeshInterpolate(&delta,pixels[0],pixels[1],pixels[2])),pixel);
cristy1861c902011-12-14 02:30:00 +00004798 }
4799 else
4800 {
4801 /*
4802 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4803 */
4804 delta.x=1.0-delta.x;
4805 delta.y=1.0-delta.y;
4806 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
4807 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy4a7ae692011-12-14 12:24:11 +00004808 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4809 MeshInterpolate(&delta,pixels[3],pixels[2],pixels[1])),pixel);
cristy1861c902011-12-14 02:30:00 +00004810 }
4811 }
cristy5c4e2582011-09-11 19:21:03 +00004812 }
4813 break;
4814 }
4815 case SplineInterpolatePixel:
4816 {
4817 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
4818 exception);
4819 if (p == (const Quantum *) NULL)
4820 {
4821 status=MagickFalse;
4822 break;
4823 }
4824 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4825 {
4826 double
4827 sum;
4828
4829 MagickRealType
4830 dx,
4831 dy;
4832
4833 PointInfo
4834 delta;
4835
4836 register ssize_t
4837 j;
4838
4839 ssize_t
4840 k,
4841 n;
4842
cristye2a912b2011-12-05 20:02:07 +00004843 channel=GetPixelChannelMapChannel(source,i);
cristyabace412011-12-11 15:56:53 +00004844 traits=GetPixelChannelMapTraits(source,channel);
cristy5c4e2582011-09-11 19:21:03 +00004845 destination_traits=GetPixelChannelMapTraits(destination,channel);
4846 if ((traits == UndefinedPixelTrait) ||
4847 (destination_traits == UndefinedPixelTrait))
4848 continue;
4849 if ((traits & BlendPixelTrait) == 0)
4850 for (j=0; j < 16; j++)
4851 {
4852 alpha[j]=1.0;
4853 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
4854 }
4855 else
4856 for (j=0; j < 16; j++)
4857 {
4858 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4859 GetPixelChannels(source));
4860 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
4861 }
4862 delta.x=x-x_offset;
4863 delta.y=y-y_offset;
4864 sum=0.0;
4865 n=0;
4866 for (j=(-1); j < 3L; j++)
4867 {
4868 dy=CubicWeightingFunction((MagickRealType) j-delta.y);
4869 for (k=(-1); k < 3L; k++)
4870 {
4871 dx=CubicWeightingFunction(delta.x-(MagickRealType) k);
4872 gamma=1.0/(fabs((double) alpha[n]) <= MagickEpsilon ? 1.0 :
4873 alpha[n]);
4874 sum+=gamma*dx*dy*pixels[n];
4875 n++;
4876 }
4877 }
cristy4a7ae692011-12-14 12:24:11 +00004878 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00004879 }
4880 break;
4881 }
4882 }
4883 return(status);
4884}
4885
4886/*
4887%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4888% %
4889% %
4890% %
cristy9075cdb2011-07-30 01:06:23 +00004891% 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 +00004892% %
4893% %
4894% %
4895%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4896%
cristy884f6002011-07-31 00:51:45 +00004897% InterpolatePixelInfo() applies a pixel interpolation method between a
4898% floating point coordinate and the pixels surrounding that coordinate. No
4899% pixel area resampling, or scaling of the result is performed.
cristy4c08aed2011-07-01 19:47:50 +00004900%
4901% The format of the InterpolatePixelInfo method is:
4902%
4903% MagickBooleanType InterpolatePixelInfo(const Image *image,
cristy5c4e2582011-09-11 19:21:03 +00004904% const CacheView *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00004905% const double x,const double y,PixelInfo *pixel,
4906% ExceptionInfo *exception)
4907%
4908% A description of each parameter follows:
4909%
4910% o image: the image.
4911%
4912% o image_view: the image view.
4913%
4914% o method: the pixel color interpolation method.
4915%
4916% o x,y: A double representing the current (x,y) position of the pixel.
4917%
4918% o pixel: return the interpolated pixel here.
4919%
4920% o exception: return any errors or warnings in this structure.
4921%
4922*/
4923
4924static inline void AlphaBlendPixelInfo(const Image *image,
4925 const Quantum *pixel,PixelInfo *pixel_info,MagickRealType *alpha)
4926{
4927 if (image->matte == MagickFalse)
4928 {
4929 *alpha=1.0;
4930 pixel_info->red=(MagickRealType) GetPixelRed(image,pixel);
4931 pixel_info->green=(MagickRealType) GetPixelGreen(image,pixel);
4932 pixel_info->blue=(MagickRealType) GetPixelBlue(image,pixel);
4933 pixel_info->black=0.0;
4934 if (image->colorspace == CMYKColorspace)
4935 pixel_info->black=(MagickRealType) GetPixelBlack(image,pixel);
4936 pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
4937 return;
4938 }
4939 *alpha=QuantumScale*GetPixelAlpha(image,pixel);
4940 pixel_info->red=(*alpha*GetPixelRed(image,pixel));
4941 pixel_info->green=(*alpha*GetPixelGreen(image,pixel));
4942 pixel_info->blue=(*alpha*GetPixelBlue(image,pixel));
4943 pixel_info->black=0.0;
4944 if (image->colorspace == CMYKColorspace)
4945 pixel_info->black=(*alpha*GetPixelBlack(image,pixel));
4946 pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
4947}
4948
4949static void BicubicInterpolate(const PixelInfo *pixels,const double dx,
4950 PixelInfo *pixel)
4951{
4952 MagickRealType
4953 dx2,
4954 p,
4955 q,
4956 r,
4957 s;
4958
4959 dx2=dx*dx;
4960 p=(pixels[3].red-pixels[2].red)-(pixels[0].red-pixels[1].red);
4961 q=(pixels[0].red-pixels[1].red)-p;
4962 r=pixels[2].red-pixels[0].red;
4963 s=pixels[1].red;
4964 pixel->red=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4965 p=(pixels[3].green-pixels[2].green)-(pixels[0].green-pixels[1].green);
4966 q=(pixels[0].green-pixels[1].green)-p;
4967 r=pixels[2].green-pixels[0].green;
4968 s=pixels[1].green;
4969 pixel->green=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4970 p=(pixels[3].blue-pixels[2].blue)-(pixels[0].blue-pixels[1].blue);
4971 q=(pixels[0].blue-pixels[1].blue)-p;
4972 r=pixels[2].blue-pixels[0].blue;
4973 s=pixels[1].blue;
4974 pixel->blue=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4975 p=(pixels[3].alpha-pixels[2].alpha)-(pixels[0].alpha-pixels[1].alpha);
4976 q=(pixels[0].alpha-pixels[1].alpha)-p;
4977 r=pixels[2].alpha-pixels[0].alpha;
4978 s=pixels[1].alpha;
4979 pixel->alpha=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4980 if (pixel->colorspace == CMYKColorspace)
4981 {
4982 p=(pixels[3].black-pixels[2].black)-(pixels[0].black-pixels[1].black);
4983 q=(pixels[0].black-pixels[1].black)-p;
4984 r=pixels[2].black-pixels[0].black;
4985 s=pixels[1].black;
4986 pixel->black=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4987 }
4988}
4989
cristy4c08aed2011-07-01 19:47:50 +00004990MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
cristy5c4e2582011-09-11 19:21:03 +00004991 const CacheView *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00004992 const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception)
4993{
4994 MagickBooleanType
4995 status;
4996
cristy4c08aed2011-07-01 19:47:50 +00004997 MagickRealType
4998 alpha[16],
4999 gamma;
5000
cristy865d58d2011-07-09 00:44:52 +00005001 PixelInfo
5002 pixels[16];
5003
cristy4c08aed2011-07-01 19:47:50 +00005004 register const Quantum
5005 *p;
5006
5007 register ssize_t
5008 i;
5009
5010 ssize_t
5011 x_offset,
5012 y_offset;
5013
5014 assert(image != (Image *) NULL);
5015 assert(image->signature == MagickSignature);
5016 assert(image_view != (CacheView *) NULL);
5017 status=MagickTrue;
5018 x_offset=(ssize_t) floor(x);
5019 y_offset=(ssize_t) floor(y);
5020 switch (method == UndefinedInterpolatePixel ? image->interpolate : method)
5021 {
5022 case AverageInterpolatePixel:
5023 {
5024 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5025 exception);
5026 if (p == (const Quantum *) NULL)
5027 {
5028 status=MagickFalse;
5029 break;
5030 }
cristy5ce8df82011-07-07 14:52:23 +00005031 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005032 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005033 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5034 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5035 AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
5036 AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
5037 AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
5038 AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
5039 AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
5040 AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
5041 AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
cristy865d58d2011-07-09 00:44:52 +00005042 10);
cristyed231572011-07-14 02:18:59 +00005043 AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
cristy865d58d2011-07-09 00:44:52 +00005044 11);
cristyed231572011-07-14 02:18:59 +00005045 AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
cristy865d58d2011-07-09 00:44:52 +00005046 12);
cristyed231572011-07-14 02:18:59 +00005047 AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
cristy865d58d2011-07-09 00:44:52 +00005048 13);
cristyed231572011-07-14 02:18:59 +00005049 AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
cristy865d58d2011-07-09 00:44:52 +00005050 14);
cristyed231572011-07-14 02:18:59 +00005051 AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
cristy865d58d2011-07-09 00:44:52 +00005052 15);
cristy4c08aed2011-07-01 19:47:50 +00005053 pixel->red=0.0;
5054 pixel->green=0.0;
5055 pixel->blue=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005056 pixel->black=0.0;
cristy865d58d2011-07-09 00:44:52 +00005057 pixel->alpha=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005058 for (i=0; i < 16L; i++)
5059 {
5060 gamma=1.0/(fabs((double) alpha[i]) <= MagickEpsilon ? 1.0 : alpha[i]);
5061 pixel->red+=gamma*0.0625*pixels[i].red;
5062 pixel->green+=gamma*0.0625*pixels[i].green;
5063 pixel->blue+=gamma*0.0625*pixels[i].blue;
cristy4c08aed2011-07-01 19:47:50 +00005064 if (image->colorspace == CMYKColorspace)
5065 pixel->black+=gamma*0.0625*pixels[i].black;
cristy865d58d2011-07-09 00:44:52 +00005066 pixel->alpha+=0.0625*pixels[i].alpha;
cristy4c08aed2011-07-01 19:47:50 +00005067 }
5068 break;
5069 }
5070 case BicubicInterpolatePixel:
5071 {
5072 PixelInfo
5073 u[4];
5074
5075 PointInfo
5076 delta;
5077
5078 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5079 exception);
5080 if (p == (const Quantum *) NULL)
5081 {
5082 status=MagickFalse;
5083 break;
5084 }
cristy5ce8df82011-07-07 14:52:23 +00005085 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005086 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005087 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5088 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5089 AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
5090 AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
5091 AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
5092 AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
5093 AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
5094 AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
5095 AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
cristy865d58d2011-07-09 00:44:52 +00005096 10);
cristyed231572011-07-14 02:18:59 +00005097 AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
cristy865d58d2011-07-09 00:44:52 +00005098 11);
cristyed231572011-07-14 02:18:59 +00005099 AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
cristy865d58d2011-07-09 00:44:52 +00005100 12);
cristyed231572011-07-14 02:18:59 +00005101 AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
cristy865d58d2011-07-09 00:44:52 +00005102 13);
cristyed231572011-07-14 02:18:59 +00005103 AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
cristy865d58d2011-07-09 00:44:52 +00005104 14);
cristyed231572011-07-14 02:18:59 +00005105 AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
cristy865d58d2011-07-09 00:44:52 +00005106 15);
cristy4c08aed2011-07-01 19:47:50 +00005107 delta.x=x-x_offset;
5108 delta.y=y-y_offset;
5109 for (i=0; i < 4L; i++)
5110 BicubicInterpolate(pixels+4*i,delta.x,u+i);
5111 BicubicInterpolate(u,delta.y,pixel);
5112 break;
5113 }
5114 case BilinearInterpolatePixel:
5115 default:
5116 {
5117 PointInfo
5118 delta,
5119 epsilon;
5120
5121 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5122 if (p == (const Quantum *) NULL)
5123 {
5124 status=MagickFalse;
5125 break;
5126 }
cristy5ce8df82011-07-07 14:52:23 +00005127 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005128 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005129 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5130 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
cristy4c08aed2011-07-01 19:47:50 +00005131 delta.x=x-x_offset;
5132 delta.y=y-y_offset;
5133 epsilon.x=1.0-delta.x;
5134 epsilon.y=1.0-delta.y;
5135 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
5136 (epsilon.x*alpha[2]+delta.x*alpha[3])));
5137 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
5138 pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x*
5139 pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red));
5140 pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x*
5141 pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x*
5142 pixels[3].green));
5143 pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x*
5144 pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x*
5145 pixels[3].blue));
cristy4c08aed2011-07-01 19:47:50 +00005146 if (image->colorspace == CMYKColorspace)
5147 pixel->black=gamma*(epsilon.y*(epsilon.x*pixels[0].black+delta.x*
5148 pixels[1].black)+delta.y*(epsilon.x*pixels[2].black+delta.x*
5149 pixels[3].black));
cristy884f6002011-07-31 00:51:45 +00005150 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
5151 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
cristy865d58d2011-07-09 00:44:52 +00005152 pixel->alpha=(epsilon.y*(epsilon.x*pixels[0].alpha+delta.x*
5153 pixels[1].alpha)+delta.y*(epsilon.x*pixels[2].alpha+delta.x*
5154 pixels[3].alpha));
cristy4c08aed2011-07-01 19:47:50 +00005155 break;
5156 }
5157 case FilterInterpolatePixel:
5158 {
5159 CacheView
5160 *filter_view;
5161
5162 Image
5163 *excerpt_image,
5164 *filter_image;
5165
5166 RectangleInfo
5167 geometry;
5168
5169 geometry.width=4L;
5170 geometry.height=4L;
5171 geometry.x=x_offset-1;
5172 geometry.y=y_offset-1;
5173 excerpt_image=ExcerptImage(image,&geometry,exception);
5174 if (excerpt_image == (Image *) NULL)
5175 {
5176 status=MagickFalse;
5177 break;
5178 }
5179 filter_image=ResizeImage(excerpt_image,1,1,image->filter,image->blur,
5180 exception);
5181 excerpt_image=DestroyImage(excerpt_image);
5182 if (filter_image == (Image *) NULL)
5183 break;
5184 filter_view=AcquireCacheView(filter_image);
5185 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
5186 if (p != (const Quantum *) NULL)
cristy803640d2011-11-17 02:11:32 +00005187 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005188 filter_view=DestroyCacheView(filter_view);
5189 filter_image=DestroyImage(filter_image);
5190 break;
5191 }
5192 case IntegerInterpolatePixel:
5193 {
5194 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
5195 if (p == (const Quantum *) NULL)
5196 {
5197 status=MagickFalse;
5198 break;
5199 }
cristy803640d2011-11-17 02:11:32 +00005200 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005201 break;
5202 }
5203 case MeshInterpolatePixel:
5204 {
5205 PointInfo
5206 delta,
5207 luminance;
5208
cristy94ea1632011-07-30 20:40:25 +00005209 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
cristy4c08aed2011-07-01 19:47:50 +00005210 if (p == (const Quantum *) NULL)
5211 {
5212 status=MagickFalse;
5213 break;
5214 }
cristy94ea1632011-07-30 20:40:25 +00005215 delta.x=x-x_offset;
5216 delta.y=y-y_offset;
cristy884f6002011-07-31 00:51:45 +00005217 luminance.x=GetPixelLuminance(image,p)-(double)
cristy94ea1632011-07-30 20:40:25 +00005218 GetPixelLuminance(image,p+3*GetPixelChannels(image));
cristy28474bf2011-09-11 23:32:52 +00005219 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
cristy94ea1632011-07-30 20:40:25 +00005220 GetPixelLuminance(image,p+2*GetPixelChannels(image));
cristy5ce8df82011-07-07 14:52:23 +00005221 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005222 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005223 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5224 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
cristy4c08aed2011-07-01 19:47:50 +00005225 if (fabs(luminance.x) < fabs(luminance.y))
5226 {
5227 /*
5228 Diagonal 0-3 NW-SE.
5229 */
5230 if (delta.x <= delta.y)
5231 {
5232 /*
cristy94ea1632011-07-30 20:40:25 +00005233 Bottom-left triangle (pixel: 2, diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005234 */
5235 delta.y=1.0-delta.y;
5236 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
5237 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
5238 pixel->red=gamma*MeshInterpolate(&delta,pixels[2].red,
5239 pixels[3].red,pixels[0].red);
5240 pixel->green=gamma*MeshInterpolate(&delta,pixels[2].green,
5241 pixels[3].green,pixels[0].green);
5242 pixel->blue=gamma*MeshInterpolate(&delta,pixels[2].blue,
5243 pixels[3].blue,pixels[0].blue);
cristy4c08aed2011-07-01 19:47:50 +00005244 if (image->colorspace == CMYKColorspace)
5245 pixel->black=gamma*MeshInterpolate(&delta,pixels[2].black,
5246 pixels[3].black,pixels[0].black);
cristy94ea1632011-07-30 20:40:25 +00005247 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005248 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[2].alpha,
5249 pixels[3].alpha,pixels[0].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005250 }
5251 else
5252 {
5253 /*
cristy94ea1632011-07-30 20:40:25 +00005254 Top-right triangle (pixel:1 , diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005255 */
5256 delta.x=1.0-delta.x;
5257 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
5258 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
5259 pixel->red=gamma*MeshInterpolate(&delta,pixels[1].red,
5260 pixels[0].red,pixels[3].red);
5261 pixel->green=gamma*MeshInterpolate(&delta,pixels[1].green,
5262 pixels[0].green,pixels[3].green);
5263 pixel->blue=gamma*MeshInterpolate(&delta,pixels[1].blue,
5264 pixels[0].blue,pixels[3].blue);
cristy4c08aed2011-07-01 19:47:50 +00005265 if (image->colorspace == CMYKColorspace)
5266 pixel->black=gamma*MeshInterpolate(&delta,pixels[1].black,
5267 pixels[0].black,pixels[3].black);
cristy94ea1632011-07-30 20:40:25 +00005268 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005269 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[1].alpha,
5270 pixels[0].alpha,pixels[3].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005271 }
5272 }
5273 else
5274 {
5275 /*
5276 Diagonal 1-2 NE-SW.
5277 */
5278 if (delta.x <= (1.0-delta.y))
5279 {
5280 /*
cristy94ea1632011-07-30 20:40:25 +00005281 Top-left triangle (pixel: 0, diagonal: 1-2).
cristy4c08aed2011-07-01 19:47:50 +00005282 */
5283 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
5284 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
5285 pixel->red=gamma*MeshInterpolate(&delta,pixels[0].red,
5286 pixels[1].red,pixels[2].red);
5287 pixel->green=gamma*MeshInterpolate(&delta,pixels[0].green,
5288 pixels[1].green,pixels[2].green);
5289 pixel->blue=gamma*MeshInterpolate(&delta,pixels[0].blue,
5290 pixels[1].blue,pixels[2].blue);
cristy4c08aed2011-07-01 19:47:50 +00005291 if (image->colorspace == CMYKColorspace)
5292 pixel->black=gamma*MeshInterpolate(&delta,pixels[0].black,
5293 pixels[1].black,pixels[2].black);
cristy94ea1632011-07-30 20:40:25 +00005294 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005295 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[0].alpha,
5296 pixels[1].alpha,pixels[2].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005297 }
5298 else
5299 {
5300 /*
5301 Bottom-right triangle (pixel: 3, diagonal: 1-2).
5302 */
5303 delta.x=1.0-delta.x;
5304 delta.y=1.0-delta.y;
5305 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
5306 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
5307 pixel->red=gamma*MeshInterpolate(&delta,pixels[3].red,
5308 pixels[2].red,pixels[1].red);
5309 pixel->green=gamma*MeshInterpolate(&delta,pixels[3].green,
5310 pixels[2].green,pixels[1].green);
5311 pixel->blue=gamma*MeshInterpolate(&delta,pixels[3].blue,
5312 pixels[2].blue,pixels[1].blue);
cristy4c08aed2011-07-01 19:47:50 +00005313 if (image->colorspace == CMYKColorspace)
5314 pixel->black=gamma*MeshInterpolate(&delta,pixels[3].black,
5315 pixels[2].black,pixels[1].black);
cristy94ea1632011-07-30 20:40:25 +00005316 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005317 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[3].alpha,
5318 pixels[2].alpha,pixels[1].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005319 }
5320 }
5321 break;
5322 }
5323 case NearestNeighborInterpolatePixel:
5324 {
5325 p=GetCacheViewVirtualPixels(image_view,NearestNeighbor(x),
5326 NearestNeighbor(y),1,1,exception);
5327 if (p == (const Quantum *) NULL)
5328 {
5329 status=MagickFalse;
5330 break;
5331 }
cristy803640d2011-11-17 02:11:32 +00005332 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005333 break;
5334 }
5335 case SplineInterpolatePixel:
5336 {
5337 MagickRealType
5338 dx,
5339 dy;
5340
5341 PointInfo
5342 delta;
5343
5344 ssize_t
5345 j,
5346 n;
5347
5348 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5349 exception);
5350 if (p == (const Quantum *) NULL)
5351 {
5352 status=MagickFalse;
5353 break;
5354 }
cristy5ce8df82011-07-07 14:52:23 +00005355 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005356 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005357 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5358 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5359 AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
5360 AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
5361 AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
5362 AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
5363 AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
5364 AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
5365 AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
cristy865d58d2011-07-09 00:44:52 +00005366 10);
cristyed231572011-07-14 02:18:59 +00005367 AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
cristy865d58d2011-07-09 00:44:52 +00005368 11);
cristyed231572011-07-14 02:18:59 +00005369 AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
cristy865d58d2011-07-09 00:44:52 +00005370 12);
cristyed231572011-07-14 02:18:59 +00005371 AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
cristy865d58d2011-07-09 00:44:52 +00005372 13);
cristyed231572011-07-14 02:18:59 +00005373 AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
cristy865d58d2011-07-09 00:44:52 +00005374 14);
cristyed231572011-07-14 02:18:59 +00005375 AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
cristy865d58d2011-07-09 00:44:52 +00005376 15);
cristy4c08aed2011-07-01 19:47:50 +00005377 pixel->red=0.0;
5378 pixel->green=0.0;
5379 pixel->blue=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005380 pixel->black=0.0;
cristy865d58d2011-07-09 00:44:52 +00005381 pixel->alpha=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005382 delta.x=x-x_offset;
5383 delta.y=y-y_offset;
5384 n=0;
5385 for (i=(-1); i < 3L; i++)
5386 {
5387 dy=CubicWeightingFunction((MagickRealType) i-delta.y);
5388 for (j=(-1); j < 3L; j++)
5389 {
5390 dx=CubicWeightingFunction(delta.x-(MagickRealType) j);
5391 gamma=1.0/(fabs((double) alpha[n]) <= MagickEpsilon ? 1.0 : alpha[n]);
5392 pixel->red+=gamma*dx*dy*pixels[n].red;
5393 pixel->green+=gamma*dx*dy*pixels[n].green;
5394 pixel->blue+=gamma*dx*dy*pixels[n].blue;
5395 if (image->colorspace == CMYKColorspace)
5396 pixel->black+=gamma*dx*dy*pixels[n].black;
5397 pixel->alpha+=dx*dy*pixels[n].alpha;
5398 n++;
5399 }
5400 }
5401 break;
5402 }
5403 }
5404 return(status);
5405}
5406
5407/*
5408%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5409% %
5410% %
5411% %
5412+ I s F u z z y E q u i v a l e n c e P i x e l %
5413% %
5414% %
5415% %
5416%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5417%
5418% IsFuzzyEquivalencePixel() returns MagickTrue if the distance between two
5419% pixels is less than the specified distance in a linear three (or four)u
5420% dimensional color space.
5421%
5422% The format of the IsFuzzyEquivalencePixel method is:
5423%
cristye4a40472011-12-22 02:56:19 +00005424% void IsFuzzyEquivalencePixel(const Image *source,const Quantum *p,
5425% const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005426%
5427% A description of each parameter follows:
5428%
cristye4a40472011-12-22 02:56:19 +00005429% o source: the source image.
cristy4c08aed2011-07-01 19:47:50 +00005430%
5431% o p: Pixel p.
5432%
cristye4a40472011-12-22 02:56:19 +00005433% o destination: the destination image.
5434%
cristy4c08aed2011-07-01 19:47:50 +00005435% o q: Pixel q.
5436%
5437*/
cristye4a40472011-12-22 02:56:19 +00005438MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source,
5439 const Quantum *p,const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005440{
5441 MagickRealType
5442 fuzz,
5443 pixel;
5444
5445 register MagickRealType
5446 distance,
5447 scale;
5448
cristye4a40472011-12-22 02:56:19 +00005449 fuzz=MagickMax(source->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(
5450 destination->fuzz,(MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005451 scale=1.0;
5452 distance=0.0;
cristye4a40472011-12-22 02:56:19 +00005453 if (source->matte != MagickFalse)
cristy4c08aed2011-07-01 19:47:50 +00005454 {
5455 /*
5456 Transparencies are involved - set alpha distance
5457 */
cristy99abff32011-12-24 20:45:16 +00005458 pixel=GetPixelAlpha(source,p)-(MagickRealType)
5459 GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005460 distance=pixel*pixel;
5461 if (distance > fuzz)
5462 return(MagickFalse);
5463 /*
5464 Generate a alpha scaling factor to generate a 4D cone on colorspace
5465 Note that if one color is transparent, distance has no color component.
5466 */
cristye4a40472011-12-22 02:56:19 +00005467 scale=QuantumScale*GetPixelAlpha(source,p);
5468 scale*=QuantumScale*GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005469 if (scale <= MagickEpsilon)
5470 return(MagickTrue);
5471 }
5472 /*
5473 RGB or CMY color cube
5474 */
5475 distance*=3.0; /* rescale appropriately */
5476 fuzz*=3.0;
cristye4a40472011-12-22 02:56:19 +00005477 pixel=GetPixelRed(source,p)-(MagickRealType) GetPixelRed(destination,q);
5478 if ((source->colorspace == HSLColorspace) ||
5479 (source->colorspace == HSBColorspace) ||
5480 (source->colorspace == HWBColorspace))
cristy4c08aed2011-07-01 19:47:50 +00005481 {
5482 /*
5483 Compute an arc distance for hue. It should be a vector angle of
5484 'S'/'W' length with 'L'/'B' forming appropriate cones.
5485 */
5486 if (fabs((double) pixel) > (QuantumRange/2))
5487 pixel-=QuantumRange;
5488 pixel*=2;
5489 }
5490 distance+=scale*pixel*pixel;
5491 if (distance > fuzz)
5492 return(MagickFalse);
cristye4a40472011-12-22 02:56:19 +00005493 pixel=GetPixelGreen(source,p)-(MagickRealType) GetPixelGreen(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005494 distance+=scale*pixel*pixel;
5495 if (distance > fuzz)
5496 return(MagickFalse);
cristye4a40472011-12-22 02:56:19 +00005497 pixel=GetPixelBlue(source,p)-(MagickRealType) GetPixelBlue(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005498 distance+=scale*pixel*pixel;
5499 if (distance > fuzz)
5500 return(MagickFalse);
5501 return(MagickTrue);
5502}
5503
5504/*
5505%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5506% %
5507% %
5508% %
5509+ 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 %
5510% %
5511% %
5512% %
5513%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5514%
5515% IsFuzzyEquivalencePixelInfo() returns true if the distance between two
5516% colors is less than the specified distance in a linear three (or four)
5517% dimensional color space.
5518%
cristy5f95f4f2011-10-23 01:01:01 +00005519% This implements the equivalent of:
5520% fuzz < sqrt(color_distance^2 * u.a*v.a + alpha_distance^2)
cristy4c08aed2011-07-01 19:47:50 +00005521%
5522% Which produces a multi-dimensional cone for that colorspace along the
5523% transparency vector.
5524%
cristy5f95f4f2011-10-23 01:01:01 +00005525% For example for an RGB:
cristy4c08aed2011-07-01 19:47:50 +00005526% color_distance^2 = ( (u.r-v.r)^2 + (u.g-v.g)^2 + (u.b-v.b)^2 ) / 3
5527%
5528% See http://www.imagemagick.org/Usage/bugs/fuzz_distance/
5529%
5530% Hue colorspace distances need more work. Hue is not a distance, it is an
5531% angle!
5532%
5533% A check that q is in the same color space as p should be made and the
5534% appropriate mapping made. -- Anthony Thyssen 8 December 2010
5535%
5536% The format of the IsFuzzyEquivalencePixelInfo method is:
5537%
5538% MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5539% const PixelInfo *q)
5540%
5541% A description of each parameter follows:
5542%
5543% o p: Pixel p.
5544%
5545% o q: Pixel q.
5546%
5547*/
5548MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5549 const PixelInfo *q)
5550{
5551 MagickRealType
5552 fuzz,
5553 pixel;
5554
5555 register MagickRealType
5556 scale,
5557 distance;
5558
5559 if ((p->fuzz == 0.0) && (q->fuzz == 0.0))
5560 return(IsPixelInfoEquivalent(p,q));
5561 if (p->fuzz == 0.0)
cristy5f95f4f2011-10-23 01:01:01 +00005562 fuzz=MagickMax(q->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(q->fuzz,
5563 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005564 else if (q->fuzz == 0.0)
cristy5f95f4f2011-10-23 01:01:01 +00005565 fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(p->fuzz,
5566 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005567 else
cristy5f95f4f2011-10-23 01:01:01 +00005568 fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(q->fuzz,
5569 (MagickRealType) MagickSQ1_2);
cristy4c08aed2011-07-01 19:47:50 +00005570 scale=1.0;
5571 distance=0.0;
5572 if ((p->matte != MagickFalse) || (q->matte != MagickFalse))
5573 {
5574 /*
5575 Transparencies are involved - set alpha distance.
5576 */
5577 pixel=(p->matte != MagickFalse ? p->alpha : OpaqueAlpha)-
5578 (q->matte != MagickFalse ? q->alpha : OpaqueAlpha);
5579 distance=pixel*pixel;
5580 if (distance > fuzz)
5581 return(MagickFalse);
5582 /*
5583 Generate a alpha scaling factor to generate a 4D cone on colorspace.
cristy5f95f4f2011-10-23 01:01:01 +00005584 If one color is transparent, distance has no color component.
cristy4c08aed2011-07-01 19:47:50 +00005585 */
5586 if (p->matte != MagickFalse)
5587 scale=(QuantumScale*p->alpha);
5588 if (q->matte != MagickFalse)
5589 scale*=(QuantumScale*q->alpha);
5590 if (scale <= MagickEpsilon )
5591 return(MagickTrue);
5592 }
5593 /*
5594 CMYK create a CMY cube with a multi-dimensional cone toward black.
5595 */
5596 if (p->colorspace == CMYKColorspace)
5597 {
5598 pixel=p->black-q->black;
5599 distance+=pixel*pixel*scale;
5600 if (distance > fuzz)
5601 return(MagickFalse);
5602 scale*=(MagickRealType) (QuantumScale*(QuantumRange-p->black));
5603 scale*=(MagickRealType) (QuantumScale*(QuantumRange-q->black));
5604 }
5605 /*
5606 RGB or CMY color cube.
5607 */
5608 distance*=3.0; /* rescale appropriately */
5609 fuzz*=3.0;
5610 pixel=p->red-q->red;
5611 if ((p->colorspace == HSLColorspace) || (p->colorspace == HSBColorspace) ||
5612 (p->colorspace == HWBColorspace))
5613 {
cristy5f95f4f2011-10-23 01:01:01 +00005614 /*
5615 This calculates a arc distance for hue-- it should be a vector angle
5616 of 'S'/'W' length with 'L'/'B' forming appropriate cones. In other
5617 words this is a hack - Anthony.
cristy4c08aed2011-07-01 19:47:50 +00005618 */
5619 if (fabs((double) pixel) > (QuantumRange/2))
5620 pixel-=QuantumRange;
5621 pixel*=2;
5622 }
5623 distance+=pixel*pixel*scale;
5624 if (distance > fuzz)
5625 return(MagickFalse);
5626 pixel=p->green-q->green;
5627 distance+=pixel*pixel*scale;
5628 if (distance > fuzz)
5629 return(MagickFalse);
5630 pixel=p->blue-q->blue;
5631 distance+=pixel*pixel*scale;
5632 if (distance > fuzz)
5633 return(MagickFalse);
5634 return(MagickTrue);
5635}
5636
5637/*
5638%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5639% %
5640% %
5641% %
cristye2a912b2011-12-05 20:02:07 +00005642% 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 +00005643% %
5644% %
5645% %
5646%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5647%
cristye2a912b2011-12-05 20:02:07 +00005648% SetPixelChannelMapMask() sets the pixel channel map from the specified
5649% channel mask.
cristy2b9582a2011-07-04 17:38:56 +00005650%
cristye2a912b2011-12-05 20:02:07 +00005651% The format of the SetPixelChannelMapMask method is:
cristy2b9582a2011-07-04 17:38:56 +00005652%
cristye2a912b2011-12-05 20:02:07 +00005653% void SetPixelChannelMapMask(Image *image,const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005654%
5655% A description of each parameter follows:
5656%
5657% o image: the image.
5658%
cristy44261462011-08-09 13:34:47 +00005659% o mask: the channel mask.
cristy2b9582a2011-07-04 17:38:56 +00005660%
5661*/
cristye2a912b2011-12-05 20:02:07 +00005662MagickExport void SetPixelChannelMapMask(Image *image,
cristy07a67852011-08-26 13:25:03 +00005663 const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005664{
cristy6a917d62011-08-24 17:31:30 +00005665#define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01)
cristydafd2872011-07-24 22:06:13 +00005666
cristy2b9582a2011-07-04 17:38:56 +00005667 register ssize_t
5668 i;
5669
cristy3c309812011-11-08 02:40:43 +00005670 image->channel_mask=channel_mask;
cristydafd2872011-07-24 22:06:13 +00005671 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
cristye2a912b2011-12-05 20:02:07 +00005672 {
5673 PixelChannel
5674 channel;
5675
5676 channel=GetPixelChannelMapChannel(image,i);
5677 SetPixelChannelMapTraits(image,channel,
5678 GetChannelBit(channel_mask,channel) == 0 ? CopyPixelTrait :
cristy0bbd87c2011-12-13 19:34:45 +00005679 image->matte == MagickFalse || (channel == AlphaPixelChannel) ?
5680 UpdatePixelTrait : (PixelTrait) (UpdatePixelTrait | BlendPixelTrait));
cristye2a912b2011-12-05 20:02:07 +00005681 }
cristy1685e722011-09-06 00:04:19 +00005682 if (image->storage_class == PseudoClass)
5683 SetPixelChannelMapTraits(image,IndexPixelChannel,CopyPixelTrait);
cristy6dcb9b82011-10-23 23:21:25 +00005684 if (image->debug != MagickFalse)
5685 LogPixelChannels(image);
cristy2b9582a2011-07-04 17:38:56 +00005686}
5687
5688/*
5689%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5690% %
5691% %
5692% %
cristybd5a96c2011-08-21 00:04:26 +00005693% 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 +00005694% %
5695% %
5696% %
5697%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5698%
cristy5f95f4f2011-10-23 01:01:01 +00005699% SetPixelChannelMask() sets the pixel channel mask from the specified channel
5700% mask.
cristy2b9582a2011-07-04 17:38:56 +00005701%
cristybd5a96c2011-08-21 00:04:26 +00005702% The format of the SetPixelChannelMask method is:
cristy2b9582a2011-07-04 17:38:56 +00005703%
cristybd5a96c2011-08-21 00:04:26 +00005704% ChannelType SetPixelChannelMask(Image *image,
5705% const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005706%
5707% A description of each parameter follows:
5708%
5709% o image: the image.
5710%
cristybd5a96c2011-08-21 00:04:26 +00005711% o channel_mask: the channel mask.
5712%
cristy2b9582a2011-07-04 17:38:56 +00005713*/
cristybd5a96c2011-08-21 00:04:26 +00005714MagickExport ChannelType SetPixelChannelMask(Image *image,
5715 const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00005716{
cristybd5a96c2011-08-21 00:04:26 +00005717 ChannelType
5718 mask;
cristy222b19c2011-08-04 01:35:11 +00005719
cristybd5a96c2011-08-21 00:04:26 +00005720 mask=image->channel_mask;
5721 image->channel_mask=channel_mask;
cristye2a912b2011-12-05 20:02:07 +00005722 SetPixelChannelMapMask(image,channel_mask);
cristybd5a96c2011-08-21 00:04:26 +00005723 return(mask);
cristy2b9582a2011-07-04 17:38:56 +00005724}