]> granicus.if.org Git - imagemagick/blob - MagickCore/pixel.c
(no commit message)
[imagemagick] / MagickCore / pixel.c
1 /*
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 %                                                                             %
19 %  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
20 %  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 \f
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 \f
71 #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 \
84       *name; \
85  \
86     PixelChannel \
87       channel; \
88  \
89     switch (GetPixelChannelMapChannel(image,i)) \
90     { \
91       case RedPixelChannel: \
92       { \
93         name="red"; \
94         if (image->colorspace == CMYKColorspace) \
95           name="cyan"; \
96         if (image->colorspace == GRAYColorspace) \
97           name="gray"; \
98         break; \
99       } \
100       case GreenPixelChannel: \
101       { \
102         name="green"; \
103         if (image->colorspace == CMYKColorspace) \
104           name="magenta"; \
105         break; \
106       } \
107       case BluePixelChannel: \
108       { \
109         name="blue"; \
110         if (image->colorspace == CMYKColorspace) \
111           name="yellow"; \
112         break; \
113       } \
114       case BlackPixelChannel: \
115       { \
116         name="black"; \
117         if (image->storage_class == PseudoClass) \
118           name="index"; \
119         break; \
120       } \
121       case IndexPixelChannel: \
122       { \
123         name="index"; \
124         break; \
125       } \
126       case AlphaPixelChannel: \
127       { \
128         name="alpha"; \
129         break; \
130       } \
131       case MaskPixelChannel: \
132       { \
133         name="mask"; \
134         break; \
135       } \
136       case MetaPixelChannel: \
137       { \
138         name="meta"; \
139         break; \
140       } \
141       default: \
142         name="undefined"; \
143     } \
144     channel=GetPixelChannelMapChannel(image,i); \
145     *traits='\0'; \
146     if ((GetPixelChannelMapTraits(image,channel) & UpdatePixelTrait) != 0) \
147       (void) ConcatenateMagickString(traits,"update,",MaxTextExtent); \
148     if ((GetPixelChannelMapTraits(image,channel) & BlendPixelTrait) != 0) \
149       (void) ConcatenateMagickString(traits,"blend,",MaxTextExtent); \
150     if ((GetPixelChannelMapTraits(image,channel) & CopyPixelTrait) != 0) \
151       (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)", \
156       (double) i,name,traits); \
157   } \
158 }
159 \f
160 /*
161 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
162 %                                                                             %
163 %                                                                             %
164 %                                                                             %
165 +   A c q u i r e P i x e l C h a n n e l M a p                               %
166 %                                                                             %
167 %                                                                             %
168 %                                                                             %
169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
170 %
171 %  AcquirePixelChannelMap() acquires a pixel component map.
172 %
173 %  The format of the AcquirePixelChannelMap() method is:
174 %
175 %      PixelChannelMap *AcquirePixelChannelMap(void)
176 %
177 */
178 MagickExport PixelChannelMap *AcquirePixelChannelMap(void)
179 {
180   PixelChannelMap
181     *channel_map;
182
183   register ssize_t
184     i;
185
186   channel_map=(PixelChannelMap *) AcquireQuantumMemory(MaxPixelChannels,
187     sizeof(*channel_map));
188   if (channel_map == (PixelChannelMap *) NULL)
189     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
190   (void) ResetMagickMemory(channel_map,0,MaxPixelChannels*sizeof(*channel_map));
191   for (i=0; i < MaxPixelChannels; i++)
192     channel_map[i].channel=(PixelChannel) i;
193   return(channel_map);
194 }
195 \f
196 /*
197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
198 %                                                                             %
199 %                                                                             %
200 %                                                                             %
201 +   C l o n e P i x e l C h a n n e l M a p                                   %
202 %                                                                             %
203 %                                                                             %
204 %                                                                             %
205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
206 %
207 %  ClonePixelChannelMap() clones a pixel component map.
208 %
209 %  The format of the ClonePixelChannelMap() method is:
210 %
211 %      PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
212 %
213 %  A description of each parameter follows:
214 %
215 %    o channel_map: the pixel component map.
216 %
217 */
218 MagickExport PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
219 {
220   PixelChannelMap
221     *clone_map;
222
223   assert(channel_map != (PixelChannelMap *) NULL);
224   clone_map=AcquirePixelChannelMap();
225   if (clone_map == (PixelChannelMap *) NULL)
226     return((PixelChannelMap *) NULL);
227   (void) CopyMagickMemory(clone_map,channel_map,MaxPixelChannels*
228     sizeof(*channel_map));
229   return(clone_map);
230 }
231 \f
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 */
255 MagickExport PixelInfo *ClonePixelInfo(const PixelInfo *pixel)
256 {
257   PixelInfo
258     *pixel_info;
259
260   pixel_info=(PixelInfo *) AcquireQuantumMemory(1,sizeof(*pixel_info));
261   if (pixel_info == (PixelInfo *) NULL)
262     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
263   *pixel_info=(*pixel);
264   return(pixel_info);
265 }
266 \f
267 /*
268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
269 %                                                                             %
270 %                                                                             %
271 %                                                                             %
272 +   D e s t r o y P i x e l C h a n n e l M a p                               %
273 %                                                                             %
274 %                                                                             %
275 %                                                                             %
276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
277 %
278 %  DestroyPixelChannelMap() deallocates memory associated with the pixel
279 %  channel map.
280 %
281 %  The format of the DestroyPixelChannelMap() method is:
282 %
283 %      PixelChannelMap *DestroyPixelChannelMap(PixelChannelMap *channel_map)
284 %
285 %  A description of each parameter follows:
286 %
287 %    o channel_map: the pixel component map.
288 %
289 */
290 MagickExport PixelChannelMap *DestroyPixelChannelMap(
291   PixelChannelMap *channel_map)
292 {
293   assert(channel_map != (PixelChannelMap *) NULL);
294   channel_map=(PixelChannelMap *) RelinquishMagickMemory(channel_map);
295   return((PixelChannelMap *) RelinquishMagickMemory(channel_map));
296 }
297 \f
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,
323 %        const size_t rows,const char *map,const StorageType type,
324 %        void *pixels,ExceptionInfo *exception)
325 %
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
341 %      types: CharPixel, DoublePixel, FloatPixel, IntegerPixel, LongPixel,
342 %      QuantumPixel, or ShortPixel.
343 %
344 %    o pixels: This array of values contain the pixel components as defined by
345 %      map and type.  You must preallocate this array where the expected
346 %      length varies depending on the values of width, height, map, and type.
347 %
348 %    o exception: return any errors or warnings in this structure.
349 %
350 */
351
352 static void ExportCharPixel(const Image *image,const ssize_t x_offset,
353   const ssize_t y_offset,const size_t columns,const size_t rows,
354   const char *restrict map,const QuantumType *quantum_map,
355   unsigned char *restrict pixels,ExceptionInfo *exception)
356 {
357   register const Quantum
358     *restrict p;
359
360   register ssize_t
361     x;
362
363   register unsigned char
364     *q;
365
366   ssize_t
367     y;
368
369   q=pixels;
370   if (LocaleCompare(map,"BGR") == 0)
371     {
372       for (y=0; y < (ssize_t) rows; y++)
373       {
374         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
375         if (p == (const Quantum *) NULL)
376           break;
377         for (x=0; x < (ssize_t) columns; x++)
378         {
379           *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
380           *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
381           *q++=ScaleQuantumToChar(GetPixelRed(image,p));
382           p+=GetPixelChannels(image);
383         }
384       }
385       return;
386     }
387   if (LocaleCompare(map,"BGRA") == 0)
388     {
389       for (y=0; y < (ssize_t) rows; y++)
390       {
391         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
392         if (p == (const Quantum *) NULL)
393           break;
394         for (x=0; x < (ssize_t) columns; x++)
395         {
396           *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
397           *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
398           *q++=ScaleQuantumToChar(GetPixelRed(image,p));
399           *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
400           p+=GetPixelChannels(image);
401         }
402       }
403       return;
404     }
405   if (LocaleCompare(map,"BGRP") == 0)
406     {
407       for (y=0; y < (ssize_t) rows; y++)
408       {
409         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
410         if (p == (const Quantum *) NULL)
411           break;
412         for (x=0; x < (ssize_t) columns; x++)
413         {
414           *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
415           *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
416           *q++=ScaleQuantumToChar(GetPixelRed(image,p));
417           *q++=ScaleQuantumToChar((Quantum) 0);
418           p+=GetPixelChannels(image);
419         }
420       }
421       return;
422     }
423   if (LocaleCompare(map,"I") == 0)
424     {
425       for (y=0; y < (ssize_t) rows; y++)
426       {
427         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
428         if (p == (const Quantum *) NULL)
429           break;
430         for (x=0; x < (ssize_t) columns; x++)
431         {
432           *q++=ScaleQuantumToChar(GetPixelIntensity(image,p));
433           p+=GetPixelChannels(image);
434         }
435       }
436       return;
437     }
438   if (LocaleCompare(map,"RGB") == 0)
439     {
440       for (y=0; y < (ssize_t) rows; y++)
441       {
442         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
443         if (p == (const Quantum *) NULL)
444           break;
445         for (x=0; x < (ssize_t) columns; x++)
446         {
447           *q++=ScaleQuantumToChar(GetPixelRed(image,p));
448           *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
449           *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
450           p+=GetPixelChannels(image);
451         }
452       }
453       return;
454     }
455   if (LocaleCompare(map,"RGBA") == 0)
456     {
457       for (y=0; y < (ssize_t) rows; y++)
458       {
459         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
460         if (p == (const Quantum *) NULL)
461           break;
462         for (x=0; x < (ssize_t) columns; x++)
463         {
464           *q++=ScaleQuantumToChar(GetPixelRed(image,p));
465           *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
466           *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
467           *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
468           p+=GetPixelChannels(image);
469         }
470       }
471       return;
472     }
473   if (LocaleCompare(map,"RGBP") == 0)
474     {
475       for (y=0; y < (ssize_t) rows; y++)
476       {
477         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
478         if (p == (const Quantum *) NULL)
479           break;
480         for (x=0; x < (ssize_t) columns; x++)
481         {
482           *q++=ScaleQuantumToChar(GetPixelRed(image,p));
483           *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
484           *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
485           *q++=ScaleQuantumToChar((Quantum) 0);
486           p+=GetPixelChannels(image);
487         }
488       }
489       return;
490     }
491   for (y=0; y < (ssize_t) rows; y++)
492   {
493     p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
494     if (p == (const Quantum *) NULL)
495       break;
496     for (x=0; x < (ssize_t) columns; x++)
497     {
498       register ssize_t
499         i;
500
501       for (i=0; i < (ssize_t) strlen(map); i++)
502       {
503         *q=0;
504         switch (quantum_map[i])
505         {
506           case RedQuantum:
507           case CyanQuantum:
508           {
509             *q=ScaleQuantumToChar(GetPixelRed(image,p));
510             break;
511           }
512           case GreenQuantum:
513           case MagentaQuantum:
514           {
515             *q=ScaleQuantumToChar(GetPixelGreen(image,p));
516             break;
517           }
518           case BlueQuantum:
519           case YellowQuantum:
520           {
521             *q=ScaleQuantumToChar(GetPixelBlue(image,p));
522             break;
523           }
524           case AlphaQuantum:
525           {
526             *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
527             break;
528           }
529           case OpacityQuantum:
530           {
531             *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
532             break;
533           }
534           case BlackQuantum:
535           {
536             if (image->colorspace == CMYKColorspace)
537               *q=ScaleQuantumToChar(GetPixelBlack(image,p));
538             break;
539           }
540           case IndexQuantum:
541           {
542             *q=ScaleQuantumToChar(GetPixelIntensity(image,p));
543             break;
544           }
545           default:
546             break;
547         }
548         q++;
549       }
550       p+=GetPixelChannels(image);
551     }
552   }
553 }
554
555 static void ExportDoublePixel(const Image *image,const ssize_t x_offset,
556   const ssize_t y_offset,const size_t columns,const size_t rows,
557   const char *restrict map,const QuantumType *quantum_map,
558   unsigned char *restrict pixels,ExceptionInfo *exception)
559 {
560   register const Quantum
561     *restrict p;
562
563   register double
564     *q;
565
566   register ssize_t
567     x;
568
569   ssize_t
570     y;
571
572   q=(double *) pixels;
573   if (LocaleCompare(map,"BGR") == 0)
574     {
575       for (y=0; y < (ssize_t) rows; y++)
576       {
577         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
578         if (p == (const Quantum *) NULL)
579           break;
580         for (x=0; x < (ssize_t) columns; x++)
581         {
582           *q++=(double) (QuantumScale*GetPixelBlue(image,p));
583           *q++=(double) (QuantumScale*GetPixelGreen(image,p));
584           *q++=(double) (QuantumScale*GetPixelRed(image,p));
585           p+=GetPixelChannels(image);
586         }
587       }
588       return;
589     }
590   if (LocaleCompare(map,"BGRA") == 0)
591     {
592       for (y=0; y < (ssize_t) rows; y++)
593       {
594         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
595         if (p == (const Quantum *) NULL)
596           break;
597         for (x=0; x < (ssize_t) columns; x++)
598         {
599           *q++=(double) (QuantumScale*GetPixelBlue(image,p));
600           *q++=(double) (QuantumScale*GetPixelGreen(image,p));
601           *q++=(double) (QuantumScale*GetPixelRed(image,p));
602           *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
603           p+=GetPixelChannels(image);
604         }
605       }
606       return;
607     }
608   if (LocaleCompare(map,"BGRP") == 0)
609     {
610       for (y=0; y < (ssize_t) rows; y++)
611       {
612         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
613         if (p == (const Quantum *) NULL)
614           break;
615         for (x=0; x < (ssize_t) columns; x++)
616         {
617           *q++=(double) (QuantumScale*GetPixelBlue(image,p));
618           *q++=(double) (QuantumScale*GetPixelGreen(image,p));
619           *q++=(double) (QuantumScale*GetPixelRed(image,p));
620           *q++=0.0;
621           p+=GetPixelChannels(image);
622         }
623       }
624       return;
625     }
626   if (LocaleCompare(map,"I") == 0)
627     {
628       for (y=0; y < (ssize_t) rows; y++)
629       {
630         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
631         if (p == (const Quantum *) NULL)
632           break;
633         for (x=0; x < (ssize_t) columns; x++)
634         {
635           *q++=(double) (QuantumScale*GetPixelIntensity(image,p));
636           p+=GetPixelChannels(image);
637         }
638       }
639       return;
640     }
641   if (LocaleCompare(map,"RGB") == 0)
642     {
643       for (y=0; y < (ssize_t) rows; y++)
644       {
645         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
646         if (p == (const Quantum *) NULL)
647           break;
648         for (x=0; x < (ssize_t) columns; x++)
649         {
650           *q++=(double) (QuantumScale*GetPixelRed(image,p));
651           *q++=(double) (QuantumScale*GetPixelGreen(image,p));
652           *q++=(double) (QuantumScale*GetPixelBlue(image,p));
653           p+=GetPixelChannels(image);
654         }
655       }
656       return;
657     }
658   if (LocaleCompare(map,"RGBA") == 0)
659     {
660       for (y=0; y < (ssize_t) rows; y++)
661       {
662         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
663         if (p == (const Quantum *) NULL)
664           break;
665         for (x=0; x < (ssize_t) columns; x++)
666         {
667           *q++=(double) (QuantumScale*GetPixelRed(image,p));
668           *q++=(double) (QuantumScale*GetPixelGreen(image,p));
669           *q++=(double) (QuantumScale*GetPixelBlue(image,p));
670           *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
671           p+=GetPixelChannels(image);
672         }
673       }
674       return;
675     }
676   if (LocaleCompare(map,"RGBP") == 0)
677     {
678       for (y=0; y < (ssize_t) rows; y++)
679       {
680         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
681         if (p == (const Quantum *) NULL)
682           break;
683         for (x=0; x < (ssize_t) columns; x++)
684         {
685           *q++=(double) (QuantumScale*GetPixelRed(image,p));
686           *q++=(double) (QuantumScale*GetPixelGreen(image,p));
687           *q++=(double) (QuantumScale*GetPixelBlue(image,p));
688           *q++=0.0;
689           p+=GetPixelChannels(image);
690         }
691       }
692       return;
693     }
694   for (y=0; y < (ssize_t) rows; y++)
695   {
696     p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
697     if (p == (const Quantum *) NULL)
698       break;
699     for (x=0; x < (ssize_t) columns; x++)
700     {
701       register ssize_t
702         i;
703
704       for (i=0; i < (ssize_t) strlen(map); i++)
705       {
706         *q=0;
707         switch (quantum_map[i])
708         {
709           case RedQuantum:
710           case CyanQuantum:
711           {
712             *q=(double) (QuantumScale*GetPixelRed(image,p));
713             break;
714           }
715           case GreenQuantum:
716           case MagentaQuantum:
717           {
718             *q=(double) (QuantumScale*GetPixelGreen(image,p));
719             break;
720           }
721           case BlueQuantum:
722           case YellowQuantum:
723           {
724             *q=(double) (QuantumScale*GetPixelBlue(image,p));
725             break;
726           }
727           case AlphaQuantum:
728           {
729             *q=(double) (QuantumScale*GetPixelAlpha(image,p));
730             break;
731           }
732           case OpacityQuantum:
733           {
734             *q=(double) (QuantumScale*GetPixelAlpha(image,p));
735             break;
736           }
737           case BlackQuantum:
738           {
739             if (image->colorspace == CMYKColorspace)
740               *q=(double) (QuantumScale*
741                 GetPixelBlack(image,p));
742             break;
743           }
744           case IndexQuantum:
745           {
746             *q=(double) (QuantumScale*GetPixelIntensity(image,p));
747             break;
748           }
749           default:
750             *q=0;
751         }
752         q++;
753       }
754       p+=GetPixelChannels(image);
755     }
756   }
757 }
758
759 static void ExportFloatPixel(const Image *image,const ssize_t x_offset,
760   const ssize_t y_offset,const size_t columns,const size_t rows,
761   const char *restrict map,const QuantumType *quantum_map,
762   unsigned char *restrict pixels,ExceptionInfo *exception)
763 {
764   register const Quantum
765     *restrict p;
766
767   register float
768     *q;
769
770   register ssize_t
771     x;
772
773   ssize_t
774     y;
775
776   q=(float *) pixels;
777   if (LocaleCompare(map,"BGR") == 0)
778     {
779       for (y=0; y < (ssize_t) rows; y++)
780       {
781         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
782         if (p == (const Quantum *) NULL)
783           break;
784         for (x=0; x < (ssize_t) columns; x++)
785         {
786           *q++=(float) (QuantumScale*GetPixelBlue(image,p));
787           *q++=(float) (QuantumScale*GetPixelGreen(image,p));
788           *q++=(float) (QuantumScale*GetPixelRed(image,p));
789           p+=GetPixelChannels(image);
790         }
791       }
792       return;
793     }
794   if (LocaleCompare(map,"BGRA") == 0)
795     {
796       for (y=0; y < (ssize_t) rows; y++)
797       {
798         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
799         if (p == (const Quantum *) NULL)
800           break;
801         for (x=0; x < (ssize_t) columns; x++)
802         {
803           *q++=(float) (QuantumScale*GetPixelBlue(image,p));
804           *q++=(float) (QuantumScale*GetPixelGreen(image,p));
805           *q++=(float) (QuantumScale*GetPixelRed(image,p));
806           *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
807           p+=GetPixelChannels(image);
808         }
809       }
810       return;
811     }
812   if (LocaleCompare(map,"BGRP") == 0)
813     {
814       for (y=0; y < (ssize_t) rows; y++)
815       {
816         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
817         if (p == (const Quantum *) NULL)
818           break;
819         for (x=0; x < (ssize_t) columns; x++)
820         {
821           *q++=(float) (QuantumScale*GetPixelBlue(image,p));
822           *q++=(float) (QuantumScale*GetPixelGreen(image,p));
823           *q++=(float) (QuantumScale*GetPixelRed(image,p));
824           *q++=0.0;
825           p+=GetPixelChannels(image);
826         }
827       }
828       return;
829     }
830   if (LocaleCompare(map,"I") == 0)
831     {
832       for (y=0; y < (ssize_t) rows; y++)
833       {
834         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
835         if (p == (const Quantum *) NULL)
836           break;
837         for (x=0; x < (ssize_t) columns; x++)
838         {
839           *q++=(float) (QuantumScale*GetPixelIntensity(image,p));
840           p+=GetPixelChannels(image);
841         }
842       }
843       return;
844     }
845   if (LocaleCompare(map,"RGB") == 0)
846     {
847       for (y=0; y < (ssize_t) rows; y++)
848       {
849         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
850         if (p == (const Quantum *) NULL)
851           break;
852         for (x=0; x < (ssize_t) columns; x++)
853         {
854           *q++=(float) (QuantumScale*GetPixelRed(image,p));
855           *q++=(float) (QuantumScale*GetPixelGreen(image,p));
856           *q++=(float) (QuantumScale*GetPixelBlue(image,p));
857           p+=GetPixelChannels(image);
858         }
859       }
860       return;
861     }
862   if (LocaleCompare(map,"RGBA") == 0)
863     {
864       for (y=0; y < (ssize_t) rows; y++)
865       {
866         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
867         if (p == (const Quantum *) NULL)
868           break;
869         for (x=0; x < (ssize_t) columns; x++)
870         {
871           *q++=(float) (QuantumScale*GetPixelRed(image,p));
872           *q++=(float) (QuantumScale*GetPixelGreen(image,p));
873           *q++=(float) (QuantumScale*GetPixelBlue(image,p));
874           *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
875           p+=GetPixelChannels(image);
876         }
877       }
878       return;
879     }
880   if (LocaleCompare(map,"RGBP") == 0)
881     {
882       for (y=0; y < (ssize_t) rows; y++)
883       {
884         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
885         if (p == (const Quantum *) NULL)
886           break;
887         for (x=0; x < (ssize_t) columns; x++)
888         {
889           *q++=(float) (QuantumScale*GetPixelRed(image,p));
890           *q++=(float) (QuantumScale*GetPixelGreen(image,p));
891           *q++=(float) (QuantumScale*GetPixelBlue(image,p));
892           *q++=0.0;
893           p+=GetPixelChannels(image);
894         }
895       }
896       return;
897     }
898   for (y=0; y < (ssize_t) rows; y++)
899   {
900     p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
901     if (p == (const Quantum *) NULL)
902       break;
903     for (x=0; x < (ssize_t) columns; x++)
904     {
905       register ssize_t
906         i;
907
908       for (i=0; i < (ssize_t) strlen(map); i++)
909       {
910         *q=0;
911         switch (quantum_map[i])
912         {
913           case RedQuantum:
914           case CyanQuantum:
915           {
916             *q=(float) (QuantumScale*GetPixelRed(image,p));
917             break;
918           }
919           case GreenQuantum:
920           case MagentaQuantum:
921           {
922             *q=(float) (QuantumScale*GetPixelGreen(image,p));
923             break;
924           }
925           case BlueQuantum:
926           case YellowQuantum:
927           {
928             *q=(float) (QuantumScale*GetPixelBlue(image,p));
929             break;
930           }
931           case AlphaQuantum:
932           {
933             *q=(float) (QuantumScale*((Quantum) (GetPixelAlpha(image,p))));
934             break;
935           }
936           case OpacityQuantum:
937           {
938             *q=(float) (QuantumScale*GetPixelAlpha(image,p));
939             break;
940           }
941           case BlackQuantum:
942           {
943             if (image->colorspace == CMYKColorspace)
944               *q=(float) (QuantumScale* GetPixelBlack(image,p));
945             break;
946           }
947           case IndexQuantum:
948           {
949             *q=(float) (QuantumScale*GetPixelIntensity(image,p));
950             break;
951           }
952           default:
953             *q=0;
954         }
955         q++;
956       }
957       p+=GetPixelChannels(image);
958     }
959   }
960 }
961
962 static void ExportIntegerPixel(const Image *image,const ssize_t x_offset,
963   const ssize_t y_offset,const size_t columns,const size_t rows,
964   const char *restrict map,const QuantumType *quantum_map,
965   unsigned char *restrict pixels,ExceptionInfo *exception)
966 {
967   register const Quantum
968     *restrict p;
969
970   register ssize_t
971     x;
972
973   register unsigned int
974     *q;
975
976   ssize_t
977     y;
978
979   q=(unsigned int *) pixels;
980   if (LocaleCompare(map,"BGR") == 0)
981     {
982       for (y=0; y < (ssize_t) rows; y++)
983       {
984         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
985         if (p == (const Quantum *) NULL)
986           break;
987         for (x=0; x < (ssize_t) columns; x++)
988         {
989           *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
990           *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
991           *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
992           p+=GetPixelChannels(image);
993         }
994       }
995       return;
996     }
997   if (LocaleCompare(map,"BGRA") == 0)
998     {
999       for (y=0; y < (ssize_t) rows; y++)
1000       {
1001         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1002         if (p == (const Quantum *) NULL)
1003           break;
1004         for (x=0; x < (ssize_t) columns; x++)
1005         {
1006           *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
1007           *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
1008           *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
1009           *q++=(unsigned int) ScaleQuantumToLong(GetPixelAlpha(image,p));
1010           p+=GetPixelChannels(image);
1011         }
1012       }
1013       return;
1014     }
1015   if (LocaleCompare(map,"BGRP") == 0)
1016     {
1017       for (y=0; y < (ssize_t) rows; y++)
1018       {
1019         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1020         if (p == (const Quantum *) NULL)
1021           break;
1022         for (x=0; x < (ssize_t) columns; x++)
1023         {
1024           *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
1025           *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
1026           *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
1027           *q++=0U;
1028           p+=GetPixelChannels(image);
1029         }
1030       }
1031       return;
1032     }
1033   if (LocaleCompare(map,"I") == 0)
1034     {
1035       for (y=0; y < (ssize_t) rows; y++)
1036       {
1037         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1038         if (p == (const Quantum *) NULL)
1039           break;
1040         for (x=0; x < (ssize_t) columns; x++)
1041         {
1042           *q++=(unsigned int) ScaleQuantumToLong(
1043             GetPixelIntensity(image,p));
1044           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         {
1058           *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
1059           *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
1060           *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
1061           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         {
1075           *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
1076           *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
1077           *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
1078           *q++=(unsigned int) ScaleQuantumToLong(GetPixelAlpha(image,p));
1079           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         {
1093           *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
1094           *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
1095           *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
1096           *q++=0U;
1097           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           {
1120             *q=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
1121             break;
1122           }
1123           case GreenQuantum:
1124           case MagentaQuantum:
1125           {
1126             *q=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
1127             break;
1128           }
1129           case BlueQuantum:
1130           case YellowQuantum:
1131           {
1132             *q=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
1133             break;
1134           }
1135           case AlphaQuantum:
1136           {
1137             *q=(unsigned int) ScaleQuantumToLong(GetPixelAlpha(image,p));
1138             break;
1139           }
1140           case OpacityQuantum:
1141           {
1142             *q=(unsigned int) ScaleQuantumToLong(GetPixelAlpha(image,p));
1143             break;
1144           }
1145           case BlackQuantum:
1146           {
1147             if (image->colorspace == CMYKColorspace)
1148               *q=(unsigned int) ScaleQuantumToLong(GetPixelBlack(image,p));
1149             break;
1150           }
1151           case IndexQuantum:
1152           {
1153             *q=(unsigned int) ScaleQuantumToLong(
1154               GetPixelIntensity(image,p));
1155             break;
1156           }
1157           default:
1158             *q=0;
1159         }
1160         q++;
1161       }
1162       p+=GetPixelChannels(image);
1163     }
1164   }
1165 }
1166
1167 static void ExportLongPixel(const Image *image,const ssize_t x_offset,
1168   const ssize_t y_offset,const size_t columns,const size_t rows,
1169   const char *restrict map,const QuantumType *quantum_map,
1170   unsigned char *restrict pixels,ExceptionInfo *exception)
1171 {
1172   register const Quantum
1173     *restrict p;
1174
1175   register ssize_t
1176     x;
1177
1178   register MagickSizeType
1179     *q;
1180
1181   ssize_t
1182     y;
1183
1184   q=(MagickSizeType *) pixels;
1185   if (LocaleCompare(map,"BGR") == 0)
1186     {
1187       for (y=0; y < (ssize_t) rows; y++)
1188       {
1189         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1190         if (p == (const Quantum *) NULL)
1191           break;
1192         for (x=0; x < (ssize_t) columns; x++)
1193         {
1194           *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1195           *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1196           *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1197           p+=GetPixelChannels(image);
1198         }
1199       }
1200       return;
1201     }
1202   if (LocaleCompare(map,"BGRA") == 0)
1203     {
1204       for (y=0; y < (ssize_t) rows; y++)
1205       {
1206         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1207         if (p == (const Quantum *) NULL)
1208           break;
1209         for (x=0; x < (ssize_t) columns; x++)
1210         {
1211           *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1212           *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1213           *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1214           *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
1215           p+=GetPixelChannels(image);
1216         }
1217       }
1218       return;
1219     }
1220   if (LocaleCompare(map,"BGRP") == 0)
1221     {
1222       for (y=0; y < (ssize_t) rows; y++)
1223       {
1224         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1225         if (p == (const Quantum *) NULL)
1226           break;
1227         for (x=0; x < (ssize_t) columns; x++)
1228         {
1229           *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1230           *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1231           *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1232           *q++=0;
1233           p+=GetPixelChannels(image);
1234         }
1235       }
1236       return;
1237     }
1238   if (LocaleCompare(map,"I") == 0)
1239     {
1240       for (y=0; y < (ssize_t) rows; y++)
1241       {
1242         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1243         if (p == (const Quantum *) NULL)
1244           break;
1245         for (x=0; x < (ssize_t) columns; x++)
1246         {
1247           *q++=ScaleQuantumToLongLong(GetPixelIntensity(image,p));
1248           p+=GetPixelChannels(image);
1249         }
1250       }
1251       return;
1252     }
1253   if (LocaleCompare(map,"RGB") == 0)
1254     {
1255       for (y=0; y < (ssize_t) rows; y++)
1256       {
1257         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1258         if (p == (const Quantum *) NULL)
1259           break;
1260         for (x=0; x < (ssize_t) columns; x++)
1261         {
1262           *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1263           *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1264           *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1265           p+=GetPixelChannels(image);
1266         }
1267       }
1268       return;
1269     }
1270   if (LocaleCompare(map,"RGBA") == 0)
1271     {
1272       for (y=0; y < (ssize_t) rows; y++)
1273       {
1274         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1275         if (p == (const Quantum *) NULL)
1276           break;
1277         for (x=0; x < (ssize_t) columns; x++)
1278         {
1279           *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1280           *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1281           *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1282           *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
1283           p+=GetPixelChannels(image);
1284         }
1285       }
1286       return;
1287     }
1288   if (LocaleCompare(map,"RGBP") == 0)
1289     {
1290       for (y=0; y < (ssize_t) rows; y++)
1291       {
1292         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1293         if (p == (const Quantum *) NULL)
1294           break;
1295         for (x=0; x < (ssize_t) columns; x++)
1296         {
1297           *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1298           *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1299           *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1300           *q++=0;
1301           p+=GetPixelChannels(image);
1302         }
1303       }
1304       return;
1305     }
1306   for (y=0; y < (ssize_t) rows; y++)
1307   {
1308     p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1309     if (p == (const Quantum *) NULL)
1310       break;
1311     for (x=0; x < (ssize_t) columns; x++)
1312     {
1313       register ssize_t
1314         i;
1315
1316       for (i=0; i < (ssize_t) strlen(map); i++)
1317       {
1318         *q=0;
1319         switch (quantum_map[i])
1320         {
1321           case RedQuantum:
1322           case CyanQuantum:
1323           {
1324             *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
1325             break;
1326           }
1327           case GreenQuantum:
1328           case MagentaQuantum:
1329           {
1330             *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1331             break;
1332           }
1333           case BlueQuantum:
1334           case YellowQuantum:
1335           {
1336             *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1337             break;
1338           }
1339           case AlphaQuantum:
1340           {
1341             *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
1342             break;
1343           }
1344           case OpacityQuantum:
1345           {
1346             *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
1347             break;
1348           }
1349           case BlackQuantum:
1350           {
1351             if (image->colorspace == CMYKColorspace)
1352               *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
1353             break;
1354           }
1355           case IndexQuantum:
1356           {
1357             *q=ScaleQuantumToLongLong(GetPixelIntensity(image,p));
1358             break;
1359           }
1360           default:
1361             break;
1362         }
1363         q++;
1364       }
1365       p+=GetPixelChannels(image);
1366     }
1367   }
1368 }
1369
1370 static void ExportQuantumPixel(const Image *image,const ssize_t x_offset,
1371   const ssize_t y_offset,const size_t columns,const size_t rows,
1372   const char *restrict map,const QuantumType *quantum_map,
1373   unsigned char *restrict pixels,ExceptionInfo *exception)
1374 {
1375   register const Quantum
1376     *restrict p;
1377
1378   register Quantum
1379     *q;
1380
1381   register ssize_t
1382     x;
1383
1384   ssize_t
1385     y;
1386
1387   q=(Quantum *) pixels;
1388   if (LocaleCompare(map,"BGR") == 0)
1389     {
1390       for (y=0; y < (ssize_t) rows; y++)
1391       {
1392         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1393         if (p == (const Quantum *) NULL)
1394           break;
1395         for (x=0; x < (ssize_t) columns; x++)
1396         {
1397           *q++=GetPixelBlue(image,p);
1398           *q++=GetPixelGreen(image,p);
1399           *q++=GetPixelRed(image,p);
1400           p+=GetPixelChannels(image);
1401         }
1402       }
1403       return;
1404     }
1405   if (LocaleCompare(map,"BGRA") == 0)
1406     {
1407       for (y=0; y < (ssize_t) rows; y++)
1408       {
1409         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1410         if (p == (const Quantum *) NULL)
1411           break;
1412         for (x=0; x < (ssize_t) columns; x++)
1413         {
1414           *q++=GetPixelBlue(image,p);
1415           *q++=GetPixelGreen(image,p);
1416           *q++=GetPixelRed(image,p);
1417           *q++=(Quantum) (GetPixelAlpha(image,p));
1418           p+=GetPixelChannels(image);
1419         }
1420       }
1421       return;
1422     }
1423   if (LocaleCompare(map,"BGRP") == 0)
1424     {
1425       for (y=0; y < (ssize_t) rows; y++)
1426       {
1427         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1428         if (p == (const Quantum *) NULL)
1429           break;
1430         for (x=0; x < (ssize_t) columns; x++)
1431         {
1432           *q++=GetPixelBlue(image,p);
1433           *q++=GetPixelGreen(image,p);
1434           *q++=GetPixelRed(image,p);
1435           *q++=(Quantum) 0;
1436           p+=GetPixelChannels(image);
1437         }
1438       }
1439       return;
1440     }
1441   if (LocaleCompare(map,"I") == 0)
1442     {
1443       for (y=0; y < (ssize_t) rows; y++)
1444       {
1445         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1446         if (p == (const Quantum *) NULL)
1447           break;
1448         for (x=0; x < (ssize_t) columns; x++)
1449         {
1450           *q++=GetPixelIntensity(image,p);
1451           p+=GetPixelChannels(image);
1452         }
1453       }
1454       return;
1455     }
1456   if (LocaleCompare(map,"RGB") == 0)
1457     {
1458       for (y=0; y < (ssize_t) rows; y++)
1459       {
1460         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1461         if (p == (const Quantum *) NULL)
1462           break;
1463         for (x=0; x < (ssize_t) columns; x++)
1464         {
1465           *q++=GetPixelRed(image,p);
1466           *q++=GetPixelGreen(image,p);
1467           *q++=GetPixelBlue(image,p);
1468           p+=GetPixelChannels(image);
1469         }
1470       }
1471       return;
1472     }
1473   if (LocaleCompare(map,"RGBA") == 0)
1474     {
1475       for (y=0; y < (ssize_t) rows; y++)
1476       {
1477         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1478         if (p == (const Quantum *) NULL)
1479           break;
1480         for (x=0; x < (ssize_t) columns; x++)
1481         {
1482           *q++=GetPixelRed(image,p);
1483           *q++=GetPixelGreen(image,p);
1484           *q++=GetPixelBlue(image,p);
1485           *q++=(Quantum) (GetPixelAlpha(image,p));
1486           p+=GetPixelChannels(image);
1487         }
1488       }
1489       return;
1490     }
1491   if (LocaleCompare(map,"RGBP") == 0)
1492     {
1493       for (y=0; y < (ssize_t) rows; y++)
1494       {
1495         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1496         if (p == (const Quantum *) NULL)
1497           break;
1498         for (x=0; x < (ssize_t) columns; x++)
1499         {
1500           *q++=GetPixelRed(image,p);
1501           *q++=GetPixelGreen(image,p);
1502           *q++=GetPixelBlue(image,p);
1503           *q++=(Quantum) 0;
1504           p+=GetPixelChannels(image);
1505         }
1506       }
1507       return;
1508     }
1509   for (y=0; y < (ssize_t) rows; y++)
1510   {
1511     p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1512     if (p == (const Quantum *) NULL)
1513       break;
1514     for (x=0; x < (ssize_t) columns; x++)
1515     {
1516       register ssize_t
1517         i;
1518
1519       for (i=0; i < (ssize_t) strlen(map); i++)
1520       {
1521         *q=(Quantum) 0;
1522         switch (quantum_map[i])
1523         {
1524           case RedQuantum:
1525           case CyanQuantum:
1526           {
1527             *q=GetPixelRed(image,p);
1528             break;
1529           }
1530           case GreenQuantum:
1531           case MagentaQuantum:
1532           {
1533             *q=GetPixelGreen(image,p);
1534             break;
1535           }
1536           case BlueQuantum:
1537           case YellowQuantum:
1538           {
1539             *q=GetPixelBlue(image,p);
1540             break;
1541           }
1542           case AlphaQuantum:
1543           {
1544             *q=GetPixelAlpha(image,p);
1545             break;
1546           }
1547           case OpacityQuantum:
1548           {
1549             *q=GetPixelAlpha(image,p);
1550             break;
1551           }
1552           case BlackQuantum:
1553           {
1554             if (image->colorspace == CMYKColorspace)
1555               *q=GetPixelBlack(image,p);
1556             break;
1557           }
1558           case IndexQuantum:
1559           {
1560             *q=(GetPixelIntensity(image,p));
1561             break;
1562           }
1563           default:
1564           {
1565             *q=(Quantum) 0;
1566             break;
1567           }
1568         }
1569         q++;
1570       }
1571       p+=GetPixelChannels(image);
1572     }
1573   }
1574 }
1575
1576 static void ExportShortPixel(const Image *image,const ssize_t x_offset,
1577   const ssize_t y_offset,const size_t columns,const size_t rows,
1578   const char *restrict map,const QuantumType *quantum_map,
1579   unsigned char *restrict pixels,ExceptionInfo *exception)
1580 {
1581   register const Quantum
1582     *restrict p;
1583
1584   register ssize_t
1585     x;
1586
1587   ssize_t
1588     y;
1589
1590   register unsigned short
1591     *q;
1592
1593   q=(unsigned short *) pixels;
1594   if (LocaleCompare(map,"BGR") == 0)
1595     {
1596       for (y=0; y < (ssize_t) rows; y++)
1597       {
1598         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1599         if (p == (const Quantum *) NULL)
1600           break;
1601         for (x=0; x < (ssize_t) columns; x++)
1602         {
1603           *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1604           *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1605           *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1606           p+=GetPixelChannels(image);
1607         }
1608       }
1609       return;
1610     }
1611   if (LocaleCompare(map,"BGRA") == 0)
1612     {
1613       for (y=0; y < (ssize_t) rows; y++)
1614       {
1615         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1616         if (p == (const Quantum *) NULL)
1617           break;
1618         for (x=0; x < (ssize_t) columns; x++)
1619         {
1620           *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1621           *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1622           *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1623           *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1624           p+=GetPixelChannels(image);
1625         }
1626       }
1627       return;
1628     }
1629   if (LocaleCompare(map,"BGRP") == 0)
1630     {
1631       for (y=0; y < (ssize_t) rows; y++)
1632       {
1633         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1634         if (p == (const Quantum *) NULL)
1635           break;
1636         for (x=0; x < (ssize_t) columns; x++)
1637         {
1638           *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1639           *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1640           *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1641           *q++=0;
1642           p+=GetPixelChannels(image);
1643         }
1644       }
1645       return;
1646     }
1647   if (LocaleCompare(map,"I") == 0)
1648     {
1649       for (y=0; y < (ssize_t) rows; y++)
1650       {
1651         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1652         if (p == (const Quantum *) NULL)
1653           break;
1654         for (x=0; x < (ssize_t) columns; x++)
1655         {
1656           *q++=ScaleQuantumToShort(GetPixelIntensity(image,p));
1657           p+=GetPixelChannels(image);
1658         }
1659       }
1660       return;
1661     }
1662   if (LocaleCompare(map,"RGB") == 0)
1663     {
1664       for (y=0; y < (ssize_t) rows; y++)
1665       {
1666         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1667         if (p == (const Quantum *) NULL)
1668           break;
1669         for (x=0; x < (ssize_t) columns; x++)
1670         {
1671           *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1672           *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1673           *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1674           p+=GetPixelChannels(image);
1675         }
1676       }
1677       return;
1678     }
1679   if (LocaleCompare(map,"RGBA") == 0)
1680     {
1681       for (y=0; y < (ssize_t) rows; y++)
1682       {
1683         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1684         if (p == (const Quantum *) NULL)
1685           break;
1686         for (x=0; x < (ssize_t) columns; x++)
1687         {
1688           *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1689           *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1690           *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1691           *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1692           p+=GetPixelChannels(image);
1693         }
1694       }
1695       return;
1696     }
1697   if (LocaleCompare(map,"RGBP") == 0)
1698     {
1699       for (y=0; y < (ssize_t) rows; y++)
1700       {
1701         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1702         if (p == (const Quantum *) NULL)
1703           break;
1704         for (x=0; x < (ssize_t) columns; x++)
1705         {
1706           *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1707           *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1708           *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1709           *q++=0;
1710           p+=GetPixelChannels(image);
1711         }
1712       }
1713       return;
1714     }
1715   for (y=0; y < (ssize_t) rows; y++)
1716   {
1717     p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1718     if (p == (const Quantum *) NULL)
1719       break;
1720     for (x=0; x < (ssize_t) columns; x++)
1721     {
1722       register ssize_t
1723         i;
1724
1725       for (i=0; i < (ssize_t) strlen(map); i++)
1726       {
1727         *q=0;
1728         switch (quantum_map[i])
1729         {
1730           case RedQuantum:
1731           case CyanQuantum:
1732           {
1733             *q=ScaleQuantumToShort(GetPixelRed(image,p));
1734             break;
1735           }
1736           case GreenQuantum:
1737           case MagentaQuantum:
1738           {
1739             *q=ScaleQuantumToShort(GetPixelGreen(image,p));
1740             break;
1741           }
1742           case BlueQuantum:
1743           case YellowQuantum:
1744           {
1745             *q=ScaleQuantumToShort(GetPixelBlue(image,p));
1746             break;
1747           }
1748           case AlphaQuantum:
1749           {
1750             *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1751             break;
1752           }
1753           case OpacityQuantum:
1754           {
1755             *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1756             break;
1757           }
1758           case BlackQuantum:
1759           {
1760             if (image->colorspace == CMYKColorspace)
1761               *q=ScaleQuantumToShort(GetPixelBlack(image,p));
1762             break;
1763           }
1764           case IndexQuantum:
1765           {
1766             *q=ScaleQuantumToShort(GetPixelIntensity(image,p));
1767             break;
1768           }
1769           default:
1770             break;
1771         }
1772         q++;
1773       }
1774       p+=GetPixelChannels(image);
1775     }
1776   }
1777 }
1778
1779 MagickExport MagickBooleanType ExportImagePixels(const Image *image,
1780   const ssize_t x_offset,const ssize_t y_offset,const size_t columns,
1781   const size_t rows,const char *map,const StorageType type,void *pixels,
1782   ExceptionInfo *exception)
1783 {
1784   QuantumType
1785     *quantum_map;
1786
1787   register ssize_t
1788     i;
1789
1790   assert(image != (Image *) NULL);
1791   assert(image->signature == MagickSignature);
1792   if (image->debug != MagickFalse)
1793     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1794   quantum_map=(QuantumType *) AcquireQuantumMemory(strlen(map),
1795     sizeof(*quantum_map));
1796   if (quantum_map == (QuantumType *) NULL)
1797     {
1798       (void) ThrowMagickException(exception,GetMagickModule(),
1799         ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1800       return(MagickFalse);
1801     }
1802   for (i=0; i < (ssize_t) strlen(map); i++)
1803   {
1804     switch (map[i])
1805     {
1806       case 'A':
1807       case 'a':
1808       {
1809         quantum_map[i]=AlphaQuantum;
1810         break;
1811       }
1812       case 'B':
1813       case 'b':
1814       {
1815         quantum_map[i]=BlueQuantum;
1816         break;
1817       }
1818       case 'C':
1819       case 'c':
1820       {
1821         quantum_map[i]=CyanQuantum;
1822         if (image->colorspace == CMYKColorspace)
1823           break;
1824         quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1825         (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1826           "ColorSeparatedImageRequired","`%s'",map);
1827         return(MagickFalse);
1828       }
1829       case 'g':
1830       case 'G':
1831       {
1832         quantum_map[i]=GreenQuantum;
1833         break;
1834       }
1835       case 'I':
1836       case 'i':
1837       {
1838         quantum_map[i]=IndexQuantum;
1839         break;
1840       }
1841       case 'K':
1842       case 'k':
1843       {
1844         quantum_map[i]=BlackQuantum;
1845         if (image->colorspace == CMYKColorspace)
1846           break;
1847         quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1848         (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1849           "ColorSeparatedImageRequired","`%s'",map);
1850         return(MagickFalse);
1851       }
1852       case 'M':
1853       case 'm':
1854       {
1855         quantum_map[i]=MagentaQuantum;
1856         if (image->colorspace == CMYKColorspace)
1857           break;
1858         quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1859         (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1860           "ColorSeparatedImageRequired","`%s'",map);
1861         return(MagickFalse);
1862       }
1863       case 'o':
1864       case 'O':
1865       {
1866         quantum_map[i]=OpacityQuantum;
1867         break;
1868       }
1869       case 'P':
1870       case 'p':
1871       {
1872         quantum_map[i]=UndefinedQuantum;
1873         break;
1874       }
1875       case 'R':
1876       case 'r':
1877       {
1878         quantum_map[i]=RedQuantum;
1879         break;
1880       }
1881       case 'Y':
1882       case 'y':
1883       {
1884         quantum_map[i]=YellowQuantum;
1885         if (image->colorspace == CMYKColorspace)
1886           break;
1887         quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1888         (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
1889           "ColorSeparatedImageRequired","`%s'",map);
1890         return(MagickFalse);
1891       }
1892       default:
1893       {
1894         quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1895         (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
1896           "UnrecognizedPixelMap","`%s'",map);
1897         return(MagickFalse);
1898       }
1899     }
1900   }
1901   switch (type)
1902   {
1903     case CharPixel:
1904     {
1905       ExportCharPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
1906         pixels,exception);
1907       break;
1908     }
1909     case DoublePixel:
1910     {
1911       ExportDoublePixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
1912         pixels,exception);
1913       break;
1914     }
1915     case FloatPixel:
1916     {
1917       ExportFloatPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
1918         pixels,exception);
1919       break;
1920     }
1921     case IntegerPixel:
1922     {
1923       ExportIntegerPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
1924         pixels,exception);
1925       break;
1926     }
1927     case LongPixel:
1928     {
1929       ExportLongPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
1930         pixels,exception);
1931       break;
1932     }
1933     case QuantumPixel:
1934     {
1935       ExportQuantumPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
1936         pixels,exception);
1937       break;
1938     }
1939     case ShortPixel:
1940     {
1941       ExportShortPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
1942         pixels,exception);
1943       break;
1944     }
1945     default:
1946     {
1947       quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1948       (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
1949         "UnrecognizedPixelMap","`%s'",map);
1950       break;
1951     }
1952   }
1953   quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1954   return(MagickTrue);
1955 }
1956 \f
1957 /*
1958 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1959 %                                                                             %
1960 %                                                                             %
1961 %                                                                             %
1962 %   G e t P i x e l I n f o                                                   %
1963 %                                                                             %
1964 %                                                                             %
1965 %                                                                             %
1966 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1967 %
1968 %  GetPixelInfo() initializes the PixelInfo structure.
1969 %
1970 %  The format of the GetPixelInfo method is:
1971 %
1972 %      GetPixelInfo(const Image *image,PixelInfo *pixel)
1973 %
1974 %  A description of each parameter follows:
1975 %
1976 %    o image: the image.
1977 %
1978 %    o pixel: Specifies a pointer to a PixelInfo structure.
1979 %
1980 */
1981 MagickExport void GetPixelInfo(const Image *image,PixelInfo *pixel)
1982 {
1983   pixel->storage_class=DirectClass;
1984   pixel->colorspace=RGBColorspace;
1985   pixel->matte=MagickFalse;
1986   pixel->fuzz=0.0;
1987   pixel->depth=MAGICKCORE_QUANTUM_DEPTH;
1988   pixel->red=0.0;
1989   pixel->green=0.0;
1990   pixel->blue=0.0;
1991   pixel->black=0.0;
1992   pixel->alpha=(MagickRealType) OpaqueAlpha;
1993   pixel->index=0.0;
1994   if (image == (const Image *) NULL)
1995     return;
1996   pixel->storage_class=image->storage_class;
1997   pixel->colorspace=image->colorspace;
1998   pixel->matte=image->matte;
1999   pixel->depth=image->depth;
2000   pixel->fuzz=image->fuzz;
2001 }
2002 \f
2003 /*
2004 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2005 %                                                                             %
2006 %                                                                             %
2007 %                                                                             %
2008 %   I m p o r t I m a g e P i x e l s                                         %
2009 %                                                                             %
2010 %                                                                             %
2011 %                                                                             %
2012 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2013 %
2014 %  ImportImagePixels() accepts pixel data and stores in the image at the
2015 %  location you specify.  The method returns MagickTrue on success otherwise
2016 %  MagickFalse if an error is encountered.  The pixel data can be either char,
2017 %  short int, int, ssize_t, float, or double in the order specified by map.
2018 %
2019 %  Suppose your want to upload the first scanline of a 640x480 image from
2020 %  character data in red-green-blue order:
2021 %
2022 %      ImportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels);
2023 %
2024 %  The format of the ImportImagePixels method is:
2025 %
2026 %      MagickBooleanType ImportImagePixels(Image *image,const ssize_t x_offset,
2027 %        const ssize_t y_offset,const size_t columns,
2028 %        const size_t rows,const char *map,const StorageType type,
2029 %        const void *pixels,ExceptionInfo *exception)
2030 %
2031 %  A description of each parameter follows:
2032 %
2033 %    o image: the image.
2034 %
2035 %    o x_offset,y_offset,columns,rows:  These values define the perimeter
2036 %      of a region of pixels you want to define.
2037 %
2038 %    o map:  This string reflects the expected ordering of the pixel array.
2039 %      It can be any combination or order of R = red, G = green, B = blue,
2040 %      A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
2041 %      Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
2042 %      P = pad.
2043 %
2044 %    o type: Define the data type of the pixels.  Float and double types are
2045 %      normalized to [0..1] otherwise [0..QuantumRange].  Choose from these
2046 %      types: CharPixel, ShortPixel, IntegerPixel, LongPixel, FloatPixel, or
2047 %      DoublePixel.
2048 %
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 %
2053 %    o exception: return any errors or warnings in this structure.
2054 %
2055 */
2056
2057 static void ImportCharPixel(Image *image,const ssize_t x_offset,
2058   const ssize_t y_offset,const size_t columns,const size_t rows,
2059   const char *restrict map,const QuantumType *quantum_map,
2060   const unsigned char *restrict pixels,ExceptionInfo *exception)
2061 {
2062   register const unsigned char
2063     *restrict p;
2064
2065   register Quantum
2066     *q;
2067
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
2314 static void ImportDoublePixel(Image *image,const ssize_t x_offset,
2315   const ssize_t y_offset,const size_t columns,const size_t rows,
2316   const char *restrict map,const QuantumType *quantum_map,
2317   const unsigned char *restrict pixels,ExceptionInfo *exception)
2318 {
2319   register const double
2320     *restrict p;
2321
2322   register Quantum
2323     *q;
2324
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
2579 static void ImportFloatPixel(Image *image,const ssize_t x_offset,
2580   const ssize_t y_offset,const size_t columns,const size_t rows,
2581   const char *restrict map,const QuantumType *quantum_map,
2582   const unsigned char *restrict pixels,ExceptionInfo *exception)
2583 {
2584   register const float
2585     *restrict p;
2586
2587   register Quantum
2588     *q;
2589
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
2844 static void ImportIntegerPixel(Image *image,const ssize_t x_offset,
2845   const ssize_t y_offset,const size_t columns,const size_t rows,
2846   const char *restrict map,const QuantumType *quantum_map,
2847   const unsigned char *restrict pixels,ExceptionInfo *exception)
2848 {
2849   register const unsigned int
2850     *restrict p;
2851
2852   register Quantum
2853     *q;
2854
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
3061 static void ImportLongPixel(Image *image,const ssize_t x_offset,
3062   const ssize_t y_offset,const size_t columns,const size_t rows,
3063   const char *restrict map,const QuantumType *quantum_map,
3064   const unsigned char *restrict pixels,ExceptionInfo *exception)
3065 {
3066   register const MagickSizeType
3067     *restrict p;
3068
3069   register Quantum
3070     *q;
3071
3072   register ssize_t
3073     x;
3074
3075   ssize_t
3076     y;
3077
3078   p=(const MagickSizeType *) pixels;
3079   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         {
3088           SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3089           SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3090           SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3091           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         {
3107           SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3108           SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3109           SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3110           SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
3111           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         {
3127           SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3128           SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3129           SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3130           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         {
3147           SetPixelGray(image,ScaleLongLongToQuantum(*p++),q);
3148           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         {
3164           SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3165           SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3166           SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3167           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         {
3183           SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3184           SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3185           SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3186           SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
3187           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         {
3203           SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3204           SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3205           SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3206           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           {
3231             SetPixelRed(image,ScaleLongLongToQuantum(*p),q);
3232             break;
3233           }
3234           case GreenQuantum:
3235           case MagentaQuantum:
3236           {
3237             SetPixelGreen(image,ScaleLongLongToQuantum(*p),q);
3238             break;
3239           }
3240           case BlueQuantum:
3241           case YellowQuantum:
3242           {
3243             SetPixelBlue(image,ScaleLongLongToQuantum(*p),q);
3244             break;
3245           }
3246           case AlphaQuantum:
3247           {
3248             SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
3249             break;
3250           }
3251           case OpacityQuantum:
3252           {
3253             SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
3254             break;
3255           }
3256           case BlackQuantum:
3257           {
3258             SetPixelBlack(image,ScaleLongLongToQuantum(*p),q);
3259             break;
3260           }
3261           case IndexQuantum:
3262           {
3263             SetPixelGray(image,ScaleLongLongToQuantum(*p),q);
3264             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
3278 static void ImportQuantumPixel(Image *image,const ssize_t x_offset,
3279   const ssize_t y_offset,const size_t columns,const size_t rows,
3280   const char *restrict map,const QuantumType *quantum_map,
3281   const unsigned char *restrict pixels,ExceptionInfo *exception)
3282 {
3283   register const Quantum
3284     *restrict p;
3285
3286   register Quantum
3287     *q;
3288
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
3495 static void ImportShortPixel(Image *image,const ssize_t x_offset,
3496   const ssize_t y_offset,const size_t columns,const size_t rows,
3497   const char *restrict map,const QuantumType *quantum_map,
3498   const unsigned char *restrict pixels,ExceptionInfo *exception)
3499 {
3500   register const unsigned short
3501     *restrict p;
3502
3503   register Quantum
3504     *q;
3505
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
3712 MagickExport 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,
3715   const void *pixels,ExceptionInfo *exception)
3716 {
3717   QuantumType
3718     *quantum_map;
3719
3720   register ssize_t
3721     i;
3722
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);
3730   quantum_map=(QuantumType *) AcquireQuantumMemory(strlen(map),
3731     sizeof(*quantum_map));
3732   if (quantum_map == (QuantumType *) NULL)
3733     ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
3734       image->filename);
3735   for (i=0; i < (ssize_t) strlen(map); i++)
3736   {
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;
3756         (void) SetImageColorspace(image,CMYKColorspace,exception);
3757         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;
3769         (void) SetImageColorspace(image,CMYKColorspace,exception);
3770         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;
3782         (void) SetImageColorspace(image,CMYKColorspace,exception);
3783         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;
3808         (void) SetImageColorspace(image,CMYKColorspace,exception);
3809         break;
3810       }
3811       default:
3812       {
3813         quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
3814         (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
3815           "UnrecognizedPixelMap","`%s'",map);
3816         return(MagickFalse);
3817       }
3818     }
3819   }
3820   if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
3821     return(MagickFalse);
3822   /*
3823     Transfer the pixels from the pixel data to the image.
3824   */
3825   switch (type)
3826   {
3827     case CharPixel:
3828     {
3829       ImportCharPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
3830         pixels,exception);
3831       break;
3832     }
3833     case DoublePixel:
3834     {
3835       ImportDoublePixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
3836         pixels,exception);
3837       break;
3838     }
3839     case FloatPixel:
3840     {
3841       ImportFloatPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
3842         pixels,exception);
3843       break;
3844     }
3845     case IntegerPixel:
3846     {
3847       ImportIntegerPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
3848         pixels,exception);
3849       break;
3850     }
3851     case LongPixel:
3852     {
3853       ImportLongPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
3854         pixels,exception);
3855       break;
3856     }
3857     case QuantumPixel:
3858     {
3859       ImportQuantumPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
3860         pixels,exception);
3861       break;
3862     }
3863     case ShortPixel:
3864     {
3865       ImportShortPixel(image,x_offset,y_offset,columns,rows,map,quantum_map,
3866         pixels,exception);
3867       break;
3868     }
3869     default:
3870     {
3871       quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
3872       (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
3873         "UnrecognizedPixelMap","`%s'",map);
3874       break;
3875     }
3876   }
3877   quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
3878   return(MagickTrue);
3879 }
3880 \f
3881 /*
3882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3883 %                                                                             %
3884 %                                                                             %
3885 %                                                                             %
3886 +   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 */
3903 MagickExport void InitializePixelChannelMap(Image *image)
3904 {
3905   PixelTrait
3906     trait;
3907
3908   register ssize_t
3909     i;
3910
3911   ssize_t
3912     n;
3913
3914   assert(image != (Image *) NULL);
3915   assert(image->signature == MagickSignature);
3916   (void) ResetMagickMemory(image->channel_map,0,MaxPixelChannels*
3917     sizeof(*image->channel_map));
3918   trait=UpdatePixelTrait;
3919   if (image->matte != MagickFalse)
3920     trait=(PixelTrait) (trait | BlendPixelTrait);
3921   n=0;
3922   if (image->colorspace == GRAYColorspace)
3923     {
3924       SetPixelChannelMap(image,BluePixelChannel,trait,n);
3925       SetPixelChannelMap(image,GreenPixelChannel,trait,n);
3926       SetPixelChannelMap(image,RedPixelChannel,trait,n++);
3927     }
3928   else
3929     {
3930       SetPixelChannelMap(image,RedPixelChannel,trait,n++);
3931       SetPixelChannelMap(image,GreenPixelChannel,trait,n++);
3932       SetPixelChannelMap(image,BluePixelChannel,trait,n++);
3933     }
3934   if (image->colorspace == CMYKColorspace)
3935     SetPixelChannelMap(image,BlackPixelChannel,trait,n++);
3936   if (image->matte != MagickFalse)
3937     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++)
3942     SetPixelChannelMap(image,(PixelChannel) (MetaPixelChannel+i),CopyPixelTrait,
3943       n++);
3944   image->number_channels=(size_t) n;
3945   if (image->debug != MagickFalse)
3946     LogPixelChannels(image);
3947   (void) SetPixelChannelMask(image,image->channel_mask);
3948 }
3949 \f
3950 /*
3951 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3952 %                                                                             %
3953 %                                                                             %
3954 %                                                                             %
3955 %   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 %
3961 %  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.
3964 %
3965 %  The format of the InterpolatePixelChannel method is:
3966 %
3967 %      MagickBooleanType InterpolatePixelChannel(const Image *image,
3968 %        const CacheView *image_view,const PixelChannel channel,
3969 %        const PixelInterpolateMethod method,const double x,const double y,
3970 %        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 */
3989
3990 static inline double MagickMax(const MagickRealType x,const MagickRealType y)
3991 {
3992   if (x > y)
3993     return(x);
3994   return(y);
3995 }
3996
3997 static 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
4014 static 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
4020 static 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
4027 MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
4028   const CacheView *image_view,const PixelChannel channel,
4029   const PixelInterpolateMethod method,const double x,const double y,
4030   double *pixel,ExceptionInfo *exception)
4031 {
4032   MagickBooleanType
4033     status;
4034
4035   MagickRealType
4036     alpha[16],
4037     gamma,
4038     pixels[16];
4039
4040   PixelTrait
4041     traits;
4042
4043   register const Quantum
4044     *p;
4045
4046   register ssize_t
4047     i;
4048
4049   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;
4058   *pixel=0.0;
4059   traits=GetPixelChannelMapTraits(image,channel);
4060   x_offset=(ssize_t) floor(x);
4061   y_offset=(ssize_t) floor(y);
4062   switch (method == UndefinedInterpolatePixel ? image->interpolate : method)
4063   {
4064     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         }
4073       if ((traits & BlendPixelTrait) == 0)
4074         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         }
4109       if ((traits & BlendPixelTrait) == 0)
4110         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:
4142     default:
4143     {
4144       PointInfo
4145         delta,
4146         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         }
4154       if ((traits & BlendPixelTrait) == 0)
4155         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
4210         *pixel=(double) GetPixelChannel(image,channel,p);
4211       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         }
4223       *pixel=(double) GetPixelChannel(image,channel,p);
4224       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         }
4235       *pixel=(double) GetPixelChannel(image,channel,p);
4236       break;
4237     }
4238     case MeshInterpolatePixel:
4239     {
4240       PointInfo
4241         delta,
4242         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         }
4250       if ((traits & BlendPixelTrait) == 0)
4251         for (i=0; i < 4; i++)
4252         {
4253           alpha[i]=1.0;
4254           pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4255         }
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         }
4263       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));
4267       luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
4268         GetPixelLuminance(image,p+2*GetPixelChannels(image));
4269       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         }
4325       break;
4326     }
4327     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         }
4347       if ((traits & BlendPixelTrait) == 0)
4348         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     }
4376   }
4377   return(status);
4378 }
4379 \f
4380 /*
4381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4382 %                                                                             %
4383 %                                                                             %
4384 %                                                                             %
4385 %   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 */
4419 MagickExport 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
4475         channel=GetPixelChannelMapChannel(source,i);
4476         traits=GetPixelChannelMapTraits(source,channel);
4477         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];
4483         sum=0.0;
4484         if ((traits & BlendPixelTrait) == 0)
4485           {
4486             for (j=0; j < 16; j++)
4487               sum+=0.0625*pixels[j];
4488             SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
4489             continue;
4490           }
4491         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         }
4499         SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
4500       }
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
4524         channel=GetPixelChannelMapChannel(source,i);
4525         traits=GetPixelChannelMapTraits(source,channel);
4526         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];
4558         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);
4560       }
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
4578         channel=GetPixelChannelMapChannel(source,i);
4579         traits=GetPixelChannelMapTraits(source,channel);
4580         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;
4588         pixels[0]=(MagickRealType) p[i];
4589         pixels[1]=(MagickRealType) p[GetPixelChannels(source)+i];
4590         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);
4596             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);
4599             continue;
4600           }
4601         alpha[0]=QuantumScale*GetPixelAlpha(source,p);
4602         alpha[1]=QuantumScale*GetPixelAlpha(source,p+GetPixelChannels(source));
4603         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);
4614         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);
4617       }
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
4634         channel=GetPixelChannelMapChannel(source,i);
4635         traits=GetPixelChannelMapTraits(source,channel);
4636         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
4660           {
4661             SetPixelChannel(destination,channel,p[i],pixel);
4662           }
4663         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       {
4678         channel=GetPixelChannelMapChannel(source,i);
4679         traits=GetPixelChannelMapTraits(source,channel);
4680         destination_traits=GetPixelChannelMapTraits(destination,channel);
4681         if ((traits == UndefinedPixelTrait) ||
4682             (destination_traits == UndefinedPixelTrait))
4683           continue;
4684         SetPixelChannel(destination,channel,p[i],pixel);
4685       }
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       {
4699         channel=GetPixelChannelMapChannel(source,i);
4700         traits=GetPixelChannelMapTraits(source,channel);
4701         destination_traits=GetPixelChannelMapTraits(destination,channel);
4702         if ((traits == UndefinedPixelTrait) ||
4703             (destination_traits == UndefinedPixelTrait))
4704           continue;
4705         SetPixelChannel(destination,channel,p[i],pixel);
4706       }
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
4723         channel=GetPixelChannelMapChannel(source,i);
4724         traits=GetPixelChannelMapTraits(source,channel);
4725         destination_traits=GetPixelChannelMapTraits(destination,channel);
4726         if ((traits == UndefinedPixelTrait) ||
4727             (destination_traits == UndefinedPixelTrait))
4728           continue;
4729         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);
4769                 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4770                   MeshInterpolate(&delta,pixels[2],pixels[3],pixels[0])),pixel);
4771               }
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);
4780                 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4781                   MeshInterpolate(&delta,pixels[1],pixels[0],pixels[3])),pixel);
4782               }
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);
4796                 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4797                   MeshInterpolate(&delta,pixels[0],pixels[1],pixels[2])),pixel);
4798               }
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);
4808                 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
4809                   MeshInterpolate(&delta,pixels[3],pixels[2],pixels[1])),pixel);
4810               }
4811           }
4812       }
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
4843         channel=GetPixelChannelMapChannel(source,i);
4844         traits=GetPixelChannelMapTraits(source,channel);
4845         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         }
4878         SetPixelChannel(destination,channel,p[i],pixel);
4879       }
4880       break;
4881     }
4882   }
4883   return(status);
4884 }
4885 \f
4886 /*
4887 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4888 %                                                                             %
4889 %                                                                             %
4890 %                                                                             %
4891 %   I n t e r p o l a t e P i x e l I n f o                                   %
4892 %                                                                             %
4893 %                                                                             %
4894 %                                                                             %
4895 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4896 %
4897 %  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.
4900 %
4901 %  The format of the InterpolatePixelInfo method is:
4902 %
4903 %      MagickBooleanType InterpolatePixelInfo(const Image *image,
4904 %        const CacheView *image_view,const PixelInterpolateMethod method,
4905 %        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
4924 static 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
4949 static 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
4990 MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
4991   const CacheView *image_view,const PixelInterpolateMethod method,
4992   const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception)
4993 {
4994   MagickBooleanType
4995     status;
4996
4997   MagickRealType
4998     alpha[16],
4999     gamma;
5000
5001   PixelInfo
5002     pixels[16];
5003
5004   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         }
5031       AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
5032       AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
5033       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+
5042         10);
5043       AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
5044         11);
5045       AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
5046         12);
5047       AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
5048         13);
5049       AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
5050         14);
5051       AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
5052         15);
5053       pixel->red=0.0;
5054       pixel->green=0.0;
5055       pixel->blue=0.0;
5056       pixel->black=0.0;
5057       pixel->alpha=0.0;
5058       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;
5064         if (image->colorspace == CMYKColorspace)
5065           pixel->black+=gamma*0.0625*pixels[i].black;
5066         pixel->alpha+=0.0625*pixels[i].alpha;
5067       }
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         }
5085       AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
5086       AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
5087       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+
5096         10);
5097       AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
5098         11);
5099       AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
5100         12);
5101       AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
5102         13);
5103       AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
5104         14);
5105       AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
5106         15);
5107       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         }
5127       AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
5128       AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
5129       AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5130       AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5131       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));
5146       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));
5150       gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
5151       gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
5152       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));
5155       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)
5187         GetPixelInfoPixel(image,p,pixel);
5188       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         }
5200       GetPixelInfoPixel(image,p,pixel);
5201       break;
5202     }
5203     case MeshInterpolatePixel:
5204     {
5205       PointInfo
5206         delta,
5207         luminance;
5208
5209       p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5210       if (p == (const Quantum *) NULL)
5211         {
5212           status=MagickFalse;
5213           break;
5214         }
5215       delta.x=x-x_offset;
5216       delta.y=y-y_offset;
5217       luminance.x=GetPixelLuminance(image,p)-(double)
5218         GetPixelLuminance(image,p+3*GetPixelChannels(image));
5219       luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
5220         GetPixelLuminance(image,p+2*GetPixelChannels(image));
5221       AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
5222       AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
5223       AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5224       AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5225       if (fabs(luminance.x) < fabs(luminance.y))
5226         {
5227           /*
5228             Diagonal 0-3 NW-SE.
5229           */
5230           if (delta.x <= delta.y)
5231             {
5232               /*
5233                 Bottom-left triangle (pixel: 2, diagonal: 0-3).
5234               */
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);
5244               if (image->colorspace == CMYKColorspace)
5245                 pixel->black=gamma*MeshInterpolate(&delta,pixels[2].black,
5246                   pixels[3].black,pixels[0].black);
5247               gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5248               pixel->alpha=gamma*MeshInterpolate(&delta,pixels[2].alpha,
5249                 pixels[3].alpha,pixels[0].alpha);
5250             }
5251           else
5252             {
5253               /*
5254                 Top-right triangle (pixel:1 , diagonal: 0-3).
5255               */
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);
5265               if (image->colorspace == CMYKColorspace)
5266                 pixel->black=gamma*MeshInterpolate(&delta,pixels[1].black,
5267                   pixels[0].black,pixels[3].black);
5268               gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5269               pixel->alpha=gamma*MeshInterpolate(&delta,pixels[1].alpha,
5270                 pixels[0].alpha,pixels[3].alpha);
5271             }
5272         }
5273       else
5274         {
5275           /*
5276             Diagonal 1-2 NE-SW.
5277           */
5278           if (delta.x <= (1.0-delta.y))
5279             {
5280               /*
5281                 Top-left triangle (pixel: 0, diagonal: 1-2).
5282               */
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);
5291               if (image->colorspace == CMYKColorspace)
5292                 pixel->black=gamma*MeshInterpolate(&delta,pixels[0].black,
5293                   pixels[1].black,pixels[2].black);
5294               gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5295               pixel->alpha=gamma*MeshInterpolate(&delta,pixels[0].alpha,
5296                 pixels[1].alpha,pixels[2].alpha);
5297             }
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);
5313               if (image->colorspace == CMYKColorspace)
5314                 pixel->black=gamma*MeshInterpolate(&delta,pixels[3].black,
5315                   pixels[2].black,pixels[1].black);
5316               gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5317               pixel->alpha=gamma*MeshInterpolate(&delta,pixels[3].alpha,
5318                 pixels[2].alpha,pixels[1].alpha);
5319             }
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         }
5332       GetPixelInfoPixel(image,p,pixel);
5333       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         }
5355       AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
5356       AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
5357       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+
5366         10);
5367       AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
5368         11);
5369       AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
5370         12);
5371       AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
5372         13);
5373       AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
5374         14);
5375       AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
5376         15);
5377       pixel->red=0.0;
5378       pixel->green=0.0;
5379       pixel->blue=0.0;
5380       pixel->black=0.0;
5381       pixel->alpha=0.0;
5382       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 \f
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 %
5424 %      void IsFuzzyEquivalencePixel(const Image *source,const Quantum *p,
5425 %        const Image *destination,const Quantum *q)
5426 %
5427 %  A description of each parameter follows:
5428 %
5429 %    o source: the source image.
5430 %
5431 %    o p: Pixel p.
5432 %
5433 %    o destination: the destination image.
5434 %
5435 %    o q: Pixel q.
5436 %
5437 */
5438 MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source,
5439   const Quantum *p,const Image *destination,const Quantum *q)
5440 {
5441   MagickRealType
5442     fuzz,
5443     pixel;
5444
5445   register MagickRealType
5446     distance,
5447     scale;
5448
5449   fuzz=MagickMax(source->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(
5450     destination->fuzz,(MagickRealType) MagickSQ1_2);
5451   scale=1.0;
5452   distance=0.0;
5453   if (source->matte != MagickFalse)
5454     {
5455       /*
5456         Transparencies are involved - set alpha distance
5457       */
5458       pixel=GetPixelAlpha(source,p)-(MagickRealType)
5459         GetPixelAlpha(destination,q);
5460       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       */
5467       scale=QuantumScale*GetPixelAlpha(source,p);
5468       scale*=QuantumScale*GetPixelAlpha(destination,q);
5469       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;
5477   pixel=GetPixelRed(source,p)-(MagickRealType) GetPixelRed(destination,q);
5478   if ((source->colorspace == HSLColorspace) ||
5479       (source->colorspace == HSBColorspace) ||
5480       (source->colorspace == HWBColorspace))
5481     {
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);
5493   pixel=GetPixelGreen(source,p)-(MagickRealType) GetPixelGreen(destination,q);
5494   distance+=scale*pixel*pixel;
5495   if (distance > fuzz)
5496     return(MagickFalse);
5497   pixel=GetPixelBlue(source,p)-(MagickRealType) GetPixelBlue(destination,q);
5498   distance+=scale*pixel*pixel;
5499   if (distance > fuzz)
5500     return(MagickFalse);
5501   return(MagickTrue);
5502 }
5503 \f
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 %
5519 %  This implements the equivalent of:
5520 %    fuzz < sqrt(color_distance^2 * u.a*v.a  + alpha_distance^2)
5521 %
5522 %  Which produces a multi-dimensional cone for that colorspace along the
5523 %  transparency vector.
5524 %
5525 %  For example for an RGB:
5526 %    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 */
5548 MagickExport 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)
5562     fuzz=MagickMax(q->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(q->fuzz,
5563       (MagickRealType) MagickSQ1_2);
5564   else if (q->fuzz == 0.0)
5565     fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(p->fuzz,
5566       (MagickRealType) MagickSQ1_2);
5567   else
5568     fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(q->fuzz,
5569       (MagickRealType) MagickSQ1_2);
5570   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.
5584         If one color is transparent, distance has no color component.
5585       */
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     {
5614       /*
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.
5618       */
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 \f
5637 /*
5638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5639 %                                                                             %
5640 %                                                                             %
5641 %                                                                             %
5642 %   S e t P i x e l C h a n n e l M a p M a s k                               %
5643 %                                                                             %
5644 %                                                                             %
5645 %                                                                             %
5646 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5647 %
5648 %  SetPixelChannelMapMask() sets the pixel channel map from the specified
5649 %  channel mask.
5650 %
5651 %  The format of the SetPixelChannelMapMask method is:
5652 %
5653 %      void SetPixelChannelMapMask(Image *image,const ChannelType channel_mask)
5654 %
5655 %  A description of each parameter follows:
5656 %
5657 %    o image: the image.
5658 %
5659 %    o mask: the channel mask.
5660 %
5661 */
5662 MagickExport void SetPixelChannelMapMask(Image *image,
5663   const ChannelType channel_mask)
5664 {
5665 #define GetChannelBit(mask,bit)  (((size_t) (mask) >> (size_t) (bit)) & 0x01)
5666
5667   register ssize_t
5668     i;
5669
5670   image->channel_mask=channel_mask;
5671   for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
5672   {
5673     PixelChannel
5674       channel;
5675
5676     channel=GetPixelChannelMapChannel(image,i);
5677     SetPixelChannelMapTraits(image,channel,
5678       GetChannelBit(channel_mask,channel) == 0 ? CopyPixelTrait :
5679       image->matte == MagickFalse || (channel == AlphaPixelChannel) ?
5680       UpdatePixelTrait : (PixelTrait) (UpdatePixelTrait | BlendPixelTrait));
5681   }
5682   if (image->storage_class == PseudoClass)
5683     SetPixelChannelMapTraits(image,IndexPixelChannel,CopyPixelTrait);
5684   if (image->debug != MagickFalse)
5685     LogPixelChannels(image);
5686 }
5687 \f
5688 /*
5689 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5690 %                                                                             %
5691 %                                                                             %
5692 %                                                                             %
5693 %   S e t P i x e l C h a n n e l M a s k                                     %
5694 %                                                                             %
5695 %                                                                             %
5696 %                                                                             %
5697 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5698 %
5699 %  SetPixelChannelMask() sets the pixel channel mask from the specified channel
5700 %  mask.
5701 %
5702 %  The format of the SetPixelChannelMask method is:
5703 %
5704 %      ChannelType SetPixelChannelMask(Image *image,
5705 %        const ChannelType channel_mask)
5706 %
5707 %  A description of each parameter follows:
5708 %
5709 %    o image: the image.
5710 %
5711 %    o channel_mask: the channel mask.
5712 %
5713 */
5714 MagickExport ChannelType SetPixelChannelMask(Image *image,
5715   const ChannelType channel_mask)
5716 {
5717   ChannelType
5718     mask;
5719
5720   mask=image->channel_mask;
5721   image->channel_mask=channel_mask;
5722   SetPixelChannelMapMask(image,channel_mask);
5723   return(mask);
5724 }