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