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