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