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