]> 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-2011 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 /*
72 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73 %                                                                             %
74 %                                                                             %
75 %                                                                             %
76 +   A c q u i r e P i x e l C h a n n e l M a p                               %
77 %                                                                             %
78 %                                                                             %
79 %                                                                             %
80 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81 %
82 %  AcquirePixelChannelMap() acquires a pixel component map.
83 %
84 %  The format of the AcquirePixelChannelMap() method is:
85 %
86 %      PixelChannelMap **AcquirePixelChannelMap(void)
87 %
88 */
89 MagickExport PixelChannelMap **AcquirePixelChannelMap(void)
90 {
91   PixelChannelMap
92     **channel_map;
93
94   register ssize_t
95     i;
96
97   channel_map=(PixelChannelMap **) AcquireAlignedMemory(MaxPixelChannelMaps,
98     sizeof(**channel_map));
99   if (channel_map == (PixelChannelMap **) NULL)
100     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
101   for (i=0; i < MaxPixelChannelMaps; i++)
102   {
103     register ssize_t
104       j;
105
106     channel_map[i]=(PixelChannelMap *) AcquireQuantumMemory(MaxPixelChannels,
107       sizeof(*channel_map[i]));
108     if (channel_map[i] == (PixelChannelMap *) NULL)
109       ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
110     (void) ResetMagickMemory(channel_map[i],0,MaxPixelChannels*
111       sizeof(*channel_map[i]));
112     for (j=0; j < MaxPixelChannels; j++)
113       channel_map[i][j].channel=(PixelChannel) j;
114   }
115   return(channel_map);
116 }
117 \f
118 /*
119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
120 %                                                                             %
121 %                                                                             %
122 %                                                                             %
123 +   C l o n e P i x e l C h a n n e l M a p                                   %
124 %                                                                             %
125 %                                                                             %
126 %                                                                             %
127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
128 %
129 %  ClonePixelChannelMap() clones a pixel component map.
130 %
131 %  The format of the ClonePixelChannelMap() method is:
132 %
133 %      PixelChannelMap **ClonePixelChannelMap(
134 %        PixelChannelMap **channel_map)
135 %
136 %  A description of each parameter follows:
137 %
138 %    o channel_map: the pixel component map.
139 %
140 */
141 MagickExport PixelChannelMap **ClonePixelChannelMap(
142   PixelChannelMap **channel_map)
143 {
144   PixelChannelMap
145     **clone_map;
146
147   register ssize_t
148     i;
149
150   assert(channel_map != (PixelChannelMap **) NULL);
151   clone_map=AcquirePixelChannelMap();
152   if (clone_map == (PixelChannelMap **) NULL)
153     return((PixelChannelMap **) NULL);
154   for (i=0; i < MaxPixelChannelMaps; i++)
155     (void) CopyMagickMemory(clone_map[i],channel_map[i],MaxPixelChannels*
156       sizeof(*channel_map[i]));
157   return(clone_map);
158 }
159 \f
160 /*
161 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
162 %                                                                             %
163 %                                                                             %
164 %                                                                             %
165 +   C l o n e P i x e l I n f o                                               %
166 %                                                                             %
167 %                                                                             %
168 %                                                                             %
169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
170 %
171 %  ClonePixelInfo() makes a duplicate of the given pixel info structure, or if
172 %  pixel info is NULL, a new one.
173 %
174 %  The format of the ClonePixelInfo method is:
175 %
176 %      PixelInfo *ClonePixelInfo(const PixelInfo *pixel_info)
177 %
178 %  A description of each parameter follows:
179 %
180 %    o pixel_info: the pixel info.
181 %
182 */
183 MagickExport PixelInfo *ClonePixelInfo(const PixelInfo *pixel)
184 {
185   PixelInfo
186     *pixel_info;
187
188   pixel_info=(PixelInfo *) AcquireAlignedMemory(1,sizeof(*pixel_info));
189   if (pixel_info == (PixelInfo *) NULL)
190     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
191   *pixel_info=(*pixel);
192   return(pixel_info);
193 }
194 \f
195 /*
196 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
197 %                                                                             %
198 %                                                                             %
199 %                                                                             %
200 +   D e s t r o y P i x e l C h a n n e l M a p                               %
201 %                                                                             %
202 %                                                                             %
203 %                                                                             %
204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
205 %
206 %  DestroyPixelChannelMap() deallocates memory associated with the pixel
207 %  channel map.
208 %
209 %  The format of the DestroyPixelChannelMap() method is:
210 %
211 %      PixelChannelMap **DestroyPixelChannelMap(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 **DestroyPixelChannelMap(
219   PixelChannelMap **channel_map)
220 {
221   register ssize_t
222     i;
223
224   assert(channel_map != (PixelChannelMap **) NULL);
225   for (i=0; i < MaxPixelChannelMaps; i++)
226     channel_map[i]=(PixelChannelMap *) RelinquishMagickMemory(channel_map[i]);
227   return((PixelChannelMap **) RelinquishMagickMemory(channel_map));
228 }
229 \f
230 /*
231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
232 %                                                                             %
233 %                                                                             %
234 %                                                                             %
235 %   E x p o r t I m a g e P i x e l s                                         %
236 %                                                                             %
237 %                                                                             %
238 %                                                                             %
239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
240 %
241 %  ExportImagePixels() extracts pixel data from an image and returns it to you.
242 %  The method returns MagickTrue on success otherwise MagickFalse if an error is
243 %  encountered.  The data is returned as char, short int, int, ssize_t, float,
244 %  or double in the order specified by map.
245 %
246 %  Suppose you want to extract the first scanline of a 640x480 image as
247 %  character data in red-green-blue order:
248 %
249 %      ExportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels,exception);
250 %
251 %  The format of the ExportImagePixels method is:
252 %
253 %      MagickBooleanType ExportImagePixels(const Image *image,
254 %        const ssize_t x_offset,const ssize_t y_offset,const size_t columns,
255 %        const size_t rows,const char *map,const StorageType type,
256 %        void *pixels,ExceptionInfo *exception)
257 %
258 %  A description of each parameter follows:
259 %
260 %    o image: the image.
261 %
262 %    o x_offset,y_offset,columns,rows:  These values define the perimeter
263 %      of a region of pixels you want to extract.
264 %
265 %    o map:  This string reflects the expected ordering of the pixel array.
266 %      It can be any combination or order of R = red, G = green, B = blue,
267 %      A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
268 %      Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
269 %      P = pad.
270 %
271 %    o type: Define the data type of the pixels.  Float and double types are
272 %      normalized to [0..1] otherwise [0..QuantumRange].  Choose from these
273 %      types: CharPixel, DoublePixel, FloatPixel, IntegerPixel, LongPixel,
274 %      QuantumPixel, or ShortPixel.
275 %
276 %    o pixels: This array of values contain the pixel components as defined by
277 %      map and type.  You must preallocate this array where the expected
278 %      length varies depending on the values of width, height, map, and type.
279 %
280 %    o exception: return any errors or warnings in this structure.
281 %
282 */
283 MagickExport MagickBooleanType ExportImagePixels(const Image *image,
284   const ssize_t x_offset,const ssize_t y_offset,const size_t columns,
285   const size_t rows,const char *map,const StorageType type,void *pixels,
286   ExceptionInfo *exception)
287 {
288   QuantumType
289     *quantum_map;
290
291   register ssize_t
292     i,
293     x;
294
295   register const Quantum
296     *p;
297
298   size_t
299     length;
300
301   ssize_t
302     y;
303
304   assert(image != (Image *) NULL);
305   assert(image->signature == MagickSignature);
306   if (image->debug != MagickFalse)
307     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
308   length=strlen(map);
309   quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
310   if (quantum_map == (QuantumType *) NULL)
311     {
312       (void) ThrowMagickException(exception,GetMagickModule(),
313         ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
314       return(MagickFalse);
315     }
316   for (i=0; i < (ssize_t) length; i++)
317   {
318     switch (map[i])
319     {
320       case 'A':
321       case 'a':
322       {
323         quantum_map[i]=AlphaQuantum;
324         break;
325       }
326       case 'B':
327       case 'b':
328       {
329         quantum_map[i]=BlueQuantum;
330         break;
331       }
332       case 'C':
333       case 'c':
334       {
335         quantum_map[i]=CyanQuantum;
336         if (image->colorspace == CMYKColorspace)
337           break;
338         quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
339         (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
340           "ColorSeparatedImageRequired","`%s'",map);
341         return(MagickFalse);
342       }
343       case 'g':
344       case 'G':
345       {
346         quantum_map[i]=GreenQuantum;
347         break;
348       }
349       case 'I':
350       case 'i':
351       {
352         quantum_map[i]=IndexQuantum;
353         break;
354       }
355       case 'K':
356       case 'k':
357       {
358         quantum_map[i]=BlackQuantum;
359         if (image->colorspace == CMYKColorspace)
360           break;
361         quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
362         (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
363           "ColorSeparatedImageRequired","`%s'",map);
364         return(MagickFalse);
365       }
366       case 'M':
367       case 'm':
368       {
369         quantum_map[i]=MagentaQuantum;
370         if (image->colorspace == CMYKColorspace)
371           break;
372         quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
373         (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
374           "ColorSeparatedImageRequired","`%s'",map);
375         return(MagickFalse);
376       }
377       case 'o':
378       case 'O':
379       {
380         quantum_map[i]=OpacityQuantum;
381         break;
382       }
383       case 'P':
384       case 'p':
385       {
386         quantum_map[i]=UndefinedQuantum;
387         break;
388       }
389       case 'R':
390       case 'r':
391       {
392         quantum_map[i]=RedQuantum;
393         break;
394       }
395       case 'Y':
396       case 'y':
397       {
398         quantum_map[i]=YellowQuantum;
399         if (image->colorspace == CMYKColorspace)
400           break;
401         quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
402         (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
403           "ColorSeparatedImageRequired","`%s'",map);
404         return(MagickFalse);
405       }
406       default:
407       {
408         quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
409         (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
410           "UnrecognizedPixelMap","`%s'",map);
411         return(MagickFalse);
412       }
413     }
414   }
415   switch (type)
416   {
417     case CharPixel:
418     {
419       register unsigned char
420         *q;
421
422       q=(unsigned char *) pixels;
423       if (LocaleCompare(map,"BGR") == 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(GetPixelBlue(image,p));
433               *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
434               *q++=ScaleQuantumToChar(GetPixelRed(image,p));
435               p+=GetPixelChannels(image);
436             }
437           }
438           break;
439         }
440       if (LocaleCompare(map,"BGRA") == 0)
441         {
442           for (y=0; y < (ssize_t) rows; y++)
443           {
444             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
445             if (p == (const Quantum *) NULL)
446               break;
447             for (x=0; x < (ssize_t) columns; x++)
448             {
449               *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
450               *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
451               *q++=ScaleQuantumToChar(GetPixelRed(image,p));
452               *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
453               p+=GetPixelChannels(image);
454             }
455           }
456           break;
457         }
458       if (LocaleCompare(map,"BGRP") == 0)
459         {
460           for (y=0; y < (ssize_t) rows; y++)
461           {
462             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
463             if (p == (const Quantum *) NULL)
464               break;
465             for (x=0; x < (ssize_t) columns; x++)
466             {
467               *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
468               *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
469               *q++=ScaleQuantumToChar(GetPixelRed(image,p));
470               *q++=ScaleQuantumToChar((Quantum) 0);
471               p+=GetPixelChannels(image);
472             }
473           }
474           break;
475         }
476       if (LocaleCompare(map,"I") == 0)
477         {
478           for (y=0; y < (ssize_t) rows; y++)
479           {
480             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
481             if (p == (const Quantum *) NULL)
482               break;
483             for (x=0; x < (ssize_t) columns; x++)
484             {
485               *q++=ScaleQuantumToChar(GetPixelIntensity(image,p));
486               p+=GetPixelChannels(image);
487             }
488           }
489           break;
490         }
491       if (LocaleCompare(map,"RGB") == 0)
492         {
493           for (y=0; y < (ssize_t) rows; y++)
494           {
495             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
496             if (p == (const Quantum *) NULL)
497               break;
498             for (x=0; x < (ssize_t) columns; x++)
499             {
500               *q++=ScaleQuantumToChar(GetPixelRed(image,p));
501               *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
502               *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
503               p+=GetPixelChannels(image);
504             }
505           }
506           break;
507         }
508       if (LocaleCompare(map,"RGBA") == 0)
509         {
510           for (y=0; y < (ssize_t) rows; y++)
511           {
512             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
513             if (p == (const Quantum *) NULL)
514               break;
515             for (x=0; x < (ssize_t) columns; x++)
516             {
517               *q++=ScaleQuantumToChar(GetPixelRed(image,p));
518               *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
519               *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
520               *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
521               p+=GetPixelChannels(image);
522             }
523           }
524           break;
525         }
526       if (LocaleCompare(map,"RGBP") == 0)
527         {
528           for (y=0; y < (ssize_t) rows; y++)
529           {
530             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
531             if (p == (const Quantum *) NULL)
532               break;
533             for (x=0; x < (ssize_t) columns; x++)
534             {
535               *q++=ScaleQuantumToChar(GetPixelRed(image,p));
536               *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
537               *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
538               *q++=ScaleQuantumToChar((Quantum) 0);
539               p+=GetPixelChannels(image);
540             }
541           }
542           break;
543         }
544       for (y=0; y < (ssize_t) rows; y++)
545       {
546         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
547         if (p == (const Quantum *) NULL)
548           break;
549         for (x=0; x < (ssize_t) columns; x++)
550         {
551           for (i=0; i < (ssize_t) length; i++)
552           {
553             *q=0;
554             switch (quantum_map[i])
555             {
556               case RedQuantum:
557               case CyanQuantum:
558               {
559                 *q=ScaleQuantumToChar(GetPixelRed(image,p));
560                 break;
561               }
562               case GreenQuantum:
563               case MagentaQuantum:
564               {
565                 *q=ScaleQuantumToChar(GetPixelGreen(image,p));
566                 break;
567               }
568               case BlueQuantum:
569               case YellowQuantum:
570               {
571                 *q=ScaleQuantumToChar(GetPixelBlue(image,p));
572                 break;
573               }
574               case AlphaQuantum:
575               {
576                 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
577                 break;
578               }
579               case OpacityQuantum:
580               {
581                 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
582                 break;
583               }
584               case BlackQuantum:
585               {
586                 if (image->colorspace == CMYKColorspace)
587                   *q=ScaleQuantumToChar(GetPixelBlack(image,p));
588                 break;
589               }
590               case IndexQuantum:
591               {
592                 *q=ScaleQuantumToChar(GetPixelIntensity(image,p));
593                 break;
594               }
595               default:
596                 break;
597             }
598             q++;
599           }
600           p+=GetPixelChannels(image);
601         }
602       }
603       break;
604     }
605     case DoublePixel:
606     {
607       register double
608         *q;
609
610       q=(double *) pixels;
611       if (LocaleCompare(map,"BGR") == 0)
612         {
613           for (y=0; y < (ssize_t) rows; y++)
614           {
615             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
616             if (p == (const Quantum *) NULL)
617               break;
618             for (x=0; x < (ssize_t) columns; x++)
619             {
620               *q++=(double) (QuantumScale*GetPixelBlue(image,p));
621               *q++=(double) (QuantumScale*GetPixelGreen(image,p));
622               *q++=(double) (QuantumScale*GetPixelRed(image,p));
623               p+=GetPixelChannels(image);
624             }
625           }
626           break;
627         }
628       if (LocaleCompare(map,"BGRA") == 0)
629         {
630           for (y=0; y < (ssize_t) rows; y++)
631           {
632             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
633             if (p == (const Quantum *) NULL)
634               break;
635             for (x=0; x < (ssize_t) columns; x++)
636             {
637               *q++=(double) (QuantumScale*GetPixelBlue(image,p));
638               *q++=(double) (QuantumScale*GetPixelGreen(image,p));
639               *q++=(double) (QuantumScale*GetPixelRed(image,p));
640               *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
641               p+=GetPixelChannels(image);
642             }
643           }
644           break;
645         }
646       if (LocaleCompare(map,"BGRP") == 0)
647         {
648           for (y=0; y < (ssize_t) rows; y++)
649           {
650             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
651             if (p == (const Quantum *) NULL)
652               break;
653             for (x=0; x < (ssize_t) columns; x++)
654             {
655               *q++=(double) (QuantumScale*GetPixelBlue(image,p));
656               *q++=(double) (QuantumScale*GetPixelGreen(image,p));
657               *q++=(double) (QuantumScale*GetPixelRed(image,p));
658               *q++=0.0;
659               p+=GetPixelChannels(image);
660             }
661           }
662           break;
663         }
664       if (LocaleCompare(map,"I") == 0)
665         {
666           for (y=0; y < (ssize_t) rows; y++)
667           {
668             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
669             if (p == (const Quantum *) NULL)
670               break;
671             for (x=0; x < (ssize_t) columns; x++)
672             {
673               *q++=(double) (QuantumScale*GetPixelIntensity(image,p));
674               p+=GetPixelChannels(image);
675             }
676           }
677           break;
678         }
679       if (LocaleCompare(map,"RGB") == 0)
680         {
681           for (y=0; y < (ssize_t) rows; y++)
682           {
683             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
684             if (p == (const Quantum *) NULL)
685               break;
686             for (x=0; x < (ssize_t) columns; x++)
687             {
688               *q++=(double) (QuantumScale*GetPixelRed(image,p));
689               *q++=(double) (QuantumScale*GetPixelGreen(image,p));
690               *q++=(double) (QuantumScale*GetPixelBlue(image,p));
691               p+=GetPixelChannels(image);
692             }
693           }
694           break;
695         }
696       if (LocaleCompare(map,"RGBA") == 0)
697         {
698           for (y=0; y < (ssize_t) rows; y++)
699           {
700             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
701             if (p == (const Quantum *) NULL)
702               break;
703             for (x=0; x < (ssize_t) columns; x++)
704             {
705               *q++=(double) (QuantumScale*GetPixelRed(image,p));
706               *q++=(double) (QuantumScale*GetPixelGreen(image,p));
707               *q++=(double) (QuantumScale*GetPixelBlue(image,p));
708               *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
709               p+=GetPixelChannels(image);
710             }
711           }
712           break;
713         }
714       if (LocaleCompare(map,"RGBP") == 0)
715         {
716           for (y=0; y < (ssize_t) rows; y++)
717           {
718             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
719             if (p == (const Quantum *) NULL)
720               break;
721             for (x=0; x < (ssize_t) columns; x++)
722             {
723               *q++=(double) (QuantumScale*GetPixelRed(image,p));
724               *q++=(double) (QuantumScale*GetPixelGreen(image,p));
725               *q++=(double) (QuantumScale*GetPixelBlue(image,p));
726               *q++=0.0;
727               p+=GetPixelChannels(image);
728             }
729           }
730           break;
731         }
732       for (y=0; y < (ssize_t) rows; y++)
733       {
734         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
735         if (p == (const Quantum *) NULL)
736           break;
737         for (x=0; x < (ssize_t) columns; x++)
738         {
739           for (i=0; i < (ssize_t) length; i++)
740           {
741             *q=0;
742             switch (quantum_map[i])
743             {
744               case RedQuantum:
745               case CyanQuantum:
746               {
747                 *q=(double) (QuantumScale*GetPixelRed(image,p));
748                 break;
749               }
750               case GreenQuantum:
751               case MagentaQuantum:
752               {
753                 *q=(double) (QuantumScale*GetPixelGreen(image,p));
754                 break;
755               }
756               case BlueQuantum:
757               case YellowQuantum:
758               {
759                 *q=(double) (QuantumScale*GetPixelBlue(image,p));
760                 break;
761               }
762               case AlphaQuantum:
763               {
764                 *q=(double) (QuantumScale*GetPixelAlpha(image,p));
765                 break;
766               }
767               case OpacityQuantum:
768               {
769                 *q=(double) (QuantumScale*GetPixelAlpha(image,p));
770                 break;
771               }
772               case BlackQuantum:
773               {
774                 if (image->colorspace == CMYKColorspace)
775                   *q=(double) (QuantumScale*
776                     GetPixelBlack(image,p));
777                 break;
778               }
779               case IndexQuantum:
780               {
781                 *q=(double) (QuantumScale*GetPixelIntensity(image,p));
782                 break;
783               }
784               default:
785                 *q=0;
786             }
787             q++;
788           }
789           p+=GetPixelChannels(image);
790         }
791       }
792       break;
793     }
794     case FloatPixel:
795     {
796       register float
797         *q;
798
799       q=(float *) pixels;
800       if (LocaleCompare(map,"BGR") == 0)
801         {
802           for (y=0; y < (ssize_t) rows; y++)
803           {
804             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
805             if (p == (const Quantum *) NULL)
806               break;
807             for (x=0; x < (ssize_t) columns; x++)
808             {
809               *q++=(float) (QuantumScale*GetPixelBlue(image,p));
810               *q++=(float) (QuantumScale*GetPixelGreen(image,p));
811               *q++=(float) (QuantumScale*GetPixelRed(image,p));
812               p+=GetPixelChannels(image);
813             }
814           }
815           break;
816         }
817       if (LocaleCompare(map,"BGRA") == 0)
818         {
819           for (y=0; y < (ssize_t) rows; y++)
820           {
821             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
822             if (p == (const Quantum *) NULL)
823               break;
824             for (x=0; x < (ssize_t) columns; x++)
825             {
826               *q++=(float) (QuantumScale*GetPixelBlue(image,p));
827               *q++=(float) (QuantumScale*GetPixelGreen(image,p));
828               *q++=(float) (QuantumScale*GetPixelRed(image,p));
829               *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
830               p+=GetPixelChannels(image);
831             }
832           }
833           break;
834         }
835       if (LocaleCompare(map,"BGRP") == 0)
836         {
837           for (y=0; y < (ssize_t) rows; y++)
838           {
839             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
840             if (p == (const Quantum *) NULL)
841               break;
842             for (x=0; x < (ssize_t) columns; x++)
843             {
844               *q++=(float) (QuantumScale*GetPixelBlue(image,p));
845               *q++=(float) (QuantumScale*GetPixelGreen(image,p));
846               *q++=(float) (QuantumScale*GetPixelRed(image,p));
847               *q++=0.0;
848               p+=GetPixelChannels(image);
849             }
850           }
851           break;
852         }
853       if (LocaleCompare(map,"I") == 0)
854         {
855           for (y=0; y < (ssize_t) rows; y++)
856           {
857             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
858             if (p == (const Quantum *) NULL)
859               break;
860             for (x=0; x < (ssize_t) columns; x++)
861             {
862               *q++=(float) (QuantumScale*GetPixelIntensity(image,p));
863               p+=GetPixelChannels(image);
864             }
865           }
866           break;
867         }
868       if (LocaleCompare(map,"RGB") == 0)
869         {
870           for (y=0; y < (ssize_t) rows; y++)
871           {
872             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
873             if (p == (const Quantum *) NULL)
874               break;
875             for (x=0; x < (ssize_t) columns; x++)
876             {
877               *q++=(float) (QuantumScale*GetPixelRed(image,p));
878               *q++=(float) (QuantumScale*GetPixelGreen(image,p));
879               *q++=(float) (QuantumScale*GetPixelBlue(image,p));
880               p+=GetPixelChannels(image);
881             }
882           }
883           break;
884         }
885       if (LocaleCompare(map,"RGBA") == 0)
886         {
887           for (y=0; y < (ssize_t) rows; y++)
888           {
889             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
890             if (p == (const Quantum *) NULL)
891               break;
892             for (x=0; x < (ssize_t) columns; x++)
893             {
894               *q++=(float) (QuantumScale*GetPixelRed(image,p));
895               *q++=(float) (QuantumScale*GetPixelGreen(image,p));
896               *q++=(float) (QuantumScale*GetPixelBlue(image,p));
897               *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
898               p+=GetPixelChannels(image);
899             }
900           }
901           break;
902         }
903       if (LocaleCompare(map,"RGBP") == 0)
904         {
905           for (y=0; y < (ssize_t) rows; y++)
906           {
907             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
908             if (p == (const Quantum *) NULL)
909               break;
910             for (x=0; x < (ssize_t) columns; x++)
911             {
912               *q++=(float) (QuantumScale*GetPixelRed(image,p));
913               *q++=(float) (QuantumScale*GetPixelGreen(image,p));
914               *q++=(float) (QuantumScale*GetPixelBlue(image,p));
915               *q++=0.0;
916               p+=GetPixelChannels(image);
917             }
918           }
919           break;
920         }
921       for (y=0; y < (ssize_t) rows; y++)
922       {
923         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
924         if (p == (const Quantum *) NULL)
925           break;
926         for (x=0; x < (ssize_t) columns; x++)
927         {
928           for (i=0; i < (ssize_t) length; i++)
929           {
930             *q=0;
931             switch (quantum_map[i])
932             {
933               case RedQuantum:
934               case CyanQuantum:
935               {
936                 *q=(float) (QuantumScale*GetPixelRed(image,p));
937                 break;
938               }
939               case GreenQuantum:
940               case MagentaQuantum:
941               {
942                 *q=(float) (QuantumScale*GetPixelGreen(image,p));
943                 break;
944               }
945               case BlueQuantum:
946               case YellowQuantum:
947               {
948                 *q=(float) (QuantumScale*GetPixelBlue(image,p));
949                 break;
950               }
951               case AlphaQuantum:
952               {
953                 *q=(float) (QuantumScale*((Quantum) (GetPixelAlpha(image,p))));
954                 break;
955               }
956               case OpacityQuantum:
957               {
958                 *q=(float) (QuantumScale*GetPixelAlpha(image,p));
959                 break;
960               }
961               case BlackQuantum:
962               {
963                 if (image->colorspace == CMYKColorspace)
964                   *q=(float) (QuantumScale* GetPixelBlack(image,p));
965                 break;
966               }
967               case IndexQuantum:
968               {
969                 *q=(float) (QuantumScale*GetPixelIntensity(image,p));
970                 break;
971               }
972               default:
973                 *q=0;
974             }
975             q++;
976           }
977           p+=GetPixelChannels(image);
978         }
979       }
980       break;
981     }
982     case IntegerPixel:
983     {
984       register unsigned int
985         *q;
986
987       q=(unsigned int *) pixels;
988       if (LocaleCompare(map,"BGR") == 0)
989         {
990           for (y=0; y < (ssize_t) rows; y++)
991           {
992             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
993             if (p == (const Quantum *) NULL)
994               break;
995             for (x=0; x < (ssize_t) columns; x++)
996             {
997               *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
998               *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
999               *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
1000               p+=GetPixelChannels(image);
1001             }
1002           }
1003           break;
1004         }
1005       if (LocaleCompare(map,"BGRA") == 0)
1006         {
1007           for (y=0; y < (ssize_t) rows; y++)
1008           {
1009             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1010             if (p == (const Quantum *) NULL)
1011               break;
1012             for (x=0; x < (ssize_t) columns; x++)
1013             {
1014               *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
1015               *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
1016               *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
1017               *q++=(unsigned int) ScaleQuantumToLong(GetPixelAlpha(image,p));
1018               p+=GetPixelChannels(image);
1019             }
1020           }
1021           break;
1022         }
1023       if (LocaleCompare(map,"BGRP") == 0)
1024         {
1025           for (y=0; y < (ssize_t) rows; y++)
1026           {
1027             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1028             if (p == (const Quantum *) NULL)
1029               break;
1030             for (x=0; x < (ssize_t) columns; x++)
1031             {
1032               *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
1033               *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
1034               *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
1035               *q++=0U;
1036               p+=GetPixelChannels(image);
1037             }
1038           }
1039           break;
1040         }
1041       if (LocaleCompare(map,"I") == 0)
1042         {
1043           for (y=0; y < (ssize_t) rows; y++)
1044           {
1045             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1046             if (p == (const Quantum *) NULL)
1047               break;
1048             for (x=0; x < (ssize_t) columns; x++)
1049             {
1050               *q++=(unsigned int) ScaleQuantumToLong(
1051                 GetPixelIntensity(image,p));
1052               p+=GetPixelChannels(image);
1053             }
1054           }
1055           break;
1056         }
1057       if (LocaleCompare(map,"RGB") == 0)
1058         {
1059           for (y=0; y < (ssize_t) rows; y++)
1060           {
1061             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1062             if (p == (const Quantum *) NULL)
1063               break;
1064             for (x=0; x < (ssize_t) columns; x++)
1065             {
1066               *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
1067               *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
1068               *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
1069               p+=GetPixelChannels(image);
1070             }
1071           }
1072           break;
1073         }
1074       if (LocaleCompare(map,"RGBA") == 0)
1075         {
1076           for (y=0; y < (ssize_t) rows; y++)
1077           {
1078             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1079             if (p == (const Quantum *) NULL)
1080               break;
1081             for (x=0; x < (ssize_t) columns; x++)
1082             {
1083               *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
1084               *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
1085               *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
1086               *q++=(unsigned int) ScaleQuantumToLong(GetPixelAlpha(image,p));
1087               p+=GetPixelChannels(image);
1088             }
1089           }
1090           break;
1091         }
1092       if (LocaleCompare(map,"RGBP") == 0)
1093         {
1094           for (y=0; y < (ssize_t) rows; y++)
1095           {
1096             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1097             if (p == (const Quantum *) NULL)
1098               break;
1099             for (x=0; x < (ssize_t) columns; x++)
1100             {
1101               *q++=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
1102               *q++=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
1103               *q++=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
1104               *q++=0U;
1105               p+=GetPixelChannels(image);
1106             }
1107           }
1108           break;
1109         }
1110       for (y=0; y < (ssize_t) rows; y++)
1111       {
1112         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1113         if (p == (const Quantum *) NULL)
1114           break;
1115         for (x=0; x < (ssize_t) columns; x++)
1116         {
1117           for (i=0; i < (ssize_t) length; i++)
1118           {
1119             *q=0;
1120             switch (quantum_map[i])
1121             {
1122               case RedQuantum:
1123               case CyanQuantum:
1124               {
1125                 *q=(unsigned int) ScaleQuantumToLong(GetPixelRed(image,p));
1126                 break;
1127               }
1128               case GreenQuantum:
1129               case MagentaQuantum:
1130               {
1131                 *q=(unsigned int) ScaleQuantumToLong(GetPixelGreen(image,p));
1132                 break;
1133               }
1134               case BlueQuantum:
1135               case YellowQuantum:
1136               {
1137                 *q=(unsigned int) ScaleQuantumToLong(GetPixelBlue(image,p));
1138                 break;
1139               }
1140               case AlphaQuantum:
1141               {
1142                 *q=(unsigned int) ScaleQuantumToLong(GetPixelAlpha(image,p));
1143                 break;
1144               }
1145               case OpacityQuantum:
1146               {
1147                 *q=(unsigned int) ScaleQuantumToLong(GetPixelAlpha(image,p));
1148                 break;
1149               }
1150               case BlackQuantum:
1151               {
1152                 if (image->colorspace == CMYKColorspace)
1153                   *q=(unsigned int) ScaleQuantumToLong(GetPixelBlack(image,p));
1154                 break;
1155               }
1156               case IndexQuantum:
1157               {
1158                 *q=(unsigned int) ScaleQuantumToLong(
1159                   GetPixelIntensity(image,p));
1160                 break;
1161               }
1162               default:
1163                 *q=0;
1164             }
1165             q++;
1166           }
1167           p+=GetPixelChannels(image);
1168         }
1169       }
1170       break;
1171     }
1172     case LongPixel:
1173     {
1174       register size_t
1175         *q;
1176
1177       q=(size_t *) pixels;
1178       if (LocaleCompare(map,"BGR") == 0)
1179         {
1180           for (y=0; y < (ssize_t) rows; y++)
1181           {
1182             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1183             if (p == (const Quantum *) NULL)
1184               break;
1185             for (x=0; x < (ssize_t) columns; x++)
1186             {
1187               *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1188               *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1189               *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1190               p+=GetPixelChannels(image);
1191             }
1192           }
1193           break;
1194         }
1195       if (LocaleCompare(map,"BGRA") == 0)
1196         {
1197           for (y=0; y < (ssize_t) rows; y++)
1198           {
1199             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1200             if (p == (const Quantum *) NULL)
1201               break;
1202             for (x=0; x < (ssize_t) columns; x++)
1203             {
1204               *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1205               *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1206               *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1207               *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
1208               p+=GetPixelChannels(image);
1209             }
1210           }
1211           break;
1212         }
1213       if (LocaleCompare(map,"BGRP") == 0)
1214         {
1215           for (y=0; y < (ssize_t) rows; y++)
1216           {
1217             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1218             if (p == (const Quantum *) NULL)
1219               break;
1220             for (x=0; x < (ssize_t) columns; x++)
1221             {
1222               *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1223               *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1224               *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1225               *q++=0;
1226               p+=GetPixelChannels(image);
1227             }
1228           }
1229           break;
1230         }
1231       if (LocaleCompare(map,"I") == 0)
1232         {
1233           for (y=0; y < (ssize_t) rows; y++)
1234           {
1235             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1236             if (p == (const Quantum *) NULL)
1237               break;
1238             for (x=0; x < (ssize_t) columns; x++)
1239             {
1240               *q++=ScaleQuantumToLong(GetPixelIntensity(image,p));
1241               p+=GetPixelChannels(image);
1242             }
1243           }
1244           break;
1245         }
1246       if (LocaleCompare(map,"RGB") == 0)
1247         {
1248           for (y=0; y < (ssize_t) rows; y++)
1249           {
1250             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1251             if (p == (const Quantum *) NULL)
1252               break;
1253             for (x=0; x < (ssize_t) columns; x++)
1254             {
1255               *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1256               *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1257               *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1258               p+=GetPixelChannels(image);
1259             }
1260           }
1261           break;
1262         }
1263       if (LocaleCompare(map,"RGBA") == 0)
1264         {
1265           for (y=0; y < (ssize_t) rows; y++)
1266           {
1267             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1268             if (p == (const Quantum *) NULL)
1269               break;
1270             for (x=0; x < (ssize_t) columns; x++)
1271             {
1272               *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1273               *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1274               *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1275               *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
1276               p+=GetPixelChannels(image);
1277             }
1278           }
1279           break;
1280         }
1281       if (LocaleCompare(map,"RGBP") == 0)
1282         {
1283           for (y=0; y < (ssize_t) rows; y++)
1284           {
1285             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1286             if (p == (const Quantum *) NULL)
1287               break;
1288             for (x=0; x < (ssize_t) columns; x++)
1289             {
1290               *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1291               *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1292               *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1293               *q++=0;
1294               p+=GetPixelChannels(image);
1295             }
1296           }
1297           break;
1298         }
1299       for (y=0; y < (ssize_t) rows; y++)
1300       {
1301         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1302         if (p == (const Quantum *) NULL)
1303           break;
1304         for (x=0; x < (ssize_t) columns; x++)
1305         {
1306           for (i=0; i < (ssize_t) length; i++)
1307           {
1308             *q=0;
1309             switch (quantum_map[i])
1310             {
1311               case RedQuantum:
1312               case CyanQuantum:
1313               {
1314                 *q=ScaleQuantumToLong(GetPixelRed(image,p));
1315                 break;
1316               }
1317               case GreenQuantum:
1318               case MagentaQuantum:
1319               {
1320                 *q=ScaleQuantumToLong(GetPixelGreen(image,p));
1321                 break;
1322               }
1323               case BlueQuantum:
1324               case YellowQuantum:
1325               {
1326                 *q=ScaleQuantumToLong(GetPixelBlue(image,p));
1327                 break;
1328               }
1329               case AlphaQuantum:
1330               {
1331                 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
1332                 break;
1333               }
1334               case OpacityQuantum:
1335               {
1336                 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
1337                 break;
1338               }
1339               case BlackQuantum:
1340               {
1341                 if (image->colorspace == CMYKColorspace)
1342                   *q=ScaleQuantumToLong(GetPixelBlack(image,p));
1343                 break;
1344               }
1345               case IndexQuantum:
1346               {
1347                 *q=ScaleQuantumToLong(GetPixelIntensity(image,p));
1348                 break;
1349               }
1350               default:
1351                 break;
1352             }
1353             q++;
1354           }
1355           p+=GetPixelChannels(image);
1356         }
1357       }
1358       break;
1359     }
1360     case QuantumPixel:
1361     {
1362       register Quantum
1363         *q;
1364
1365       q=(Quantum *) pixels;
1366       if (LocaleCompare(map,"BGR") == 0)
1367         {
1368           for (y=0; y < (ssize_t) rows; y++)
1369           {
1370             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1371             if (p == (const Quantum *) NULL)
1372               break;
1373             for (x=0; x < (ssize_t) columns; x++)
1374             {
1375               *q++=GetPixelBlue(image,p);
1376               *q++=GetPixelGreen(image,p);
1377               *q++=GetPixelRed(image,p);
1378               p+=GetPixelChannels(image);
1379             }
1380           }
1381           break;
1382         }
1383       if (LocaleCompare(map,"BGRA") == 0)
1384         {
1385           for (y=0; y < (ssize_t) rows; y++)
1386           {
1387             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1388             if (p == (const Quantum *) NULL)
1389               break;
1390             for (x=0; x < (ssize_t) columns; x++)
1391             {
1392               *q++=GetPixelBlue(image,p);
1393               *q++=GetPixelGreen(image,p);
1394               *q++=GetPixelRed(image,p);
1395               *q++=(Quantum) (GetPixelAlpha(image,p));
1396               p+=GetPixelChannels(image);
1397             }
1398           }
1399           break;
1400         }
1401       if (LocaleCompare(map,"BGRP") == 0)
1402         {
1403           for (y=0; y < (ssize_t) rows; y++)
1404           {
1405             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1406             if (p == (const Quantum *) NULL)
1407               break;
1408             for (x=0; x < (ssize_t) columns; x++)
1409             {
1410               *q++=GetPixelBlue(image,p);
1411               *q++=GetPixelGreen(image,p);
1412               *q++=GetPixelRed(image,p);
1413               *q++=(Quantum) 0;
1414               p+=GetPixelChannels(image);
1415             }
1416           }
1417           break;
1418         }
1419       if (LocaleCompare(map,"I") == 0)
1420         {
1421           for (y=0; y < (ssize_t) rows; y++)
1422           {
1423             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1424             if (p == (const Quantum *) NULL)
1425               break;
1426             for (x=0; x < (ssize_t) columns; x++)
1427             {
1428               *q++=GetPixelIntensity(image,p);
1429               p+=GetPixelChannels(image);
1430             }
1431           }
1432           break;
1433         }
1434       if (LocaleCompare(map,"RGB") == 0)
1435         {
1436           for (y=0; y < (ssize_t) rows; y++)
1437           {
1438             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1439             if (p == (const Quantum *) NULL)
1440               break;
1441             for (x=0; x < (ssize_t) columns; x++)
1442             {
1443               *q++=GetPixelRed(image,p);
1444               *q++=GetPixelGreen(image,p);
1445               *q++=GetPixelBlue(image,p);
1446               p+=GetPixelChannels(image);
1447             }
1448           }
1449           break;
1450         }
1451       if (LocaleCompare(map,"RGBA") == 0)
1452         {
1453           for (y=0; y < (ssize_t) rows; y++)
1454           {
1455             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1456             if (p == (const Quantum *) NULL)
1457               break;
1458             for (x=0; x < (ssize_t) columns; x++)
1459             {
1460               *q++=GetPixelRed(image,p);
1461               *q++=GetPixelGreen(image,p);
1462               *q++=GetPixelBlue(image,p);
1463               *q++=(Quantum) (GetPixelAlpha(image,p));
1464               p+=GetPixelChannels(image);
1465             }
1466           }
1467           break;
1468         }
1469       if (LocaleCompare(map,"RGBP") == 0)
1470         {
1471           for (y=0; y < (ssize_t) rows; y++)
1472           {
1473             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1474             if (p == (const Quantum *) NULL)
1475               break;
1476             for (x=0; x < (ssize_t) columns; x++)
1477             {
1478               *q++=GetPixelRed(image,p);
1479               *q++=GetPixelGreen(image,p);
1480               *q++=GetPixelBlue(image,p);
1481               *q++=(Quantum) 0;
1482               p+=GetPixelChannels(image);
1483             }
1484           }
1485           break;
1486         }
1487       for (y=0; y < (ssize_t) rows; y++)
1488       {
1489         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1490         if (p == (const Quantum *) NULL)
1491           break;
1492         for (x=0; x < (ssize_t) columns; x++)
1493         {
1494           for (i=0; i < (ssize_t) length; i++)
1495           {
1496             *q=(Quantum) 0;
1497             switch (quantum_map[i])
1498             {
1499               case RedQuantum:
1500               case CyanQuantum:
1501               {
1502                 *q=GetPixelRed(image,p);
1503                 break;
1504               }
1505               case GreenQuantum:
1506               case MagentaQuantum:
1507               {
1508                 *q=GetPixelGreen(image,p);
1509                 break;
1510               }
1511               case BlueQuantum:
1512               case YellowQuantum:
1513               {
1514                 *q=GetPixelBlue(image,p);
1515                 break;
1516               }
1517               case AlphaQuantum:
1518               {
1519                 *q=(Quantum) (GetPixelAlpha(image,p));
1520                 break;
1521               }
1522               case OpacityQuantum:
1523               {
1524                 *q=GetPixelAlpha(image,p);
1525                 break;
1526               }
1527               case BlackQuantum:
1528               {
1529                 if (image->colorspace == CMYKColorspace)
1530                   *q=GetPixelBlack(image,p);
1531                 break;
1532               }
1533               case IndexQuantum:
1534               {
1535                 *q=(GetPixelIntensity(image,p));
1536                 break;
1537               }
1538               default:
1539                 *q=(Quantum) 0;
1540             }
1541             q++;
1542           }
1543           p+=GetPixelChannels(image);
1544         }
1545       }
1546       break;
1547     }
1548     case ShortPixel:
1549     {
1550       register unsigned short
1551         *q;
1552
1553       q=(unsigned short *) pixels;
1554       if (LocaleCompare(map,"BGR") == 0)
1555         {
1556           for (y=0; y < (ssize_t) rows; y++)
1557           {
1558             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1559             if (p == (const Quantum *) NULL)
1560               break;
1561             for (x=0; x < (ssize_t) columns; x++)
1562             {
1563               *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1564               *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1565               *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1566               p+=GetPixelChannels(image);
1567             }
1568           }
1569           break;
1570         }
1571       if (LocaleCompare(map,"BGRA") == 0)
1572         {
1573           for (y=0; y < (ssize_t) rows; y++)
1574           {
1575             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1576             if (p == (const Quantum *) NULL)
1577               break;
1578             for (x=0; x < (ssize_t) columns; x++)
1579             {
1580               *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1581               *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1582               *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1583               *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1584               p+=GetPixelChannels(image);
1585             }
1586           }
1587           break;
1588         }
1589       if (LocaleCompare(map,"BGRP") == 0)
1590         {
1591           for (y=0; y < (ssize_t) rows; y++)
1592           {
1593             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1594             if (p == (const Quantum *) NULL)
1595               break;
1596             for (x=0; x < (ssize_t) columns; x++)
1597             {
1598               *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1599               *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1600               *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1601               *q++=0;
1602               p+=GetPixelChannels(image);
1603             }
1604           }
1605           break;
1606         }
1607       if (LocaleCompare(map,"I") == 0)
1608         {
1609           for (y=0; y < (ssize_t) rows; y++)
1610           {
1611             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1612             if (p == (const Quantum *) NULL)
1613               break;
1614             for (x=0; x < (ssize_t) columns; x++)
1615             {
1616               *q++=ScaleQuantumToShort(GetPixelIntensity(image,p));
1617               p+=GetPixelChannels(image);
1618             }
1619           }
1620           break;
1621         }
1622       if (LocaleCompare(map,"RGB") == 0)
1623         {
1624           for (y=0; y < (ssize_t) rows; y++)
1625           {
1626             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1627             if (p == (const Quantum *) NULL)
1628               break;
1629             for (x=0; x < (ssize_t) columns; x++)
1630             {
1631               *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1632               *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1633               *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1634               p+=GetPixelChannels(image);
1635             }
1636           }
1637           break;
1638         }
1639       if (LocaleCompare(map,"RGBA") == 0)
1640         {
1641           for (y=0; y < (ssize_t) rows; y++)
1642           {
1643             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1644             if (p == (const Quantum *) NULL)
1645               break;
1646             for (x=0; x < (ssize_t) columns; x++)
1647             {
1648               *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1649               *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1650               *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1651               *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1652               p+=GetPixelChannels(image);
1653             }
1654           }
1655           break;
1656         }
1657       if (LocaleCompare(map,"RGBP") == 0)
1658         {
1659           for (y=0; y < (ssize_t) rows; y++)
1660           {
1661             p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1662             if (p == (const Quantum *) NULL)
1663               break;
1664             for (x=0; x < (ssize_t) columns; x++)
1665             {
1666               *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1667               *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1668               *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1669               *q++=0;
1670               p+=GetPixelChannels(image);
1671             }
1672           }
1673           break;
1674         }
1675       for (y=0; y < (ssize_t) rows; y++)
1676       {
1677         p=GetVirtualPixels(image,x_offset,y_offset+y,columns,1,exception);
1678         if (p == (const Quantum *) NULL)
1679           break;
1680         for (x=0; x < (ssize_t) columns; x++)
1681         {
1682           for (i=0; i < (ssize_t) length; i++)
1683           {
1684             *q=0;
1685             switch (quantum_map[i])
1686             {
1687               case RedQuantum:
1688               case CyanQuantum:
1689               {
1690                 *q=ScaleQuantumToShort(GetPixelRed(image,p));
1691                 break;
1692               }
1693               case GreenQuantum:
1694               case MagentaQuantum:
1695               {
1696                 *q=ScaleQuantumToShort(GetPixelGreen(image,p));
1697                 break;
1698               }
1699               case BlueQuantum:
1700               case YellowQuantum:
1701               {
1702                 *q=ScaleQuantumToShort(GetPixelBlue(image,p));
1703                 break;
1704               }
1705               case AlphaQuantum:
1706               {
1707                 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1708                 break;
1709               }
1710               case OpacityQuantum:
1711               {
1712                 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1713                 break;
1714               }
1715               case BlackQuantum:
1716               {
1717                 if (image->colorspace == CMYKColorspace)
1718                   *q=ScaleQuantumToShort(GetPixelBlack(image,p));
1719                 break;
1720               }
1721               case IndexQuantum:
1722               {
1723                 *q=ScaleQuantumToShort(GetPixelIntensity(image,p));
1724                 break;
1725               }
1726               default:
1727                 break;
1728             }
1729             q++;
1730           }
1731           p+=GetPixelChannels(image);
1732         }
1733       }
1734       break;
1735     }
1736     default:
1737     {
1738       quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1739       (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
1740         "UnrecognizedPixelMap","`%s'",map);
1741       break;
1742     }
1743   }
1744   quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1745   return(MagickTrue);
1746 }
1747 \f
1748 /*
1749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1750 %                                                                             %
1751 %                                                                             %
1752 %                                                                             %
1753 %   G e t M a g i c k P i x e l P a c k e t                                   %
1754 %                                                                             %
1755 %                                                                             %
1756 %                                                                             %
1757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1758 %
1759 %  GetPixelInfo() initializes the PixelInfo structure.
1760 %
1761 %  The format of the GetPixelInfo method is:
1762 %
1763 %      GetPixelInfo(const Image *image,PixelInfo *pixel)
1764 %
1765 %  A description of each parameter follows:
1766 %
1767 %    o image: the image.
1768 %
1769 %    o pixel: Specifies a pointer to a PixelPacket structure.
1770 %
1771 */
1772 MagickExport void GetPixelInfo(const Image *image,
1773   PixelInfo *pixel)
1774 {
1775   pixel->storage_class=DirectClass;
1776   pixel->colorspace=RGBColorspace;
1777   pixel->matte=MagickFalse;
1778   pixel->fuzz=0.0;
1779   pixel->depth=MAGICKCORE_QUANTUM_DEPTH;
1780   pixel->red=0.0;
1781   pixel->green=0.0;
1782   pixel->blue=0.0;
1783   pixel->black=0.0;
1784   pixel->alpha=(MagickRealType) OpaqueAlpha;
1785   pixel->index=0.0;
1786   if (image == (const Image *) NULL)
1787     return;
1788   pixel->storage_class=image->storage_class;
1789   pixel->colorspace=image->colorspace;
1790   pixel->matte=image->matte;
1791   pixel->depth=image->depth;
1792   pixel->fuzz=image->fuzz;
1793 }
1794 \f
1795 /*
1796 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1797 %                                                                             %
1798 %                                                                             %
1799 %                                                                             %
1800 %   I m p o r t I m a g e P i x e l s                                         %
1801 %                                                                             %
1802 %                                                                             %
1803 %                                                                             %
1804 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1805 %
1806 %  ImportImagePixels() accepts pixel data and stores in the image at the
1807 %  location you specify.  The method returns MagickTrue on success otherwise
1808 %  MagickFalse if an error is encountered.  The pixel data can be either char,
1809 %  short int, int, ssize_t, float, or double in the order specified by map.
1810 %
1811 %  Suppose your want to upload the first scanline of a 640x480 image from
1812 %  character data in red-green-blue order:
1813 %
1814 %      ImportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels);
1815 %
1816 %  The format of the ImportImagePixels method is:
1817 %
1818 %      MagickBooleanType ImportImagePixels(Image *image,const ssize_t x_offset,
1819 %        const ssize_t y_offset,const size_t columns,
1820 %        const size_t rows,const char *map,const StorageType type,
1821 %        const void *pixels)
1822 %
1823 %  A description of each parameter follows:
1824 %
1825 %    o image: the image.
1826 %
1827 %    o x_offset,y_offset,columns,rows:  These values define the perimeter
1828 %      of a region of pixels you want to define.
1829 %
1830 %    o map:  This string reflects the expected ordering of the pixel array.
1831 %      It can be any combination or order of R = red, G = green, B = blue,
1832 %      A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
1833 %      Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
1834 %      P = pad.
1835 %
1836 %    o type: Define the data type of the pixels.  Float and double types are
1837 %      normalized to [0..1] otherwise [0..QuantumRange].  Choose from these
1838 %      types: CharPixel, ShortPixel, IntegerPixel, LongPixel, FloatPixel, or
1839 %      DoublePixel.
1840 %
1841 %    o pixels: This array of values contain the pixel components as defined by
1842 %      map and type.  You must preallocate this array where the expected
1843 %      length varies depending on the values of width, height, map, and type.
1844 %
1845 */
1846 MagickExport MagickBooleanType ImportImagePixels(Image *image,
1847   const ssize_t x_offset,const ssize_t y_offset,const size_t columns,
1848   const size_t rows,const char *map,const StorageType type,
1849   const void *pixels)
1850 {
1851   ExceptionInfo
1852     *exception;
1853
1854   QuantumType
1855     *quantum_map;
1856
1857   register Quantum
1858     *q;
1859
1860   register ssize_t
1861     i,
1862     x;
1863
1864   size_t
1865     length;
1866
1867   ssize_t
1868     y;
1869
1870   /*
1871     Allocate image structure.
1872   */
1873   assert(image != (Image *) NULL);
1874   assert(image->signature == MagickSignature);
1875   if (image->debug != MagickFalse)
1876     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1877   length=strlen(map);
1878   quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
1879   if (quantum_map == (QuantumType *) NULL)
1880     ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1881       image->filename);
1882   for (i=0; i < (ssize_t) length; i++)
1883   {
1884     switch (map[i])
1885     {
1886       case 'a':
1887       case 'A':
1888       {
1889         quantum_map[i]=AlphaQuantum;
1890         image->matte=MagickTrue;
1891         break;
1892       }
1893       case 'B':
1894       case 'b':
1895       {
1896         quantum_map[i]=BlueQuantum;
1897         break;
1898       }
1899       case 'C':
1900       case 'c':
1901       {
1902         quantum_map[i]=CyanQuantum;
1903         (void) SetImageColorspace(image,CMYKColorspace);
1904         break;
1905       }
1906       case 'g':
1907       case 'G':
1908       {
1909         quantum_map[i]=GreenQuantum;
1910         break;
1911       }
1912       case 'K':
1913       case 'k':
1914       {
1915         quantum_map[i]=BlackQuantum;
1916         (void) SetImageColorspace(image,CMYKColorspace);
1917         break;
1918       }
1919       case 'I':
1920       case 'i':
1921       {
1922         quantum_map[i]=IndexQuantum;
1923         break;
1924       }
1925       case 'm':
1926       case 'M':
1927       {
1928         quantum_map[i]=MagentaQuantum;
1929         (void) SetImageColorspace(image,CMYKColorspace);
1930         break;
1931       }
1932       case 'O':
1933       case 'o':
1934       {
1935         quantum_map[i]=OpacityQuantum;
1936         image->matte=MagickTrue;
1937         break;
1938       }
1939       case 'P':
1940       case 'p':
1941       {
1942         quantum_map[i]=UndefinedQuantum;
1943         break;
1944       }
1945       case 'R':
1946       case 'r':
1947       {
1948         quantum_map[i]=RedQuantum;
1949         break;
1950       }
1951       case 'Y':
1952       case 'y':
1953       {
1954         quantum_map[i]=YellowQuantum;
1955         (void) SetImageColorspace(image,CMYKColorspace);
1956         break;
1957       }
1958       default:
1959       {
1960         quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
1961         (void) ThrowMagickException(&image->exception,GetMagickModule(),
1962           OptionError,"UnrecognizedPixelMap","`%s'",map);
1963         return(MagickFalse);
1964       }
1965     }
1966   }
1967   if (SetImageStorageClass(image,DirectClass) == MagickFalse)
1968     return(MagickFalse);
1969   /*
1970     Transfer the pixels from the pixel datarray to the image.
1971   */
1972   exception=(&image->exception);
1973   switch (type)
1974   {
1975     case CharPixel:
1976     {
1977       register const unsigned char
1978         *p;
1979
1980       p=(const unsigned char *) pixels;
1981       if (LocaleCompare(map,"BGR") == 0)
1982         {
1983           for (y=0; y < (ssize_t) rows; y++)
1984           {
1985             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
1986             if (q == (Quantum *) NULL)
1987               break;
1988             for (x=0; x < (ssize_t) columns; x++)
1989             {
1990               SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
1991               SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
1992               SetPixelRed(image,ScaleCharToQuantum(*p++),q);
1993               q+=GetPixelChannels(image);
1994             }
1995             if (SyncAuthenticPixels(image,exception) == MagickFalse)
1996               break;
1997           }
1998           break;
1999         }
2000       if (LocaleCompare(map,"BGRA") == 0)
2001         {
2002           for (y=0; y < (ssize_t) rows; y++)
2003           {
2004             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2005             if (q == (Quantum *) NULL)
2006               break;
2007             for (x=0; x < (ssize_t) columns; x++)
2008             {
2009               SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2010               SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2011               SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2012               SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2013               q+=GetPixelChannels(image);
2014             }
2015             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2016               break;
2017           }
2018           break;
2019         }
2020       if (LocaleCompare(map,"BGRO") == 0)
2021         {
2022           for (y=0; y < (ssize_t) rows; y++)
2023           {
2024             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2025             if (q == (Quantum *) NULL)
2026               break;
2027             for (x=0; x < (ssize_t) columns; x++)
2028             {
2029               SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2030               SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2031               SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2032               SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2033               q+=GetPixelChannels(image);
2034             }
2035             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2036               break;
2037           }
2038           break;
2039         }
2040       if (LocaleCompare(map,"BGRP") == 0)
2041         {
2042           for (y=0; y < (ssize_t) rows; y++)
2043           {
2044             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2045             if (q == (Quantum *) NULL)
2046               break;
2047             for (x=0; x < (ssize_t) columns; x++)
2048             {
2049               SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2050               SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2051               SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2052               p++;
2053               q+=GetPixelChannels(image);
2054             }
2055             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2056               break;
2057           }
2058           break;
2059         }
2060       if (LocaleCompare(map,"I") == 0)
2061         {
2062           for (y=0; y < (ssize_t) rows; y++)
2063           {
2064             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2065             if (q == (Quantum *) NULL)
2066               break;
2067             for (x=0; x < (ssize_t) columns; x++)
2068             {
2069               SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2070               SetPixelGreen(image,GetPixelRed(image,q),q);
2071               SetPixelBlue(image,GetPixelRed(image,q),q);
2072               q+=GetPixelChannels(image);
2073             }
2074             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2075               break;
2076           }
2077           break;
2078         }
2079       if (LocaleCompare(map,"RGB") == 0)
2080         {
2081           for (y=0; y < (ssize_t) rows; y++)
2082           {
2083             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2084             if (q == (Quantum *) NULL)
2085               break;
2086             for (x=0; x < (ssize_t) columns; x++)
2087             {
2088               SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2089               SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2090               SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2091               q+=GetPixelChannels(image);
2092             }
2093             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2094               break;
2095           }
2096           break;
2097         }
2098       if (LocaleCompare(map,"RGBA") == 0)
2099         {
2100           for (y=0; y < (ssize_t) rows; y++)
2101           {
2102             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2103             if (q == (Quantum *) NULL)
2104               break;
2105             for (x=0; x < (ssize_t) columns; x++)
2106             {
2107               SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2108               SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2109               SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2110               SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2111               q+=GetPixelChannels(image);
2112             }
2113             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2114               break;
2115           }
2116           break;
2117         }
2118       if (LocaleCompare(map,"RGBO") == 0)
2119         {
2120           for (y=0; y < (ssize_t) rows; y++)
2121           {
2122             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2123             if (q == (Quantum *) NULL)
2124               break;
2125             for (x=0; x < (ssize_t) columns; x++)
2126             {
2127               SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2128               SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2129               SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2130               SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2131               q+=GetPixelChannels(image);
2132             }
2133             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2134               break;
2135           }
2136           break;
2137         }
2138       if (LocaleCompare(map,"RGBP") == 0)
2139         {
2140           for (y=0; y < (ssize_t) rows; y++)
2141           {
2142             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2143             if (q == (Quantum *) NULL)
2144               break;
2145             for (x=0; x < (ssize_t) columns; x++)
2146             {
2147               SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2148               SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2149               SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2150               p++;
2151               q+=GetPixelChannels(image);
2152             }
2153             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2154               break;
2155           }
2156           break;
2157         }
2158       for (y=0; y < (ssize_t) rows; y++)
2159       {
2160         q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2161         if (q == (Quantum *) NULL)
2162           break;
2163         for (x=0; x < (ssize_t) columns; x++)
2164         {
2165           for (i=0; i < (ssize_t) length; i++)
2166           {
2167             switch (quantum_map[i])
2168             {
2169               case RedQuantum:
2170               case CyanQuantum:
2171               {
2172                 SetPixelRed(image,ScaleCharToQuantum(*p),q);
2173                 break;
2174               }
2175               case GreenQuantum:
2176               case MagentaQuantum:
2177               {
2178                 SetPixelGreen(image,ScaleCharToQuantum(*p),q);
2179                 break;
2180               }
2181               case BlueQuantum:
2182               case YellowQuantum:
2183               {
2184                 SetPixelBlue(image,ScaleCharToQuantum(*p),q);
2185                 break;
2186               }
2187               case AlphaQuantum:
2188               {
2189                 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2190                 break;
2191               }
2192               case OpacityQuantum:
2193               {
2194                 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2195                 break;
2196               }
2197               case BlackQuantum:
2198               {
2199                 SetPixelBlack(image,ScaleCharToQuantum(*p),q);
2200                 break;
2201               }
2202               case IndexQuantum:
2203               {
2204                 SetPixelRed(image,ScaleCharToQuantum(*p),q);
2205                 SetPixelGreen(image,GetPixelRed(image,q),q);
2206                 SetPixelBlue(image,GetPixelRed(image,q),q);
2207                 break;
2208               }
2209               default:
2210                 break;
2211             }
2212             p++;
2213           }
2214           q+=GetPixelChannels(image);
2215         }
2216         if (SyncAuthenticPixels(image,exception) == MagickFalse)
2217           break;
2218       }
2219       break;
2220     }
2221     case DoublePixel:
2222     {
2223       register const double
2224         *p;
2225
2226       p=(const double *) pixels;
2227       if (LocaleCompare(map,"BGR") == 0)
2228         {
2229           for (y=0; y < (ssize_t) rows; y++)
2230           {
2231             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2232             if (q == (Quantum *) NULL)
2233               break;
2234             for (x=0; x < (ssize_t) columns; x++)
2235             {
2236               SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2237                 (*p)),q);
2238               p++;
2239               SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2240                 (*p)),q);
2241               p++;
2242               SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2243                 (*p)),q);
2244               p++;
2245               q+=GetPixelChannels(image);
2246             }
2247             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2248               break;
2249           }
2250           break;
2251         }
2252       if (LocaleCompare(map,"BGRA") == 0)
2253         {
2254           for (y=0; y < (ssize_t) rows; y++)
2255           {
2256             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2257             if (q == (Quantum *) NULL)
2258               break;
2259             for (x=0; x < (ssize_t) columns; x++)
2260             {
2261               SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2262                 (*p)),q);
2263               p++;
2264               SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2265                 (*p)),q);
2266               p++;
2267               SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2268                 (*p)),q);
2269               p++;
2270               SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2271                 (*p)),q);
2272               p++;
2273               q+=GetPixelChannels(image);
2274             }
2275             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2276               break;
2277           }
2278           break;
2279         }
2280       if (LocaleCompare(map,"BGRP") == 0)
2281         {
2282           for (y=0; y < (ssize_t) rows; y++)
2283           {
2284             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2285             if (q == (Quantum *) NULL)
2286               break;
2287             for (x=0; x < (ssize_t) columns; x++)
2288             {
2289               SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2290                 (*p)),q);
2291               p++;
2292               SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2293                 (*p)),q);
2294               p++;
2295               SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2296                 (*p)),q);
2297               p++;
2298               p++;
2299               q+=GetPixelChannels(image);
2300             }
2301             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2302               break;
2303           }
2304           break;
2305         }
2306       if (LocaleCompare(map,"I") == 0)
2307         {
2308           for (y=0; y < (ssize_t) rows; y++)
2309           {
2310             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2311             if (q == (Quantum *) NULL)
2312               break;
2313             for (x=0; x < (ssize_t) columns; x++)
2314             {
2315               SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2316                 (*p)),q);
2317               SetPixelGreen(image,GetPixelRed(image,q),q);
2318               SetPixelBlue(image,GetPixelRed(image,q),q);
2319               p++;
2320               q+=GetPixelChannels(image);
2321             }
2322             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2323               break;
2324           }
2325           break;
2326         }
2327       if (LocaleCompare(map,"RGB") == 0)
2328         {
2329           for (y=0; y < (ssize_t) rows; y++)
2330           {
2331             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2332             if (q == (Quantum *) NULL)
2333               break;
2334             for (x=0; x < (ssize_t) columns; x++)
2335             {
2336               SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2337                 (*p)),q);
2338               p++;
2339               SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2340                 (*p)),q);
2341               p++;
2342               SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2343                 (*p)),q);
2344               p++;
2345               q+=GetPixelChannels(image);
2346             }
2347             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2348               break;
2349           }
2350           break;
2351         }
2352       if (LocaleCompare(map,"RGBA") == 0)
2353         {
2354           for (y=0; y < (ssize_t) rows; y++)
2355           {
2356             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2357             if (q == (Quantum *) NULL)
2358               break;
2359             for (x=0; x < (ssize_t) columns; x++)
2360             {
2361               SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2362                 (*p)),q);
2363               p++;
2364               SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2365                 (*p)),q);
2366               p++;
2367               SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2368                 (*p)),q);
2369               p++;
2370               SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2371                 (*p)),q);
2372               p++;
2373               q+=GetPixelChannels(image);
2374             }
2375             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2376               break;
2377           }
2378           break;
2379         }
2380       if (LocaleCompare(map,"RGBP") == 0)
2381         {
2382           for (y=0; y < (ssize_t) rows; y++)
2383           {
2384             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2385             if (q == (Quantum *) NULL)
2386               break;
2387             for (x=0; x < (ssize_t) columns; x++)
2388             {
2389               SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2390                 (*p)),q);
2391               p++;
2392               SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2393                 (*p)),q);
2394               p++;
2395               SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2396                 (*p)),q);
2397               p++;
2398               q+=GetPixelChannels(image);
2399             }
2400             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2401               break;
2402           }
2403           break;
2404         }
2405       for (y=0; y < (ssize_t) rows; y++)
2406       {
2407         q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2408         if (q == (Quantum *) NULL)
2409           break;
2410         for (x=0; x < (ssize_t) columns; x++)
2411         {
2412           for (i=0; i < (ssize_t) length; i++)
2413           {
2414             switch (quantum_map[i])
2415             {
2416               case RedQuantum:
2417               case CyanQuantum:
2418               {
2419                 SetPixelRed(image,ClampToQuantum((MagickRealType)
2420                   QuantumRange*(*p)),q);
2421                 break;
2422               }
2423               case GreenQuantum:
2424               case MagentaQuantum:
2425               {
2426                 SetPixelGreen(image,ClampToQuantum((MagickRealType)
2427                   QuantumRange*(*p)),q);
2428                 break;
2429               }
2430               case BlueQuantum:
2431               case YellowQuantum:
2432               {
2433                 SetPixelBlue(image,ClampToQuantum((MagickRealType)
2434                   QuantumRange*(*p)),q);
2435                 break;
2436               }
2437               case AlphaQuantum:
2438               {
2439                 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2440                   QuantumRange*(*p)),q);
2441                 break;
2442               }
2443               case OpacityQuantum:
2444               {
2445                 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2446                   QuantumRange*(*p)),q);
2447                 break;
2448               }
2449               case BlackQuantum:
2450               {
2451                 SetPixelBlack(image,ClampToQuantum((MagickRealType)
2452                   QuantumRange*(*p)),q);
2453                 break;
2454               }
2455               case IndexQuantum:
2456               {
2457                 SetPixelRed(image,ClampToQuantum((MagickRealType)
2458                   QuantumRange*(*p)),q);
2459                 SetPixelGreen(image,GetPixelRed(image,q),q);
2460                 SetPixelBlue(image,GetPixelRed(image,q),q);
2461                 break;
2462               }
2463               default:
2464                 break;
2465             }
2466             p++;
2467           }
2468           q+=GetPixelChannels(image);
2469         }
2470         if (SyncAuthenticPixels(image,exception) == MagickFalse)
2471           break;
2472       }
2473       break;
2474     }
2475     case FloatPixel:
2476     {
2477       register const float
2478         *p;
2479
2480       p=(const float *) pixels;
2481       if (LocaleCompare(map,"BGR") == 0)
2482         {
2483           for (y=0; y < (ssize_t) rows; y++)
2484           {
2485             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2486             if (q == (Quantum *) NULL)
2487               break;
2488             for (x=0; x < (ssize_t) columns; x++)
2489             {
2490               SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2491                 (*p)),q);
2492               p++;
2493               SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2494                 (*p)),q);
2495               p++;
2496               SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2497                 (*p)),q);
2498               p++;
2499               q+=GetPixelChannels(image);
2500             }
2501             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2502               break;
2503           }
2504           break;
2505         }
2506       if (LocaleCompare(map,"BGRA") == 0)
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               SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2516                 (*p)),q);
2517               p++;
2518               SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2519                 (*p)),q);
2520               p++;
2521               SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2522                 (*p)),q);
2523               p++;
2524               SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2525                 (*p)),q);
2526               p++;
2527               q+=GetPixelChannels(image);
2528             }
2529             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2530               break;
2531           }
2532           break;
2533         }
2534       if (LocaleCompare(map,"BGRP") == 0)
2535         {
2536           for (y=0; y < (ssize_t) rows; y++)
2537           {
2538             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2539             if (q == (Quantum *) NULL)
2540               break;
2541             for (x=0; x < (ssize_t) columns; x++)
2542             {
2543               SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2544                 (*p)),q);
2545               p++;
2546               SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2547                 (*p)),q);
2548               p++;
2549               SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2550                 (*p)),q);
2551               p++;
2552               p++;
2553               q+=GetPixelChannels(image);
2554             }
2555             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2556               break;
2557           }
2558           break;
2559         }
2560       if (LocaleCompare(map,"I") == 0)
2561         {
2562           for (y=0; y < (ssize_t) rows; y++)
2563           {
2564             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2565             if (q == (Quantum *) NULL)
2566               break;
2567             for (x=0; x < (ssize_t) columns; x++)
2568             {
2569               SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2570                 (*p)),q);
2571               SetPixelGreen(image,GetPixelRed(image,q),q);
2572               SetPixelBlue(image,GetPixelRed(image,q),q);
2573               p++;
2574               q+=GetPixelChannels(image);
2575             }
2576             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2577               break;
2578           }
2579           break;
2580         }
2581       if (LocaleCompare(map,"RGB") == 0)
2582         {
2583           for (y=0; y < (ssize_t) rows; y++)
2584           {
2585             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2586             if (q == (Quantum *) NULL)
2587               break;
2588             for (x=0; x < (ssize_t) columns; x++)
2589             {
2590               SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2591                 (*p)),q);
2592               p++;
2593               SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2594                 (*p)),q);
2595               p++;
2596               SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2597                 (*p)),q);
2598               p++;
2599               q+=GetPixelChannels(image);
2600             }
2601             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2602               break;
2603           }
2604           break;
2605         }
2606       if (LocaleCompare(map,"RGBA") == 0)
2607         {
2608           for (y=0; y < (ssize_t) rows; y++)
2609           {
2610             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2611             if (q == (Quantum *) NULL)
2612               break;
2613             for (x=0; x < (ssize_t) columns; x++)
2614             {
2615               SetPixelRed(image,ClampToQuantum((MagickRealType)
2616                 QuantumRange*(*p)),q);
2617               p++;
2618               SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2619                 (*p)),q);
2620               p++;
2621               SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2622                 (*p)),q);
2623               p++;
2624               SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange*
2625                 (*p)),q);
2626               p++;
2627               q+=GetPixelChannels(image);
2628             }
2629             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2630               break;
2631           }
2632           break;
2633         }
2634       if (LocaleCompare(map,"RGBP") == 0)
2635         {
2636           for (y=0; y < (ssize_t) rows; y++)
2637           {
2638             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2639             if (q == (Quantum *) NULL)
2640               break;
2641             for (x=0; x < (ssize_t) columns; x++)
2642             {
2643               SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange*
2644                 (*p)),q);
2645               p++;
2646               SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange*
2647                 (*p)),q);
2648               p++;
2649               SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange*
2650                 (*p)),q);
2651               p++;
2652               q+=GetPixelChannels(image);
2653             }
2654             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2655               break;
2656           }
2657           break;
2658         }
2659       for (y=0; y < (ssize_t) rows; y++)
2660       {
2661         q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2662         if (q == (Quantum *) NULL)
2663           break;
2664         for (x=0; x < (ssize_t) columns; x++)
2665         {
2666           for (i=0; i < (ssize_t) length; i++)
2667           {
2668             switch (quantum_map[i])
2669             {
2670               case RedQuantum:
2671               case CyanQuantum:
2672               {
2673                 SetPixelRed(image,ClampToQuantum((MagickRealType)
2674                   QuantumRange*(*p)),q);
2675                 break;
2676               }
2677               case GreenQuantum:
2678               case MagentaQuantum:
2679               {
2680                 SetPixelGreen(image,ClampToQuantum((MagickRealType)
2681                   QuantumRange*(*p)),q);
2682                 break;
2683               }
2684               case BlueQuantum:
2685               case YellowQuantum:
2686               {
2687                 SetPixelBlue(image,ClampToQuantum((MagickRealType)
2688                   QuantumRange*(*p)),q);
2689                 break;
2690               }
2691               case AlphaQuantum:
2692               {
2693                 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2694                   QuantumRange*(*p)),q);
2695                 break;
2696               }
2697               case OpacityQuantum:
2698               {
2699                 SetPixelAlpha(image,ClampToQuantum((MagickRealType)
2700                   QuantumRange*(*p)),q);
2701                 break;
2702               }
2703               case BlackQuantum:
2704               {
2705                 SetPixelBlack(image,ClampToQuantum((MagickRealType)
2706                   QuantumRange*(*p)),q);
2707                 break;
2708               }
2709               case IndexQuantum:
2710               {
2711                 SetPixelRed(image,ClampToQuantum((MagickRealType)
2712                   QuantumRange*(*p)),q);
2713                 SetPixelGreen(image,GetPixelRed(image,q),q);
2714                 SetPixelBlue(image,GetPixelRed(image,q),q);
2715                 break;
2716               }
2717               default:
2718                 break;
2719             }
2720             p++;
2721           }
2722           q+=GetPixelChannels(image);
2723         }
2724         if (SyncAuthenticPixels(image,exception) == MagickFalse)
2725           break;
2726       }
2727       break;
2728     }
2729     case IntegerPixel:
2730     {
2731       register const unsigned int
2732         *p;
2733
2734       p=(const unsigned int *) pixels;
2735       if (LocaleCompare(map,"BGR") == 0)
2736         {
2737           for (y=0; y < (ssize_t) rows; y++)
2738           {
2739             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2740             if (q == (Quantum *) NULL)
2741               break;
2742             for (x=0; x < (ssize_t) columns; x++)
2743             {
2744               SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2745               SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2746               SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2747               q+=GetPixelChannels(image);
2748             }
2749             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2750               break;
2751           }
2752           break;
2753         }
2754       if (LocaleCompare(map,"BGRA") == 0)
2755         {
2756           for (y=0; y < (ssize_t) rows; y++)
2757           {
2758             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2759             if (q == (Quantum *) NULL)
2760               break;
2761             for (x=0; x < (ssize_t) columns; x++)
2762             {
2763               SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2764               SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2765               SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2766               SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
2767               q+=GetPixelChannels(image);
2768             }
2769             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2770               break;
2771           }
2772           break;
2773         }
2774       if (LocaleCompare(map,"BGRP") == 0)
2775         {
2776           for (y=0; y < (ssize_t) rows; y++)
2777           {
2778             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2779             if (q == (Quantum *) NULL)
2780               break;
2781             for (x=0; x < (ssize_t) columns; x++)
2782             {
2783               SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2784               SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2785               SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2786               p++;
2787               q+=GetPixelChannels(image);
2788             }
2789             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2790               break;
2791           }
2792           break;
2793         }
2794       if (LocaleCompare(map,"I") == 0)
2795         {
2796           for (y=0; y < (ssize_t) rows; y++)
2797           {
2798             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2799             if (q == (Quantum *) NULL)
2800               break;
2801             for (x=0; x < (ssize_t) columns; x++)
2802             {
2803               SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2804               SetPixelGreen(image,GetPixelRed(image,q),q);
2805               SetPixelBlue(image,GetPixelRed(image,q),q);
2806               q+=GetPixelChannels(image);
2807             }
2808             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2809               break;
2810           }
2811           break;
2812         }
2813       if (LocaleCompare(map,"RGB") == 0)
2814         {
2815           for (y=0; y < (ssize_t) rows; y++)
2816           {
2817             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2818             if (q == (Quantum *) NULL)
2819               break;
2820             for (x=0; x < (ssize_t) columns; x++)
2821             {
2822               SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2823               SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2824               SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2825               q+=GetPixelChannels(image);
2826             }
2827             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2828               break;
2829           }
2830           break;
2831         }
2832       if (LocaleCompare(map,"RGBA") == 0)
2833         {
2834           for (y=0; y < (ssize_t) rows; y++)
2835           {
2836             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2837             if (q == (Quantum *) NULL)
2838               break;
2839             for (x=0; x < (ssize_t) columns; x++)
2840             {
2841               SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2842               SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2843               SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2844               SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
2845               q+=GetPixelChannels(image);
2846             }
2847             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2848               break;
2849           }
2850           break;
2851         }
2852       if (LocaleCompare(map,"RGBP") == 0)
2853         {
2854           for (y=0; y < (ssize_t) rows; y++)
2855           {
2856             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2857             if (q == (Quantum *) NULL)
2858               break;
2859             for (x=0; x < (ssize_t) columns; x++)
2860             {
2861               SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2862               SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2863               SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2864               p++;
2865               q+=GetPixelChannels(image);
2866             }
2867             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2868               break;
2869           }
2870           break;
2871         }
2872       for (y=0; y < (ssize_t) rows; y++)
2873       {
2874         q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2875         if (q == (Quantum *) NULL)
2876           break;
2877         for (x=0; x < (ssize_t) columns; x++)
2878         {
2879           for (i=0; i < (ssize_t) length; i++)
2880           {
2881             switch (quantum_map[i])
2882             {
2883               case RedQuantum:
2884               case CyanQuantum:
2885               {
2886                 SetPixelRed(image,ScaleLongToQuantum(*p),q);
2887                 break;
2888               }
2889               case GreenQuantum:
2890               case MagentaQuantum:
2891               {
2892                 SetPixelGreen(image,ScaleLongToQuantum(*p),q);
2893                 break;
2894               }
2895               case BlueQuantum:
2896               case YellowQuantum:
2897               {
2898                 SetPixelBlue(image,ScaleLongToQuantum(*p),q);
2899                 break;
2900               }
2901               case AlphaQuantum:
2902               {
2903                 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
2904                 break;
2905               }
2906               case OpacityQuantum:
2907               {
2908                 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
2909                 break;
2910               }
2911               case BlackQuantum:
2912               {
2913                 SetPixelBlack(image,ScaleLongToQuantum(*p),q);
2914                 break;
2915               }
2916               case IndexQuantum:
2917               {
2918                 SetPixelRed(image,ScaleLongToQuantum(*p),q);
2919                 SetPixelGreen(image,GetPixelRed(image,q),q);
2920                 SetPixelBlue(image,GetPixelRed(image,q),q);
2921                 break;
2922               }
2923               default:
2924                 break;
2925             }
2926             p++;
2927           }
2928           q+=GetPixelChannels(image);
2929         }
2930         if (SyncAuthenticPixels(image,exception) == MagickFalse)
2931           break;
2932       }
2933       break;
2934     }
2935     case LongPixel:
2936     {
2937       register const unsigned int
2938         *p;
2939
2940       p=(const unsigned int *) pixels;
2941       if (LocaleCompare(map,"BGR") == 0)
2942         {
2943           for (y=0; y < (ssize_t) rows; y++)
2944           {
2945             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2946             if (q == (Quantum *) NULL)
2947               break;
2948             for (x=0; x < (ssize_t) columns; x++)
2949             {
2950               SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2951               SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2952               SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2953               q+=GetPixelChannels(image);
2954             }
2955             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2956               break;
2957           }
2958           break;
2959         }
2960       if (LocaleCompare(map,"BGRA") == 0)
2961         {
2962           for (y=0; y < (ssize_t) rows; y++)
2963           {
2964             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2965             if (q == (Quantum *) NULL)
2966               break;
2967             for (x=0; x < (ssize_t) columns; x++)
2968             {
2969               SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2970               SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2971               SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2972               SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
2973               q+=GetPixelChannels(image);
2974             }
2975             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2976               break;
2977           }
2978           break;
2979         }
2980       if (LocaleCompare(map,"BGRP") == 0)
2981         {
2982           for (y=0; y < (ssize_t) rows; y++)
2983           {
2984             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
2985             if (q == (Quantum *) NULL)
2986               break;
2987             for (x=0; x < (ssize_t) columns; x++)
2988             {
2989               SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
2990               SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
2991               SetPixelRed(image,ScaleLongToQuantum(*p++),q);
2992               p++;
2993               q+=GetPixelChannels(image);
2994             }
2995             if (SyncAuthenticPixels(image,exception) == MagickFalse)
2996               break;
2997           }
2998           break;
2999         }
3000       if (LocaleCompare(map,"I") == 0)
3001         {
3002           for (y=0; y < (ssize_t) rows; y++)
3003           {
3004             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3005             if (q == (Quantum *) NULL)
3006               break;
3007             for (x=0; x < (ssize_t) columns; x++)
3008             {
3009               SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3010               SetPixelGreen(image,GetPixelRed(image,q),q);
3011               SetPixelBlue(image,GetPixelRed(image,q),q);
3012               q+=GetPixelChannels(image);
3013             }
3014             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3015               break;
3016           }
3017           break;
3018         }
3019       if (LocaleCompare(map,"RGB") == 0)
3020         {
3021           for (y=0; y < (ssize_t) rows; y++)
3022           {
3023             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3024             if (q == (Quantum *) NULL)
3025               break;
3026             for (x=0; x < (ssize_t) columns; x++)
3027             {
3028               SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3029               SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3030               SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3031               q+=GetPixelChannels(image);
3032             }
3033             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3034               break;
3035           }
3036           break;
3037         }
3038       if (LocaleCompare(map,"RGBA") == 0)
3039         {
3040           for (y=0; y < (ssize_t) rows; y++)
3041           {
3042             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3043             if (q == (Quantum *) NULL)
3044               break;
3045             for (x=0; x < (ssize_t) columns; x++)
3046             {
3047               SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3048               SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3049               SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3050               SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
3051               q+=GetPixelChannels(image);
3052             }
3053             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3054               break;
3055           }
3056           break;
3057         }
3058       if (LocaleCompare(map,"RGBP") == 0)
3059         {
3060           for (y=0; y < (ssize_t) rows; y++)
3061           {
3062             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3063             if (q == (Quantum *) NULL)
3064               break;
3065             for (x=0; x < (ssize_t) columns; x++)
3066             {
3067               SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3068               SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3069               SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3070               p++;
3071               q+=GetPixelChannels(image);
3072             }
3073             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3074               break;
3075           }
3076           break;
3077         }
3078       for (y=0; y < (ssize_t) rows; y++)
3079       {
3080         q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3081         if (q == (Quantum *) NULL)
3082           break;
3083         for (x=0; x < (ssize_t) columns; x++)
3084         {
3085           for (i=0; i < (ssize_t) length; i++)
3086           {
3087             switch (quantum_map[i])
3088             {
3089               case RedQuantum:
3090               case CyanQuantum:
3091               {
3092                 SetPixelRed(image,ScaleLongToQuantum(*p),q);
3093                 break;
3094               }
3095               case GreenQuantum:
3096               case MagentaQuantum:
3097               {
3098                 SetPixelGreen(image,ScaleLongToQuantum(*p),q);
3099                 break;
3100               }
3101               case BlueQuantum:
3102               case YellowQuantum:
3103               {
3104                 SetPixelBlue(image,ScaleLongToQuantum(*p),q);
3105                 break;
3106               }
3107               case AlphaQuantum:
3108               {
3109                 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3110                 break;
3111               }
3112               case OpacityQuantum:
3113               {
3114                 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3115                 break;
3116               }
3117               case BlackQuantum:
3118               {
3119                 SetPixelBlack(image,ScaleLongToQuantum(*p),q);
3120                 break;
3121               }
3122               case IndexQuantum:
3123               {
3124                 SetPixelRed(image,ScaleLongToQuantum(*p),q);
3125                 SetPixelGreen(image,GetPixelRed(image,q),q);
3126                 SetPixelBlue(image,GetPixelRed(image,q),q);
3127                 break;
3128               }
3129               default:
3130                 break;
3131             }
3132             p++;
3133           }
3134           q+=GetPixelChannels(image);
3135         }
3136         if (SyncAuthenticPixels(image,exception) == MagickFalse)
3137           break;
3138       }
3139       break;
3140     }
3141     case QuantumPixel:
3142     {
3143       register const Quantum
3144         *p;
3145
3146       p=(const Quantum *) pixels;
3147       if (LocaleCompare(map,"BGR") == 0)
3148         {
3149           for (y=0; y < (ssize_t) rows; y++)
3150           {
3151             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3152             if (q == (Quantum *) NULL)
3153               break;
3154             for (x=0; x < (ssize_t) columns; x++)
3155             {
3156               SetPixelBlue(image,*p++,q);
3157               SetPixelGreen(image,*p++,q);
3158               SetPixelRed(image,*p++,q);
3159               q+=GetPixelChannels(image);
3160             }
3161             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3162               break;
3163           }
3164           break;
3165         }
3166       if (LocaleCompare(map,"BGRA") == 0)
3167         {
3168           for (y=0; y < (ssize_t) rows; y++)
3169           {
3170             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3171             if (q == (Quantum *) NULL)
3172               break;
3173             for (x=0; x < (ssize_t) columns; x++)
3174             {
3175               SetPixelBlue(image,*p++,q);
3176               SetPixelGreen(image,*p++,q);
3177               SetPixelRed(image,*p++,q);
3178               SetPixelAlpha(image,*p++,q);
3179               q+=GetPixelChannels(image);
3180             }
3181             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3182               break;
3183           }
3184           break;
3185         }
3186       if (LocaleCompare(map,"BGRP") == 0)
3187         {
3188           for (y=0; y < (ssize_t) rows; y++)
3189           {
3190             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3191             if (q == (Quantum *) NULL)
3192               break;
3193             for (x=0; x < (ssize_t) columns; x++)
3194             {
3195               SetPixelBlue(image,*p++,q);
3196               SetPixelGreen(image,*p++,q);
3197               SetPixelRed(image,*p++,q);
3198               p++;
3199               q+=GetPixelChannels(image);
3200             }
3201             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3202               break;
3203           }
3204           break;
3205         }
3206       if (LocaleCompare(map,"I") == 0)
3207         {
3208           for (y=0; y < (ssize_t) rows; y++)
3209           {
3210             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3211             if (q == (Quantum *) NULL)
3212               break;
3213             for (x=0; x < (ssize_t) columns; x++)
3214             {
3215               SetPixelRed(image,*p++,q);
3216               SetPixelGreen(image,GetPixelRed(image,q),q);
3217               SetPixelBlue(image,GetPixelRed(image,q),q);
3218               q+=GetPixelChannels(image);
3219             }
3220             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3221               break;
3222           }
3223           break;
3224         }
3225       if (LocaleCompare(map,"RGB") == 0)
3226         {
3227           for (y=0; y < (ssize_t) rows; y++)
3228           {
3229             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3230             if (q == (Quantum *) NULL)
3231               break;
3232             for (x=0; x < (ssize_t) columns; x++)
3233             {
3234               SetPixelRed(image,*p++,q);
3235               SetPixelGreen(image,*p++,q);
3236               SetPixelBlue(image,*p++,q);
3237               q+=GetPixelChannels(image);
3238             }
3239             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3240               break;
3241           }
3242           break;
3243         }
3244       if (LocaleCompare(map,"RGBA") == 0)
3245         {
3246           for (y=0; y < (ssize_t) rows; y++)
3247           {
3248             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3249             if (q == (Quantum *) NULL)
3250               break;
3251             for (x=0; x < (ssize_t) columns; x++)
3252             {
3253               SetPixelRed(image,*p++,q);
3254               SetPixelGreen(image,*p++,q);
3255               SetPixelBlue(image,*p++,q);
3256               SetPixelAlpha(image,*p++,q);
3257               q+=GetPixelChannels(image);
3258             }
3259             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3260               break;
3261           }
3262           break;
3263         }
3264       if (LocaleCompare(map,"RGBP") == 0)
3265         {
3266           for (y=0; y < (ssize_t) rows; y++)
3267           {
3268             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3269             if (q == (Quantum *) NULL)
3270               break;
3271             for (x=0; x < (ssize_t) columns; x++)
3272             {
3273               SetPixelRed(image,*p++,q);
3274               SetPixelGreen(image,*p++,q);
3275               SetPixelBlue(image,*p++,q);
3276               p++;
3277               q+=GetPixelChannels(image);
3278             }
3279             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3280               break;
3281           }
3282           break;
3283         }
3284       for (y=0; y < (ssize_t) rows; y++)
3285       {
3286         q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3287         if (q == (Quantum *) NULL)
3288           break;
3289         for (x=0; x < (ssize_t) columns; x++)
3290         {
3291           for (i=0; i < (ssize_t) length; i++)
3292           {
3293             switch (quantum_map[i])
3294             {
3295               case RedQuantum:
3296               case CyanQuantum:
3297               {
3298                 SetPixelRed(image,*p,q);
3299                 break;
3300               }
3301               case GreenQuantum:
3302               case MagentaQuantum:
3303               {
3304                 SetPixelGreen(image,*p,q);
3305                 break;
3306               }
3307               case BlueQuantum:
3308               case YellowQuantum:
3309               {
3310                 SetPixelBlue(image,*p,q);
3311                 break;
3312               }
3313               case AlphaQuantum:
3314               {
3315                 SetPixelAlpha(image,*p,q);
3316                 break;
3317               }
3318               case OpacityQuantum:
3319               {
3320                 SetPixelAlpha(image,*p,q);
3321                 break;
3322               }
3323               case BlackQuantum:
3324               {
3325                 SetPixelBlack(image,*p,q);
3326                 break;
3327               }
3328               case IndexQuantum:
3329               {
3330                 SetPixelRed(image,*p,q);
3331                 SetPixelGreen(image,GetPixelRed(image,q),q);
3332                 SetPixelBlue(image,GetPixelRed(image,q),q);
3333                 break;
3334               }
3335               default:
3336                 break;
3337             }
3338             p++;
3339           }
3340           q+=GetPixelChannels(image);
3341         }
3342         if (SyncAuthenticPixels(image,exception) == MagickFalse)
3343           break;
3344       }
3345       break;
3346     }
3347     case ShortPixel:
3348     {
3349       register const unsigned short
3350         *p;
3351
3352       p=(const unsigned short *) pixels;
3353       if (LocaleCompare(map,"BGR") == 0)
3354         {
3355           for (y=0; y < (ssize_t) rows; y++)
3356           {
3357             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3358             if (q == (Quantum *) NULL)
3359               break;
3360             for (x=0; x < (ssize_t) columns; x++)
3361             {
3362               SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3363               SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3364               SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3365               q+=GetPixelChannels(image);
3366             }
3367             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3368               break;
3369           }
3370           break;
3371         }
3372       if (LocaleCompare(map,"BGRA") == 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               SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3382               SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3383               SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3384               SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3385               q+=GetPixelChannels(image);
3386             }
3387             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3388               break;
3389           }
3390           break;
3391         }
3392       if (LocaleCompare(map,"BGRP") == 0)
3393         {
3394           for (y=0; y < (ssize_t) rows; y++)
3395           {
3396             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3397             if (q == (Quantum *) NULL)
3398               break;
3399             for (x=0; x < (ssize_t) columns; x++)
3400             {
3401               SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3402               SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3403               SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3404               p++;
3405               q+=GetPixelChannels(image);
3406             }
3407             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3408               break;
3409           }
3410           break;
3411         }
3412       if (LocaleCompare(map,"I") == 0)
3413         {
3414           for (y=0; y < (ssize_t) rows; y++)
3415           {
3416             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3417             if (q == (Quantum *) NULL)
3418               break;
3419             for (x=0; x < (ssize_t) columns; x++)
3420             {
3421               SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3422               SetPixelGreen(image,GetPixelRed(image,q),q);
3423               SetPixelBlue(image,GetPixelRed(image,q),q);
3424               q+=GetPixelChannels(image);
3425             }
3426             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3427               break;
3428           }
3429           break;
3430         }
3431       if (LocaleCompare(map,"RGB") == 0)
3432         {
3433           for (y=0; y < (ssize_t) rows; y++)
3434           {
3435             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3436             if (q == (Quantum *) NULL)
3437               break;
3438             for (x=0; x < (ssize_t) columns; x++)
3439             {
3440               SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3441               SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3442               SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3443               q+=GetPixelChannels(image);
3444             }
3445             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3446               break;
3447           }
3448           break;
3449         }
3450       if (LocaleCompare(map,"RGBA") == 0)
3451         {
3452           for (y=0; y < (ssize_t) rows; y++)
3453           {
3454             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3455             if (q == (Quantum *) NULL)
3456               break;
3457             for (x=0; x < (ssize_t) columns; x++)
3458             {
3459               SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3460               SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3461               SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3462               SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3463               q+=GetPixelChannels(image);
3464             }
3465             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3466               break;
3467           }
3468           break;
3469         }
3470       if (LocaleCompare(map,"RGBP") == 0)
3471         {
3472           for (y=0; y < (ssize_t) rows; y++)
3473           {
3474             q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3475             if (q == (Quantum *) NULL)
3476               break;
3477             for (x=0; x < (ssize_t) columns; x++)
3478             {
3479               SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3480               SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3481               SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3482               p++;
3483               q+=GetPixelChannels(image);
3484             }
3485             if (SyncAuthenticPixels(image,exception) == MagickFalse)
3486               break;
3487           }
3488           break;
3489         }
3490       for (y=0; y < (ssize_t) rows; y++)
3491       {
3492         q=GetAuthenticPixels(image,x_offset,y_offset+y,columns,1,exception);
3493         if (q == (Quantum *) NULL)
3494           break;
3495         for (x=0; x < (ssize_t) columns; x++)
3496         {
3497           for (i=0; i < (ssize_t) length; i++)
3498           {
3499             switch (quantum_map[i])
3500             {
3501               case RedQuantum:
3502               case CyanQuantum:
3503               {
3504                 SetPixelRed(image,ScaleShortToQuantum(*p),q);
3505                 break;
3506               }
3507               case GreenQuantum:
3508               case MagentaQuantum:
3509               {
3510                 SetPixelGreen(image,ScaleShortToQuantum(*p),q);
3511                 break;
3512               }
3513               case BlueQuantum:
3514               case YellowQuantum:
3515               {
3516                 SetPixelBlue(image,ScaleShortToQuantum(*p),q);
3517                 break;
3518               }
3519               case AlphaQuantum:
3520               {
3521                 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
3522                 break;
3523               }
3524               case OpacityQuantum:
3525               {
3526                 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
3527                 break;
3528               }
3529               case BlackQuantum:
3530               {
3531                 SetPixelBlack(image,ScaleShortToQuantum(*p),q);
3532                 break;
3533               }
3534               case IndexQuantum:
3535               {
3536                 SetPixelRed(image,ScaleShortToQuantum(*p),q);
3537                 SetPixelGreen(image,GetPixelRed(image,q),q);
3538                 SetPixelBlue(image,GetPixelRed(image,q),q);
3539                 break;
3540               }
3541               default:
3542                 break;
3543             }
3544             p++;
3545           }
3546           q+=GetPixelChannels(image);
3547         }
3548         if (SyncAuthenticPixels(image,exception) == MagickFalse)
3549           break;
3550       }
3551       break;
3552     }
3553     default:
3554     {
3555       quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
3556       (void) ThrowMagickException(&image->exception,GetMagickModule(),
3557         OptionError,"UnrecognizedPixelMap","`%s'",map);
3558       break;
3559     }
3560   }
3561   quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
3562   return(MagickTrue);
3563 }
3564 \f
3565 /*
3566 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3567 %                                                                             %
3568 %                                                                             %
3569 %                                                                             %
3570 %   I n t e r p o l a t e P i x e l C h a n n e l                             %
3571 %                                                                             %
3572 %                                                                             %
3573 %                                                                             %
3574 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3575 %
3576 %  InterpolatePixelChannel() applies a pixel interpolation method between a
3577 %  floating point coordinate and the pixels surrounding that coordinate.  No
3578 %  pixel area resampling, or scaling of the result is performed.
3579 %
3580 %  The format of the InterpolatePixelChannel method is:
3581 %
3582 %      MagickBooleanType InterpolatePixelChannel(const Image *image,
3583 %        const PixelChannel channel,const CacheView *image_view,
3584 %        const InterpolatePixelMethod method,const double x,const double y,
3585 %        double *pixel,ExceptionInfo *exception)
3586 %
3587 %  A description of each parameter follows:
3588 %
3589 %    o image: the image.
3590 %
3591 %    o image_view: the image view.
3592 %
3593 %    o channel: the pixel channel to interpolate.
3594 %
3595 %    o method: the pixel color interpolation method.
3596 %
3597 %    o x,y: A double representing the current (x,y) position of the pixel.
3598 %
3599 %    o pixel: return the interpolated pixel here.
3600 %
3601 %    o exception: return any errors or warnings in this structure.
3602 %
3603 */
3604
3605 static inline double MagickMax(const MagickRealType x,const MagickRealType y)
3606 {
3607   if (x > y)
3608     return(x);
3609   return(y);
3610 }
3611
3612 static inline MagickRealType CubicWeightingFunction(const MagickRealType x)
3613 {
3614   MagickRealType
3615     alpha,
3616     gamma;
3617
3618   alpha=MagickMax(x+2.0,0.0);
3619   gamma=1.0*alpha*alpha*alpha;
3620   alpha=MagickMax(x+1.0,0.0);
3621   gamma-=4.0*alpha*alpha*alpha;
3622   alpha=MagickMax(x+0.0,0.0);
3623   gamma+=6.0*alpha*alpha*alpha;
3624   alpha=MagickMax(x-1.0,0.0);
3625   gamma-=4.0*alpha*alpha*alpha;
3626   return(gamma/6.0);
3627 }
3628
3629 static inline double MeshInterpolate(const PointInfo *delta,const double p,
3630   const double x,const double y)
3631 {
3632   return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p);
3633 }
3634
3635 static inline ssize_t NearestNeighbor(const MagickRealType x)
3636 {
3637   if (x >= 0.0)
3638     return((ssize_t) (x+0.5));
3639   return((ssize_t) (x-0.5));
3640 }
3641
3642 MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
3643   const CacheView *image_view,const PixelChannel channel,
3644   const InterpolatePixelMethod method,const double x,const double y,
3645   double *pixel,ExceptionInfo *exception)
3646 {
3647   MagickBooleanType
3648     status;
3649
3650   MagickRealType
3651     alpha[16],
3652     gamma,
3653     pixels[16];
3654
3655   PixelTrait
3656     traits;
3657
3658   register const Quantum
3659     *p;
3660
3661   register ssize_t
3662     i;
3663
3664   ssize_t
3665     x_offset,
3666     y_offset;
3667
3668   assert(image != (Image *) NULL);
3669   assert(image != (Image *) NULL);
3670   assert(image->signature == MagickSignature);
3671   assert(image_view != (CacheView *) NULL);
3672   status=MagickTrue;
3673   *pixel=0.0;
3674   traits=GetPixelChannelMapTraits(image,channel);
3675   x_offset=(ssize_t) floor(x);
3676   y_offset=(ssize_t) floor(y);
3677   switch (method == UndefinedInterpolatePixel ? image->interpolate : method)
3678   {
3679     case AverageInterpolatePixel:
3680     {
3681       p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
3682         exception);
3683       if (p == (const Quantum *) NULL)
3684         {
3685           status=MagickFalse;
3686           break;
3687         }
3688       if ((traits & BlendPixelTrait) == 0)
3689         for (i=0; i < 16; i++)
3690         {
3691           alpha[i]=1.0;
3692           pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
3693         }
3694       else
3695         for (i=0; i < 16; i++)
3696         {
3697           alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
3698             GetPixelChannels(image));
3699           pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
3700         }
3701       for (i=0; i < 16; i++)
3702       {
3703         gamma=1.0/(fabs((double) alpha[i]) <= MagickEpsilon ? 1.0 : alpha[i]);
3704         *pixel+=gamma*0.0625*pixels[i];
3705       }
3706       break;
3707     }
3708     case BicubicInterpolatePixel:
3709     {
3710       MagickRealType
3711         u[4],
3712         v[4];
3713
3714       PointInfo
3715         delta;
3716
3717       p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
3718         exception);
3719       if (p == (const Quantum *) NULL)
3720         {
3721           status=MagickFalse;
3722           break;
3723         }
3724       if ((traits & BlendPixelTrait) == 0)
3725         for (i=0; i < 16; i++)
3726         {
3727           alpha[i]=1.0;
3728           pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
3729         }
3730       else
3731         for (i=0; i < 16; i++)
3732         {
3733           alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
3734             GetPixelChannels(image));
3735           pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
3736         }
3737       delta.x=x-x_offset;
3738       delta.y=y-y_offset;
3739       for (i=0; i < 4; i++)
3740       {
3741         u[0]=(pixels[4*i+3]-pixels[4*i+2])-(pixels[4*i+0]-pixels[4*i+1]);
3742         u[1]=(pixels[4*i+0]-pixels[4*i+1])-u[0];
3743         u[2]=pixels[4*i+2]-pixels[4*i+0];
3744         u[3]=pixels[4*i+1];
3745         v[i]=(delta.x*delta.x*delta.x*u[0])+(delta.x*delta.x*u[1])+(delta.x*
3746           u[2])+u[3];
3747       }
3748       u[0]=(v[3]-v[2])-(v[0]-v[1]);
3749       u[1]=(v[0]-v[1])-u[0];
3750       u[2]=v[2]-v[0];
3751       u[3]=v[1];
3752       *pixel=(delta.y*delta.y*delta.y*u[0])+(delta.y*delta.y*u[1])+(delta.y*
3753         u[2])+u[3];
3754       break;
3755     }
3756     case BilinearInterpolatePixel:
3757     default:
3758     {
3759       PointInfo
3760         delta,
3761         epsilon;
3762
3763       p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
3764       if (p == (const Quantum *) NULL)
3765         {
3766           status=MagickFalse;
3767           break;
3768         }
3769       if ((traits & BlendPixelTrait) == 0)
3770         for (i=0; i < 4; i++)
3771         {
3772           alpha[i]=1.0;
3773           pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
3774         }
3775       else
3776         for (i=0; i < 4; i++)
3777         {
3778           alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
3779             GetPixelChannels(image));
3780           pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
3781         }
3782       delta.x=x-x_offset;
3783       delta.y=y-y_offset;
3784       epsilon.x=1.0-delta.x;
3785       epsilon.y=1.0-delta.y;
3786       gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
3787         (epsilon.x*alpha[2]+delta.x*alpha[3])));
3788       gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
3789       *pixel=gamma*(epsilon.y*(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*
3790         (epsilon.x*pixels[2]+delta.x*pixels[3]));
3791       break;
3792     }
3793     case FilterInterpolatePixel:
3794     {
3795       CacheView
3796         *filter_view;
3797
3798       Image
3799         *excerpt_image,
3800         *filter_image;
3801
3802       RectangleInfo
3803         geometry;
3804
3805       geometry.width=4L;
3806       geometry.height=4L;
3807       geometry.x=x_offset-1;
3808       geometry.y=y_offset-1;
3809       excerpt_image=ExcerptImage(image,&geometry,exception);
3810       if (excerpt_image == (Image *) NULL)
3811         {
3812           status=MagickFalse;
3813           break;
3814         }
3815       filter_image=ResizeImage(excerpt_image,1,1,image->filter,image->blur,
3816         exception);
3817       excerpt_image=DestroyImage(excerpt_image);
3818       if (filter_image == (Image *) NULL)
3819         break;
3820       filter_view=AcquireCacheView(filter_image);
3821       p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
3822       if (p == (const Quantum *) NULL)
3823         status=MagickFalse;
3824       else
3825         *pixel=(double) p[channel];
3826       filter_view=DestroyCacheView(filter_view);
3827       filter_image=DestroyImage(filter_image);
3828       break;
3829     }
3830     case IntegerInterpolatePixel:
3831     {
3832       p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
3833       if (p == (const Quantum *) NULL)
3834         {
3835           status=MagickFalse;
3836           break;
3837         }
3838       *pixel=(double) p[channel];
3839       break;
3840     }
3841     case NearestNeighborInterpolatePixel:
3842     {
3843       p=GetCacheViewVirtualPixels(image_view,NearestNeighbor(x),
3844         NearestNeighbor(y),1,1,exception);
3845       if (p == (const Quantum *) NULL)
3846         {
3847           status=MagickFalse;
3848           break;
3849         }
3850       *pixel=(double) p[channel];
3851       break;
3852     }
3853     case MeshInterpolatePixel:
3854     {
3855       PointInfo
3856         delta,
3857         luminance;
3858
3859       p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
3860       if (p == (const Quantum *) NULL)
3861         {
3862           status=MagickFalse;
3863           break;
3864         }
3865       if ((traits & BlendPixelTrait) == 0)
3866         for (i=0; i < 4; i++)
3867         {
3868           alpha[i]=1.0;
3869           pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
3870         }
3871       else
3872         for (i=0; i < 4; i++)
3873         {
3874           alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
3875             GetPixelChannels(image));
3876           pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
3877         }
3878       delta.x=x-x_offset;
3879       delta.y=y-y_offset;
3880       luminance.x=GetPixelLuminance(image,p)-(double)
3881         GetPixelLuminance(image,p+3*GetPixelChannels(image));
3882       luminance.y=GetPixelLuminance(image,p+1*GetPixelChannels(image))-(double)
3883         GetPixelLuminance(image,p+2*GetPixelChannels(image));
3884       if (fabs(luminance.x) < fabs(luminance.y))
3885         {
3886           /*
3887             Diagonal 0-3 NW-SE.
3888           */
3889           if (delta.x <= delta.y)
3890             {
3891               /*
3892                 Bottom-left triangle (pixel: 2, diagonal: 0-3).
3893               */
3894               delta.y=1.0-delta.y;
3895               gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
3896               gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
3897               *pixel=gamma*MeshInterpolate(&delta,pixels[2],pixels[3],
3898                 pixels[0]);
3899             }
3900           else
3901             {
3902               /*
3903                 Top-right triangle (pixel: 1, diagonal: 0-3).
3904               */
3905               delta.x=1.0-delta.x;
3906               gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
3907               gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
3908               *pixel=gamma*MeshInterpolate(&delta,pixels[1],pixels[0],
3909                 pixels[3]);
3910             }
3911         }
3912       else
3913         {
3914           /*
3915             Diagonal 1-2 NE-SW.
3916           */
3917           if (delta.x <= (1.0-delta.y))
3918             {
3919               /*
3920                 Top-left triangle (pixel: 0, diagonal: 1-2).
3921               */
3922               gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
3923               gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
3924               *pixel=gamma*MeshInterpolate(&delta,pixels[0],pixels[1],
3925                 pixels[2]);
3926             }
3927           else
3928             {
3929               /*
3930                 Bottom-right triangle (pixel: 3, diagonal: 1-2).
3931               */
3932               delta.x=1.0-delta.x;
3933               delta.y=1.0-delta.y;
3934               gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
3935               gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
3936               *pixel=gamma*MeshInterpolate(&delta,pixels[3],pixels[2],
3937                 pixels[1]);
3938             }
3939         }
3940       break;
3941     }
3942     case SplineInterpolatePixel:
3943     {
3944       MagickRealType
3945         dx,
3946         dy;
3947
3948       PointInfo
3949         delta;
3950
3951       ssize_t
3952         j,
3953         n;
3954
3955       p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
3956         exception);
3957       if (p == (const Quantum *) NULL)
3958         {
3959           status=MagickFalse;
3960           break;
3961         }
3962       if ((traits & BlendPixelTrait) == 0)
3963         for (i=0; i < 16; i++)
3964         {
3965           alpha[i]=1.0;
3966           pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
3967         }
3968       else
3969         for (i=0; i < 16; i++)
3970         {
3971           alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
3972             GetPixelChannels(image));
3973           pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
3974         }
3975       delta.x=x-x_offset;
3976       delta.y=y-y_offset;
3977       n=0;
3978       for (i=(-1); i < 3L; i++)
3979       {
3980         dy=CubicWeightingFunction((MagickRealType) i-delta.y);
3981         for (j=(-1); j < 3L; j++)
3982         {
3983           dx=CubicWeightingFunction(delta.x-(MagickRealType) j);
3984           gamma=1.0/(fabs((double) alpha[n]) <= MagickEpsilon ? 1.0 : alpha[n]);
3985           *pixel+=gamma*dx*dy*pixels[n];
3986           n++;
3987         }
3988       }
3989       break;
3990     }
3991   }
3992   return(status);
3993 }
3994 \f
3995 /*
3996 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3997 %                                                                             %
3998 %                                                                             %
3999 %                                                                             %
4000 %   I n t e r p o l a t e P i x e l I n f o                                   %
4001 %                                                                             %
4002 %                                                                             %
4003 %                                                                             %
4004 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4005 %
4006 %  InterpolatePixelInfo() applies a pixel interpolation method between a
4007 %  floating point coordinate and the pixels surrounding that coordinate.  No
4008 %  pixel area resampling, or scaling of the result is performed.
4009 %
4010 %  The format of the InterpolatePixelInfo method is:
4011 %
4012 %      MagickBooleanType InterpolatePixelInfo(const Image *image,
4013 %        const CacheView *image_view,const InterpolatePixelMethod method,
4014 %        const double x,const double y,PixelInfo *pixel,
4015 %        ExceptionInfo *exception)
4016 %
4017 %  A description of each parameter follows:
4018 %
4019 %    o image: the image.
4020 %
4021 %    o image_view: the image view.
4022 %
4023 %    o method: the pixel color interpolation method.
4024 %
4025 %    o x,y: A double representing the current (x,y) position of the pixel.
4026 %
4027 %    o pixel: return the interpolated pixel here.
4028 %
4029 %    o exception: return any errors or warnings in this structure.
4030 %
4031 */
4032
4033 static inline void AlphaBlendPixelInfo(const Image *image,
4034   const Quantum *pixel,PixelInfo *pixel_info,MagickRealType *alpha)
4035 {
4036   if (image->matte == MagickFalse)
4037     {
4038       *alpha=1.0;
4039       pixel_info->red=(MagickRealType) GetPixelRed(image,pixel);
4040       pixel_info->green=(MagickRealType) GetPixelGreen(image,pixel);
4041       pixel_info->blue=(MagickRealType) GetPixelBlue(image,pixel);
4042       pixel_info->black=0.0;
4043       if (image->colorspace == CMYKColorspace)
4044         pixel_info->black=(MagickRealType) GetPixelBlack(image,pixel);
4045       pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
4046       return;
4047     }
4048   *alpha=QuantumScale*GetPixelAlpha(image,pixel);
4049   pixel_info->red=(*alpha*GetPixelRed(image,pixel));
4050   pixel_info->green=(*alpha*GetPixelGreen(image,pixel));
4051   pixel_info->blue=(*alpha*GetPixelBlue(image,pixel));
4052   pixel_info->black=0.0;
4053   if (image->colorspace == CMYKColorspace)
4054     pixel_info->black=(*alpha*GetPixelBlack(image,pixel));
4055   pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
4056 }
4057
4058 static void BicubicInterpolate(const PixelInfo *pixels,const double dx,
4059   PixelInfo *pixel)
4060 {
4061   MagickRealType
4062     dx2,
4063     p,
4064     q,
4065     r,
4066     s;
4067
4068   dx2=dx*dx;
4069   p=(pixels[3].red-pixels[2].red)-(pixels[0].red-pixels[1].red);
4070   q=(pixels[0].red-pixels[1].red)-p;
4071   r=pixels[2].red-pixels[0].red;
4072   s=pixels[1].red;
4073   pixel->red=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4074   p=(pixels[3].green-pixels[2].green)-(pixels[0].green-pixels[1].green);
4075   q=(pixels[0].green-pixels[1].green)-p;
4076   r=pixels[2].green-pixels[0].green;
4077   s=pixels[1].green;
4078   pixel->green=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4079   p=(pixels[3].blue-pixels[2].blue)-(pixels[0].blue-pixels[1].blue);
4080   q=(pixels[0].blue-pixels[1].blue)-p;
4081   r=pixels[2].blue-pixels[0].blue;
4082   s=pixels[1].blue;
4083   pixel->blue=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4084   p=(pixels[3].alpha-pixels[2].alpha)-(pixels[0].alpha-pixels[1].alpha);
4085   q=(pixels[0].alpha-pixels[1].alpha)-p;
4086   r=pixels[2].alpha-pixels[0].alpha;
4087   s=pixels[1].alpha;
4088   pixel->alpha=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4089   if (pixel->colorspace == CMYKColorspace)
4090     {
4091       p=(pixels[3].black-pixels[2].black)-(pixels[0].black-pixels[1].black);
4092       q=(pixels[0].black-pixels[1].black)-p;
4093       r=pixels[2].black-pixels[0].black;
4094       s=pixels[1].black;
4095       pixel->black=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
4096     }
4097 }
4098
4099 MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
4100   const CacheView *image_view,const InterpolatePixelMethod method,
4101   const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception)
4102 {
4103   MagickBooleanType
4104     status;
4105
4106   MagickRealType
4107     alpha[16],
4108     gamma;
4109
4110   PixelInfo
4111     pixels[16];
4112
4113   register const Quantum
4114     *p;
4115
4116   register ssize_t
4117     i;
4118
4119   ssize_t
4120     x_offset,
4121     y_offset;
4122
4123   assert(image != (Image *) NULL);
4124   assert(image->signature == MagickSignature);
4125   assert(image_view != (CacheView *) NULL);
4126   status=MagickTrue;
4127   x_offset=(ssize_t) floor(x);
4128   y_offset=(ssize_t) floor(y);
4129   switch (method == UndefinedInterpolatePixel ? image->interpolate : method)
4130   {
4131     case AverageInterpolatePixel:
4132     {
4133       p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4134         exception);
4135       if (p == (const Quantum *) NULL)
4136         {
4137           status=MagickFalse;
4138           break;
4139         }
4140       AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
4141       AlphaBlendPixelInfo(image,p+1*GetPixelChannels(image),pixels+1,alpha+1);
4142       AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
4143       AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
4144       AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
4145       AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
4146       AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
4147       AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
4148       AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
4149       AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
4150       AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
4151         10);
4152       AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
4153         11);
4154       AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
4155         12);
4156       AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
4157         13);
4158       AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
4159         14);
4160       AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
4161         15);
4162       pixel->red=0.0;
4163       pixel->green=0.0;
4164       pixel->blue=0.0;
4165       pixel->black=0.0;
4166       pixel->alpha=0.0;
4167       for (i=0; i < 16L; i++)
4168       {
4169         gamma=1.0/(fabs((double) alpha[i]) <= MagickEpsilon ? 1.0 : alpha[i]);
4170         pixel->red+=gamma*0.0625*pixels[i].red;
4171         pixel->green+=gamma*0.0625*pixels[i].green;
4172         pixel->blue+=gamma*0.0625*pixels[i].blue;
4173         if (image->colorspace == CMYKColorspace)
4174           pixel->black+=gamma*0.0625*pixels[i].black;
4175         pixel->alpha+=0.0625*pixels[i].alpha;
4176       }
4177       break;
4178     }
4179     case BicubicInterpolatePixel:
4180     {
4181       PixelInfo
4182         u[4];
4183
4184       PointInfo
4185         delta;
4186
4187       p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4188         exception);
4189       if (p == (const Quantum *) NULL)
4190         {
4191           status=MagickFalse;
4192           break;
4193         }
4194       AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
4195       AlphaBlendPixelInfo(image,p+1*GetPixelChannels(image),pixels+1,alpha+1);
4196       AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
4197       AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
4198       AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
4199       AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
4200       AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
4201       AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
4202       AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
4203       AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
4204       AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
4205         10);
4206       AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
4207         11);
4208       AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
4209         12);
4210       AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
4211         13);
4212       AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
4213         14);
4214       AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
4215         15);
4216       delta.x=x-x_offset;
4217       delta.y=y-y_offset;
4218       for (i=0; i < 4L; i++)
4219         BicubicInterpolate(pixels+4*i,delta.x,u+i);
4220       BicubicInterpolate(u,delta.y,pixel);
4221       break;
4222     }
4223     case BilinearInterpolatePixel:
4224     default:
4225     {
4226       PointInfo
4227         delta,
4228         epsilon;
4229
4230       p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4231       if (p == (const Quantum *) NULL)
4232         {
4233           status=MagickFalse;
4234           break;
4235         }
4236       AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
4237       AlphaBlendPixelInfo(image,p+1*GetPixelChannels(image),pixels+1,alpha+1);
4238       AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
4239       AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
4240       delta.x=x-x_offset;
4241       delta.y=y-y_offset;
4242       epsilon.x=1.0-delta.x;
4243       epsilon.y=1.0-delta.y;
4244       gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4245         (epsilon.x*alpha[2]+delta.x*alpha[3])));
4246       gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4247       pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x*
4248         pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red));
4249       pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x*
4250         pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x*
4251         pixels[3].green));
4252       pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x*
4253         pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x*
4254         pixels[3].blue));
4255       if (image->colorspace == CMYKColorspace)
4256         pixel->black=gamma*(epsilon.y*(epsilon.x*pixels[0].black+delta.x*
4257           pixels[1].black)+delta.y*(epsilon.x*pixels[2].black+delta.x*
4258           pixels[3].black));
4259       gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
4260       gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4261       pixel->alpha=(epsilon.y*(epsilon.x*pixels[0].alpha+delta.x*
4262         pixels[1].alpha)+delta.y*(epsilon.x*pixels[2].alpha+delta.x*
4263         pixels[3].alpha));
4264       break;
4265     }
4266     case FilterInterpolatePixel:
4267     {
4268       CacheView
4269         *filter_view;
4270
4271       Image
4272         *excerpt_image,
4273         *filter_image;
4274
4275       RectangleInfo
4276         geometry;
4277
4278       geometry.width=4L;
4279       geometry.height=4L;
4280       geometry.x=x_offset-1;
4281       geometry.y=y_offset-1;
4282       excerpt_image=ExcerptImage(image,&geometry,exception);
4283       if (excerpt_image == (Image *) NULL)
4284         {
4285           status=MagickFalse;
4286           break;
4287         }
4288       filter_image=ResizeImage(excerpt_image,1,1,image->filter,image->blur,
4289         exception);
4290       excerpt_image=DestroyImage(excerpt_image);
4291       if (filter_image == (Image *) NULL)
4292         break;
4293       filter_view=AcquireCacheView(filter_image);
4294       p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4295       if (p != (const Quantum *) NULL)
4296         SetPixelInfo(image,p,pixel);
4297       filter_view=DestroyCacheView(filter_view);
4298       filter_image=DestroyImage(filter_image);
4299       break;
4300     }
4301     case IntegerInterpolatePixel:
4302     {
4303       p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
4304       if (p == (const Quantum *) NULL)
4305         {
4306           status=MagickFalse;
4307           break;
4308         }
4309       SetPixelInfo(image,p,pixel);
4310       break;
4311     }
4312     case MeshInterpolatePixel:
4313     {
4314       PointInfo
4315         delta,
4316         luminance;
4317
4318       p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4319       if (p == (const Quantum *) NULL)
4320         {
4321           status=MagickFalse;
4322           break;
4323         }
4324       delta.x=x-x_offset;
4325       delta.y=y-y_offset;
4326       luminance.x=GetPixelLuminance(image,p)-(double)
4327         GetPixelLuminance(image,p+3*GetPixelChannels(image));
4328       luminance.y=GetPixelLuminance(image,p+1*GetPixelChannels(image))-(double)
4329         GetPixelLuminance(image,p+2*GetPixelChannels(image));
4330       AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
4331       AlphaBlendPixelInfo(image,p+1*GetPixelChannels(image),pixels+1,alpha+1);
4332       AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
4333       AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
4334       if (fabs(luminance.x) < fabs(luminance.y))
4335         {
4336           /*
4337             Diagonal 0-3 NW-SE.
4338           */
4339           if (delta.x <= delta.y)
4340             {
4341               /*
4342                 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4343               */
4344               delta.y=1.0-delta.y;
4345               gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
4346               gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4347               pixel->red=gamma*MeshInterpolate(&delta,pixels[2].red,
4348                 pixels[3].red,pixels[0].red);
4349               pixel->green=gamma*MeshInterpolate(&delta,pixels[2].green,
4350                 pixels[3].green,pixels[0].green);
4351               pixel->blue=gamma*MeshInterpolate(&delta,pixels[2].blue,
4352                 pixels[3].blue,pixels[0].blue);
4353               if (image->colorspace == CMYKColorspace)
4354                 pixel->black=gamma*MeshInterpolate(&delta,pixels[2].black,
4355                   pixels[3].black,pixels[0].black);
4356               gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
4357               pixel->alpha=gamma*MeshInterpolate(&delta,pixels[2].alpha,
4358                 pixels[3].alpha,pixels[0].alpha);
4359             }
4360           else
4361             {
4362               /*
4363                 Top-right triangle (pixel:1 , diagonal: 0-3).
4364               */
4365               delta.x=1.0-delta.x;
4366               gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
4367               gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4368               pixel->red=gamma*MeshInterpolate(&delta,pixels[1].red,
4369                 pixels[0].red,pixels[3].red);
4370               pixel->green=gamma*MeshInterpolate(&delta,pixels[1].green,
4371                 pixels[0].green,pixels[3].green);
4372               pixel->blue=gamma*MeshInterpolate(&delta,pixels[1].blue,
4373                 pixels[0].blue,pixels[3].blue);
4374               if (image->colorspace == CMYKColorspace)
4375                 pixel->black=gamma*MeshInterpolate(&delta,pixels[1].black,
4376                   pixels[0].black,pixels[3].black);
4377               gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
4378               pixel->alpha=gamma*MeshInterpolate(&delta,pixels[1].alpha,
4379                 pixels[0].alpha,pixels[3].alpha);
4380             }
4381         }
4382       else
4383         {
4384           /*
4385             Diagonal 1-2 NE-SW.
4386           */
4387           if (delta.x <= (1.0-delta.y))
4388             {
4389               /*
4390                 Top-left triangle (pixel: 0, diagonal: 1-2).
4391               */
4392               gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
4393               gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4394               pixel->red=gamma*MeshInterpolate(&delta,pixels[0].red,
4395                 pixels[1].red,pixels[2].red);
4396               pixel->green=gamma*MeshInterpolate(&delta,pixels[0].green,
4397                 pixels[1].green,pixels[2].green);
4398               pixel->blue=gamma*MeshInterpolate(&delta,pixels[0].blue,
4399                 pixels[1].blue,pixels[2].blue);
4400               if (image->colorspace == CMYKColorspace)
4401                 pixel->black=gamma*MeshInterpolate(&delta,pixels[0].black,
4402                   pixels[1].black,pixels[2].black);
4403               gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
4404               pixel->alpha=gamma*MeshInterpolate(&delta,pixels[0].alpha,
4405                 pixels[1].alpha,pixels[2].alpha);
4406             }
4407           else
4408             {
4409               /*
4410                 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4411               */
4412               delta.x=1.0-delta.x;
4413               delta.y=1.0-delta.y;
4414               gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
4415               gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
4416               pixel->red=gamma*MeshInterpolate(&delta,pixels[3].red,
4417                 pixels[2].red,pixels[1].red);
4418               pixel->green=gamma*MeshInterpolate(&delta,pixels[3].green,
4419                 pixels[2].green,pixels[1].green);
4420               pixel->blue=gamma*MeshInterpolate(&delta,pixels[3].blue,
4421                 pixels[2].blue,pixels[1].blue);
4422               if (image->colorspace == CMYKColorspace)
4423                 pixel->black=gamma*MeshInterpolate(&delta,pixels[3].black,
4424                   pixels[2].black,pixels[1].black);
4425               gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
4426               pixel->alpha=gamma*MeshInterpolate(&delta,pixels[3].alpha,
4427                 pixels[2].alpha,pixels[1].alpha);
4428             }
4429         }
4430       break;
4431     }
4432     case NearestNeighborInterpolatePixel:
4433     {
4434       p=GetCacheViewVirtualPixels(image_view,NearestNeighbor(x),
4435         NearestNeighbor(y),1,1,exception);
4436       if (p == (const Quantum *) NULL)
4437         {
4438           status=MagickFalse;
4439           break;
4440         }
4441       SetPixelInfo(image,p,pixel);
4442       break;
4443     }
4444     case SplineInterpolatePixel:
4445     {
4446       MagickRealType
4447         dx,
4448         dy;
4449
4450       PointInfo
4451         delta;
4452
4453       ssize_t
4454         j,
4455         n;
4456
4457       p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4458         exception);
4459       if (p == (const Quantum *) NULL)
4460         {
4461           status=MagickFalse;
4462           break;
4463         }
4464       AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
4465       AlphaBlendPixelInfo(image,p+1*GetPixelChannels(image),pixels+1,alpha+1);
4466       AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
4467       AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
4468       AlphaBlendPixelInfo(image,p+4*GetPixelChannels(image),pixels+4,alpha+4);
4469       AlphaBlendPixelInfo(image,p+5*GetPixelChannels(image),pixels+5,alpha+5);
4470       AlphaBlendPixelInfo(image,p+6*GetPixelChannels(image),pixels+6,alpha+6);
4471       AlphaBlendPixelInfo(image,p+7*GetPixelChannels(image),pixels+7,alpha+7);
4472       AlphaBlendPixelInfo(image,p+8*GetPixelChannels(image),pixels+8,alpha+8);
4473       AlphaBlendPixelInfo(image,p+9*GetPixelChannels(image),pixels+9,alpha+9);
4474       AlphaBlendPixelInfo(image,p+10*GetPixelChannels(image),pixels+10,alpha+
4475         10);
4476       AlphaBlendPixelInfo(image,p+11*GetPixelChannels(image),pixels+11,alpha+
4477         11);
4478       AlphaBlendPixelInfo(image,p+12*GetPixelChannels(image),pixels+12,alpha+
4479         12);
4480       AlphaBlendPixelInfo(image,p+13*GetPixelChannels(image),pixels+13,alpha+
4481         13);
4482       AlphaBlendPixelInfo(image,p+14*GetPixelChannels(image),pixels+14,alpha+
4483         14);
4484       AlphaBlendPixelInfo(image,p+15*GetPixelChannels(image),pixels+15,alpha+
4485         15);
4486       pixel->red=0.0;
4487       pixel->green=0.0;
4488       pixel->blue=0.0;
4489       pixel->black=0.0;
4490       pixel->alpha=0.0;
4491       delta.x=x-x_offset;
4492       delta.y=y-y_offset;
4493       n=0;
4494       for (i=(-1); i < 3L; i++)
4495       {
4496         dy=CubicWeightingFunction((MagickRealType) i-delta.y);
4497         for (j=(-1); j < 3L; j++)
4498         {
4499           dx=CubicWeightingFunction(delta.x-(MagickRealType) j);
4500           gamma=1.0/(fabs((double) alpha[n]) <= MagickEpsilon ? 1.0 : alpha[n]);
4501           pixel->red+=gamma*dx*dy*pixels[n].red;
4502           pixel->green+=gamma*dx*dy*pixels[n].green;
4503           pixel->blue+=gamma*dx*dy*pixels[n].blue;
4504           if (image->colorspace == CMYKColorspace)
4505             pixel->black+=gamma*dx*dy*pixels[n].black;
4506           pixel->alpha+=dx*dy*pixels[n].alpha;
4507           n++;
4508         }
4509       }
4510       break;
4511     }
4512   }
4513   return(status);
4514 }
4515 \f
4516 /*
4517 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4518 %                                                                             %
4519 %                                                                             %
4520 %                                                                             %
4521 +   I s F u z z y E q u i v a l e n c e P i x e l                             %
4522 %                                                                             %
4523 %                                                                             %
4524 %                                                                             %
4525 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4526 %
4527 %  IsFuzzyEquivalencePixel() returns MagickTrue if the distance between two
4528 %  pixels is less than the specified distance in a linear three (or four)u
4529 %  dimensional color space.
4530 %
4531 %  The format of the IsFuzzyEquivalencePixel method is:
4532 %
4533 %      void IsFuzzyEquivalencePixel(const Image *image,const Quantum *p,
4534 %        const Quantum *q)
4535 %
4536 %  A description of each parameter follows:
4537 %
4538 %    o image: the image.
4539 %
4540 %    o p: Pixel p.
4541 %
4542 %    o q: Pixel q.
4543 %
4544 */
4545 MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *image,
4546   const Quantum *p,const Quantum *q)
4547 {
4548   MagickRealType
4549     fuzz,
4550     pixel;
4551
4552   register MagickRealType
4553     distance,
4554     scale;
4555
4556   fuzz=MagickMax(image->fuzz,(MagickRealType) MagickSQ1_2)*
4557     MagickMax(image->fuzz,(MagickRealType) MagickSQ1_2);
4558   scale=1.0;
4559   distance=0.0;
4560   if (image->matte != MagickFalse)
4561     {
4562       /*
4563         Transparencies are involved - set alpha distance
4564       */
4565       pixel=(MagickRealType) ((image->matte != MagickFalse ?
4566         GetPixelAlpha(image,p) : OpaqueAlpha)-(image->matte != MagickFalse ?
4567         GetPixelAlpha(image,q) : OpaqueAlpha));
4568       distance=pixel*pixel;
4569       if (distance > fuzz)
4570         return(MagickFalse);
4571       /*
4572         Generate a alpha scaling factor to generate a 4D cone on colorspace
4573         Note that if one color is transparent, distance has no color component.
4574       */
4575       scale=QuantumScale*GetPixelAlpha(image,p);
4576       scale*=QuantumScale*GetPixelAlpha(image,q);
4577       if (scale <= MagickEpsilon)
4578         return(MagickTrue);
4579     }
4580   /*
4581     RGB or CMY color cube
4582   */
4583   distance*=3.0;  /* rescale appropriately */
4584   fuzz*=3.0;
4585   pixel=GetPixelRed(image,p)-(MagickRealType) GetPixelRed(image,q);
4586   if ((image->colorspace == HSLColorspace) ||
4587       (image->colorspace == HSBColorspace) ||
4588       (image->colorspace == HWBColorspace))
4589     {
4590       /*
4591         Compute an arc distance for hue.  It should be a vector angle of
4592         'S'/'W' length with 'L'/'B' forming appropriate cones.
4593       */
4594       if (fabs((double) pixel) > (QuantumRange/2))
4595         pixel-=QuantumRange;
4596       pixel*=2;
4597     }
4598   distance+=scale*pixel*pixel;
4599   if (distance > fuzz)
4600     return(MagickFalse);
4601   pixel=GetPixelGreen(image,p)-(MagickRealType) GetPixelGreen(image,q);
4602   distance+=scale*pixel*pixel;
4603   if (distance > fuzz)
4604     return(MagickFalse);
4605   pixel=GetPixelBlue(image,p)-(MagickRealType) GetPixelBlue(image,q);
4606   distance+=scale*pixel*pixel;
4607   if (distance > fuzz)
4608     return(MagickFalse);
4609   return(MagickTrue);
4610 }
4611 \f
4612 /*
4613 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4614 %                                                                             %
4615 %                                                                             %
4616 %                                                                             %
4617 +   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                     %
4618 %                                                                             %
4619 %                                                                             %
4620 %                                                                             %
4621 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4622 %
4623 %  IsFuzzyEquivalencePixelInfo() returns true if the distance between two
4624 %  colors is less than the specified distance in a linear three (or four)
4625 %  dimensional color space.
4626 %
4627 %  This implements the equivalent of...
4628 %    fuzz < sqrt( color_distance^2 * u.a*v.a  + alpha_distance^2 )
4629 %
4630 %  Which produces a multi-dimensional cone for that colorspace along the
4631 %  transparency vector.
4632 %
4633 %  For example for an RGB
4634 %    color_distance^2  = ( (u.r-v.r)^2 + (u.g-v.g)^2 + (u.b-v.b)^2 ) / 3
4635 %
4636 %  See http://www.imagemagick.org/Usage/bugs/fuzz_distance/
4637 %
4638 %  Hue colorspace distances need more work.  Hue is not a distance, it is an
4639 %  angle!
4640 %
4641 %  A check that q is in the same color space as p should be made and the
4642 %  appropriate mapping made.  -- Anthony Thyssen  8 December 2010
4643 %
4644 %  The format of the IsFuzzyEquivalencePixelInfo method is:
4645 %
4646 %      MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
4647 %        const PixelInfo *q)
4648 %
4649 %  A description of each parameter follows:
4650 %
4651 %    o p: Pixel p.
4652 %
4653 %    o q: Pixel q.
4654 %
4655 */
4656 MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
4657   const PixelInfo *q)
4658 {
4659   MagickRealType
4660     fuzz,
4661     pixel;
4662
4663   register MagickRealType
4664     scale,
4665     distance;
4666
4667   if ((p->fuzz == 0.0) && (q->fuzz == 0.0))
4668     return(IsPixelInfoEquivalent(p,q));
4669   if (p->fuzz == 0.0)
4670     fuzz=MagickMax(q->fuzz,(MagickRealType) MagickSQ1_2)*
4671       MagickMax(q->fuzz,(MagickRealType) MagickSQ1_2);
4672   else if (q->fuzz == 0.0)
4673     fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*
4674       MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2);
4675   else
4676     fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*
4677       MagickMax(q->fuzz,(MagickRealType) MagickSQ1_2);
4678   scale=1.0;
4679   distance=0.0;
4680   if ((p->matte != MagickFalse) || (q->matte != MagickFalse))
4681     {
4682       /*
4683         Transparencies are involved - set alpha distance.
4684       */
4685       pixel=(p->matte != MagickFalse ? p->alpha : OpaqueAlpha)-
4686         (q->matte != MagickFalse ? q->alpha : OpaqueAlpha);
4687       distance=pixel*pixel;
4688       if (distance > fuzz)
4689         return(MagickFalse);
4690       /*
4691         Generate a alpha scaling factor to generate a 4D cone on colorspace.
4692         Note that if one color is transparent, distance has no color component.
4693       */
4694       if (p->matte != MagickFalse)
4695         scale=(QuantumScale*p->alpha);
4696       if (q->matte != MagickFalse)
4697         scale*=(QuantumScale*q->alpha);
4698       if (scale <= MagickEpsilon )
4699         return(MagickTrue);
4700     }
4701   /*
4702     CMYK create a CMY cube with a multi-dimensional cone toward black.
4703   */
4704   if (p->colorspace == CMYKColorspace)
4705     {
4706       pixel=p->black-q->black;
4707       distance+=pixel*pixel*scale;
4708       if (distance > fuzz)
4709         return(MagickFalse);
4710       scale*=(MagickRealType) (QuantumScale*(QuantumRange-p->black));
4711       scale*=(MagickRealType) (QuantumScale*(QuantumRange-q->black));
4712     }
4713   /*
4714     RGB or CMY color cube.
4715   */
4716   distance*=3.0;  /* rescale appropriately */
4717   fuzz*=3.0;
4718   pixel=p->red-q->red;
4719   if ((p->colorspace == HSLColorspace) || (p->colorspace == HSBColorspace) ||
4720       (p->colorspace == HWBColorspace))
4721     {
4722       /* This calculates a arc distance for hue
4723          Really if should be a vector angle of 'S'/'W' length
4724          with 'L'/'B' forming appropriate cones.
4725          In other words this is a hack - Anthony
4726       */
4727       if (fabs((double) pixel) > (QuantumRange/2))
4728         pixel-=QuantumRange;
4729       pixel*=2;
4730     }
4731   distance+=pixel*pixel*scale;
4732   if (distance > fuzz)
4733     return(MagickFalse);
4734   pixel=p->green-q->green;
4735   distance+=pixel*pixel*scale;
4736   if (distance > fuzz)
4737     return(MagickFalse);
4738   pixel=p->blue-q->blue;
4739   distance+=pixel*pixel*scale;
4740   if (distance > fuzz)
4741     return(MagickFalse);
4742   return(MagickTrue);
4743 }
4744 \f
4745 /*
4746 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4747 %                                                                             %
4748 %                                                                             %
4749 %                                                                             %
4750 +   I s F u z z y E q u i v a l e n c e P i x e l P a c k e t                 %
4751 %                                                                             %
4752 %                                                                             %
4753 %                                                                             %
4754 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4755 %
4756 %  IsFuzzyEquivalencePixelPacket() returns MagickTrue if the distance between
4757 %  two pixels is less than the specified distance in a linear three (or four)
4758 %  dimensional color space.
4759 %
4760 %  The format of the IsFuzzyEquivalencePixelPacket method is:
4761 %
4762 %      void IsFuzzyEquivalencePixelPacket(const Image *image,
4763 %        const PixelPacket *p,const PixelPacket *q)
4764 %
4765 %  A description of each parameter follows:
4766 %
4767 %    o image: the image.
4768 %
4769 %    o p: Pixel p.
4770 %
4771 %    o q: Pixel q.
4772 %
4773 */
4774 MagickExport MagickBooleanType IsFuzzyEquivalencePixelPacket(const Image *image,
4775   const PixelPacket *p,const PixelPacket *q)
4776 {
4777   MagickRealType
4778     fuzz,
4779     pixel;
4780
4781   register MagickRealType
4782     distance,
4783     scale;
4784
4785   if ((image->fuzz == 0.0) && (image->matte == MagickFalse))
4786     return(IsPixelPacketEquivalent(p,q));
4787   fuzz=MagickMax(image->fuzz,(MagickRealType) MagickSQ1_2)*
4788     MagickMax(image->fuzz,(MagickRealType) MagickSQ1_2);
4789   scale=1.0;
4790   distance=0.0;
4791   if (image->matte != MagickFalse)
4792     {
4793       /*
4794         Transparencies are involved - set alpha distance
4795       */
4796       pixel=(MagickRealType) ((image->matte != MagickFalse ? p->alpha :
4797         OpaqueAlpha)-(image->matte != MagickFalse ? q->alpha : OpaqueAlpha));
4798       distance=pixel*pixel;
4799       if (distance > fuzz)
4800         return(MagickFalse);
4801       /*
4802         Generate a alpha scaling factor to generate a 4D cone on colorspace
4803         Note that if one color is transparent, distance has no color component.
4804       */
4805       scale=QuantumScale*p->alpha;
4806       scale*=QuantumScale*q->alpha;
4807       if (scale <= MagickEpsilon)
4808         return(MagickTrue);
4809     }
4810   /*
4811     RGB or CMY color cube
4812   */
4813   distance*=3.0;  /* rescale appropriately */
4814   fuzz*=3.0;
4815   pixel=p->red-(MagickRealType) q->red;
4816   if ((image->colorspace == HSLColorspace) ||
4817       (image->colorspace == HSBColorspace) ||
4818       (image->colorspace == HWBColorspace))
4819     {
4820       /*
4821         Compute an arc distance for hue.  It should be a vector angle of
4822         'S'/'W' length with 'L'/'B' forming appropriate cones.
4823       */
4824       if (fabs((double) pixel) > (QuantumRange/2))
4825         pixel-=QuantumRange;
4826       pixel*=2;
4827     }
4828   distance+=scale*pixel*pixel;
4829   if (distance > fuzz)
4830     return(MagickFalse);
4831   pixel=(MagickRealType) p->green-q->green;
4832   distance+=scale*pixel*pixel;
4833   if (distance > fuzz)
4834     return(MagickFalse);
4835   pixel=(MagickRealType) p->blue-q->blue;
4836   distance+=scale*pixel*pixel;
4837   if (distance > fuzz)
4838     return(MagickFalse);
4839   return(MagickTrue);
4840 }
4841 \f
4842 /*
4843 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4844 %                                                                             %
4845 %                                                                             %
4846 %                                                                             %
4847 %   P o p P i x e l C h a n n e l M a p                                       %
4848 %                                                                             %
4849 %                                                                             %
4850 %                                                                             %
4851 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4852 %
4853 %  PopPixelChannelMap() pops the pixel component map.
4854 %
4855 %  The format of the PopPixelChannelMap method is:
4856 %
4857 %      void PopPixelChannelMap(Image *image)
4858 %
4859 %  A description of each parameter follows:
4860 %
4861 %    o image: the image.
4862 %
4863 */
4864 MagickExport void PopPixelChannelMap(Image *image)
4865 {
4866   image->map--;
4867   if (image->map < 0)
4868     ThrowFatalException(ResourceLimitFatalError,"PixelChannelMapStack");
4869 }
4870 \f
4871 /*
4872 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4873 %                                                                             %
4874 %                                                                             %
4875 %                                                                             %
4876 %   P u s h P i x e l C h a n n e l M a p                                     %
4877 %                                                                             %
4878 %                                                                             %
4879 %                                                                             %
4880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4881 %
4882 %  PushPixelChannelMap() pushes the pixel channel map from the specified
4883 %  channel mask.
4884 %
4885 %  The format of the PushPixelChannelMap method is:
4886 %
4887 %      void PushPixelChannelMap(Image *image,const ChannelType channel_mask)
4888 %
4889 %  A description of each parameter follows:
4890 %
4891 %    o image: the image.
4892 %
4893 %    o channel_mask: the channel mask.
4894 %
4895 */
4896 MagickExport void PushPixelChannelMap(Image *image,
4897   const ChannelType channel_mask)
4898 {
4899   image->map++;
4900   if (image->map >= MaxPixelChannelMaps)
4901     ThrowFatalException(ResourceLimitFatalError,"PixelChannelMapStack");
4902   SetPixelChannelMap(image,channel_mask);
4903 }
4904 \f
4905 /*
4906 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4907 %                                                                             %
4908 %                                                                             %
4909 %                                                                             %
4910 %   S e t P i x e l C h a n n e l M a p                                       %
4911 %                                                                             %
4912 %                                                                             %
4913 %                                                                             %
4914 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4915 %
4916 %  SetPixelChannelMap() sets the pixel channel map from the specified channel
4917 %  mask.
4918 %
4919 %  The format of the SetPixelChannelMap method is:
4920 %
4921 %      void SetPixelChannelMap(Image *image,const ChannelType channel_mask)
4922 %
4923 %  A description of each parameter follows:
4924 %
4925 %    o image: the image.
4926 %
4927 %    o channel_mask: the channel mask.
4928 %
4929 */
4930 MagickExport void SetPixelChannelMap(Image *image,
4931   const ChannelType channel_mask)
4932 {
4933 #define GetChannelBit(alpha,i)  (((size_t) (alpha) >> (size_t) (i)) & 0x01)
4934
4935   register ssize_t
4936     i;
4937
4938   for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
4939     SetPixelChannelMapTraits(image,(PixelChannel) i,
4940       GetChannelBit(channel_mask,i) ? UpdatePixelTrait : CopyPixelTrait);
4941   for ( ; i < MaxPixelChannels; i++)
4942     SetPixelChannelMapTraits(image,(PixelChannel) i,UndefinedPixelTrait);
4943 }
4944 \f
4945 /*
4946 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4947 %                                                                             %
4948 %                                                                             %
4949 %                                                                             %
4950 +   S t a n d a r d P i x e l C h a n n e l M a p                             %
4951 %                                                                             %
4952 %                                                                             %
4953 %                                                                             %
4954 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4955 %
4956 %  StandardPixelChannelMap() defines the standard pixel component map.
4957 %
4958 %  The format of the StandardPixelChannelMap() method is:
4959 %
4960 %      void StandardPixelChannelMap(Image *image)
4961 %
4962 %  A description of each parameter follows:
4963 %
4964 %    o image: the image.
4965 %
4966 */
4967 MagickExport void StandardPixelChannelMap(Image *image)
4968 {
4969   PixelChannel
4970     alpha_channel;
4971
4972   register ssize_t
4973     i;
4974
4975   for (i=0; i < (ssize_t) MaxPixelChannels; i++)
4976   {
4977     SetPixelChannelMapChannel(image,(PixelChannel) i,(PixelChannel) i);
4978     SetPixelChannelMapTraits(image,(PixelChannel) i,UndefinedPixelTrait);
4979   }
4980   image->number_channels=4;
4981   if (0 && image->colorspace == GRAYColorspace)
4982     image->number_channels=2;
4983   if (image->colorspace == CMYKColorspace)
4984     image->number_channels++;
4985   if (image->storage_class == PseudoClass)
4986     image->number_channels++;
4987   for (i=0; i < (ssize_t) image->number_channels; i++)
4988     SetPixelChannelMapTraits(image,(PixelChannel) i,(PixelTrait)
4989       UpdatePixelTrait);
4990   alpha_channel=GetPixelChannelMapChannel(image,AlphaPixelChannel);
4991   if (image->matte != MagickFalse)
4992     for (i=0; i < (ssize_t) image->number_channels; i++)
4993       if ((PixelChannel) i != alpha_channel)
4994         SetPixelChannelMapTraits(image,(PixelChannel) i,(PixelTrait)
4995           (UpdatePixelTrait | BlendPixelTrait));
4996   if (0 && image->colorspace == GRAYColorspace)
4997     {
4998       image->number_channels=2;
4999       SetPixelChannelMapChannel(image,GreenPixelChannel,RedPixelChannel);
5000       SetPixelChannelMapChannel(image,BluePixelChannel,RedPixelChannel);
5001     }
5002   if (image->storage_class == PseudoClass)
5003     {
5004       SetPixelChannelMapChannel(image,IndexPixelChannel,IndexPixelChannel);
5005       SetPixelChannelMapTraits(image,IndexPixelChannel,CopyPixelTrait);
5006     }
5007   image->number_channels+=image->number_meta_channels;
5008   for ( ; i < (ssize_t) image->number_channels; i++)
5009     SetPixelChannelMapTraits(image,(PixelChannel) i,CopyPixelTrait);
5010 }