Home | History | Annotate | Download | only in MagickCore
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                              GGGG  EEEEE  M   M                             %
      7 %                             G      E      MM MM                             %
      8 %                             G GG   EEE    M M M                             %
      9 %                             G   G  E      M   M                             %
     10 %                              GGGG  EEEEE  M   M                             %
     11 %                                                                             %
     12 %                                                                             %
     13 %                    Graphic Gems - Graphic Support Methods                   %
     14 %                                                                             %
     15 %                               Software Design                               %
     16 %                                    Cristy                                   %
     17 %                                 August 1996                                 %
     18 %                                                                             %
     19 %                                                                             %
     20 %  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
     21 %  dedicated to making software imaging solutions freely available.           %
     22 %                                                                             %
     23 %  You may not use this file except in compliance with the License.  You may  %
     24 %  obtain a copy of the License at                                            %
     25 %                                                                             %
     26 %    http://www.imagemagick.org/script/license.php                            %
     27 %                                                                             %
     28 %  Unless required by applicable law or agreed to in writing, software        %
     29 %  distributed under the License is distributed on an "AS IS" BASIS,          %
     30 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
     31 %  See the License for the specific language governing permissions and        %
     32 %  limitations under the License.                                             %
     33 %                                                                             %
     34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     35 %
     36 %
     37 %
     38 */
     39 
     40 /*
     42   Include declarations.
     43 */
     44 #include "MagickCore/studio.h"
     45 #include "MagickCore/color-private.h"
     46 #include "MagickCore/draw.h"
     47 #include "MagickCore/gem.h"
     48 #include "MagickCore/gem-private.h"
     49 #include "MagickCore/image.h"
     50 #include "MagickCore/image-private.h"
     51 #include "MagickCore/log.h"
     52 #include "MagickCore/memory_.h"
     53 #include "MagickCore/pixel-accessor.h"
     54 #include "MagickCore/pixel-private.h"
     55 #include "MagickCore/quantum.h"
     56 #include "MagickCore/quantum-private.h"
     57 #include "MagickCore/random_.h"
     58 #include "MagickCore/resize.h"
     59 #include "MagickCore/transform.h"
     60 #include "MagickCore/signature-private.h"
     61 
     62 /*
     64 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     65 %                                                                             %
     66 %                                                                             %
     67 %                                                                             %
     68 %   C o n v e r t H C L T o R G B                                             %
     69 %                                                                             %
     70 %                                                                             %
     71 %                                                                             %
     72 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     73 %
     74 %  ConvertHCLToRGB() transforms a (hue, chroma, luma) to a (red, green,
     75 %  blue) triple.
     76 %
     77 %  The format of the ConvertHCLToRGBImage method is:
     78 %
     79 %      void ConvertHCLToRGB(const double hue,const double chroma,
     80 %        const double luma,double *red,double *green,double *blue)
     81 %
     82 %  A description of each parameter follows:
     83 %
     84 %    o hue, chroma, luma: A double value representing a component of the
     85 %      HCL color space.
     86 %
     87 %    o red, green, blue: A pointer to a pixel component of type Quantum.
     88 %
     89 */
     90 MagickPrivate void ConvertHCLToRGB(const double hue,const double chroma,
     91   const double luma,double *red,double *green,double *blue)
     92 {
     93   double
     94     b,
     95     c,
     96     g,
     97     h,
     98     m,
     99     r,
    100     x;
    101 
    102   /*
    103     Convert HCL to RGB colorspace.
    104   */
    105   assert(red != (double *) NULL);
    106   assert(green != (double *) NULL);
    107   assert(blue != (double *) NULL);
    108   h=6.0*hue;
    109   c=chroma;
    110   x=c*(1.0-fabs(fmod(h,2.0)-1.0));
    111   r=0.0;
    112   g=0.0;
    113   b=0.0;
    114   if ((0.0 <= h) && (h < 1.0))
    115     {
    116       r=c;
    117       g=x;
    118     }
    119   else
    120     if ((1.0 <= h) && (h < 2.0))
    121       {
    122         r=x;
    123         g=c;
    124       }
    125     else
    126       if ((2.0 <= h) && (h < 3.0))
    127         {
    128           g=c;
    129           b=x;
    130         }
    131       else
    132         if ((3.0 <= h) && (h < 4.0))
    133           {
    134             g=x;
    135             b=c;
    136           }
    137         else
    138           if ((4.0 <= h) && (h < 5.0))
    139             {
    140               r=x;
    141               b=c;
    142             }
    143           else
    144             if ((5.0 <= h) && (h < 6.0))
    145               {
    146                 r=c;
    147                 b=x;
    148               }
    149   m=luma-(0.298839*r+0.586811*g+0.114350*b);
    150   *red=QuantumRange*(r+m);
    151   *green=QuantumRange*(g+m);
    152   *blue=QuantumRange*(b+m);
    153 }
    154 
    155 /*
    157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    158 %                                                                             %
    159 %                                                                             %
    160 %                                                                             %
    161 %   C o n v e r t H C L p T o R G B                                           %
    162 %                                                                             %
    163 %                                                                             %
    164 %                                                                             %
    165 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    166 %
    167 %  ConvertHCLpToRGB() transforms a (hue, chroma, luma) to a (red, green,
    168 %  blue) triple.  Since HCL colorspace is wider than RGB, we instead choose a
    169 %  saturation strategy to project it on the RGB cube.
    170 %
    171 %  The format of the ConvertHCLpToRGBImage method is:
    172 %
    173 %      void ConvertHCLpToRGB(const double hue,const double chroma,
    174 %        const double luma,double *red,double *green,double *blue)
    175 %
    176 %  A description of each parameter follows:
    177 %
    178 %    o hue, chroma, luma: A double value representing a componenet of the
    179 %      HCLp color space.
    180 %
    181 %    o red, green, blue: A pointer to a pixel component of type Quantum.
    182 %
    183 */
    184 MagickPrivate void ConvertHCLpToRGB(const double hue,const double chroma,
    185   const double luma,double *red,double *green,double *blue)
    186 {
    187   double
    188     b,
    189     c,
    190     g,
    191     h,
    192     m,
    193     r,
    194     x,
    195     z;
    196 
    197   /*
    198     Convert HCLp to RGB colorspace.
    199   */
    200   assert(red != (double *) NULL);
    201   assert(green != (double *) NULL);
    202   assert(blue != (double *) NULL);
    203   h=6.0*hue;
    204   c=chroma;
    205   x=c*(1.0-fabs(fmod(h,2.0)-1.0));
    206   r=0.0;
    207   g=0.0;
    208   b=0.0;
    209   if ((0.0 <= h) && (h < 1.0))
    210     {
    211       r=c;
    212       g=x;
    213     }
    214   else
    215     if ((1.0 <= h) && (h < 2.0))
    216       {
    217         r=x;
    218         g=c;
    219       }
    220     else
    221       if ((2.0 <= h) && (h < 3.0))
    222         {
    223           g=c;
    224           b=x;
    225         }
    226       else
    227         if ((3.0 <= h) && (h < 4.0))
    228           {
    229             g=x;
    230             b=c;
    231           }
    232         else
    233           if ((4.0 <= h) && (h < 5.0))
    234             {
    235               r=x;
    236               b=c;
    237             }
    238           else
    239             if ((5.0 <= h) && (h < 6.0))
    240               {
    241                 r=c;
    242                 b=x;
    243               }
    244   m=luma-(0.298839*r+0.586811*g+0.114350*b);
    245   z=1.0;
    246   if (m < 0.0)
    247     {
    248       z=luma/(luma-m);
    249       m=0.0;
    250     }
    251   else
    252     if (m+c > 1.0)
    253       {
    254         z=(1.0-luma)/(m+c-luma);
    255         m=1.0-z*c;
    256       }
    257   *red=QuantumRange*(z*r+m);
    258   *green=QuantumRange*(z*g+m);
    259   *blue=QuantumRange*(z*b+m);
    260 }
    261 
    262 /*
    264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    265 %                                                                             %
    266 %                                                                             %
    267 %                                                                             %
    268 %   C o n v e r t H S B T o R G B                                             %
    269 %                                                                             %
    270 %                                                                             %
    271 %                                                                             %
    272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    273 %
    274 %  ConvertHSBToRGB() transforms a (hue, saturation, brightness) to a (red,
    275 %  green, blue) triple.
    276 %
    277 %  The format of the ConvertHSBToRGBImage method is:
    278 %
    279 %      void ConvertHSBToRGB(const double hue,const double saturation,
    280 %        const double brightness,double *red,double *green,double *blue)
    281 %
    282 %  A description of each parameter follows:
    283 %
    284 %    o hue, saturation, brightness: A double value representing a
    285 %      component of the HSB color space.
    286 %
    287 %    o red, green, blue: A pointer to a pixel component of type Quantum.
    288 %
    289 */
    290 MagickPrivate void ConvertHSBToRGB(const double hue,const double saturation,
    291   const double brightness,double *red,double *green,double *blue)
    292 {
    293   double
    294     f,
    295     h,
    296     p,
    297     q,
    298     t;
    299 
    300   /*
    301     Convert HSB to RGB colorspace.
    302   */
    303   assert(red != (double *) NULL);
    304   assert(green != (double *) NULL);
    305   assert(blue != (double *) NULL);
    306   if (fabs(saturation) < MagickEpsilon)
    307     {
    308       *red=QuantumRange*brightness;
    309       *green=(*red);
    310       *blue=(*red);
    311       return;
    312     }
    313   h=6.0*(hue-floor(hue));
    314   f=h-floor((double) h);
    315   p=brightness*(1.0-saturation);
    316   q=brightness*(1.0-saturation*f);
    317   t=brightness*(1.0-(saturation*(1.0-f)));
    318   switch ((int) h)
    319   {
    320     case 0:
    321     default:
    322     {
    323       *red=QuantumRange*brightness;
    324       *green=QuantumRange*t;
    325       *blue=QuantumRange*p;
    326       break;
    327     }
    328     case 1:
    329     {
    330       *red=QuantumRange*q;
    331       *green=QuantumRange*brightness;
    332       *blue=QuantumRange*p;
    333       break;
    334     }
    335     case 2:
    336     {
    337       *red=QuantumRange*p;
    338       *green=QuantumRange*brightness;
    339       *blue=QuantumRange*t;
    340       break;
    341     }
    342     case 3:
    343     {
    344       *red=QuantumRange*p;
    345       *green=QuantumRange*q;
    346       *blue=QuantumRange*brightness;
    347       break;
    348     }
    349     case 4:
    350     {
    351       *red=QuantumRange*t;
    352       *green=QuantumRange*p;
    353       *blue=QuantumRange*brightness;
    354       break;
    355     }
    356     case 5:
    357     {
    358       *red=QuantumRange*brightness;
    359       *green=QuantumRange*p;
    360       *blue=QuantumRange*q;
    361       break;
    362     }
    363   }
    364 }
    365 
    366 /*
    368 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    369 %                                                                             %
    370 %                                                                             %
    371 %                                                                             %
    372 %   C o n v e r t H S I T o R G B                                             %
    373 %                                                                             %
    374 %                                                                             %
    375 %                                                                             %
    376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    377 %
    378 %  ConvertHSIToRGB() transforms a (hue, saturation, intensity) to a (red,
    379 %  green, blue) triple.
    380 %
    381 %  The format of the ConvertHSIToRGBImage method is:
    382 %
    383 %      void ConvertHSIToRGB(const double hue,const double saturation,
    384 %        const double intensity,double *red,double *green,double *blue)
    385 %
    386 %  A description of each parameter follows:
    387 %
    388 %    o hue, saturation, intensity: A double value representing a
    389 %      component of the HSI color space.
    390 %
    391 %    o red, green, blue: A pointer to a pixel component of type Quantum.
    392 %
    393 */
    394 MagickPrivate void ConvertHSIToRGB(const double hue,const double saturation,
    395   const double intensity,double *red,double *green,double *blue)
    396 {
    397   double
    398     b,
    399     g,
    400     h,
    401     r;
    402 
    403   /*
    404     Convert HSI to RGB colorspace.
    405   */
    406   assert(red != (double *) NULL);
    407   assert(green != (double *) NULL);
    408   assert(blue != (double *) NULL);
    409   h=360.0*hue;
    410   h-=360.0*floor(h/360.0);
    411   if (h < 120.0)
    412     {
    413       b=intensity*(1.0-saturation);
    414       r=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
    415         (MagickPI/180.0)));
    416       g=3.0*intensity-r-b;
    417     }
    418   else
    419     if (h < 240.0)
    420       {
    421         h-=120.0;
    422         r=intensity*(1.0-saturation);
    423         g=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
    424           (MagickPI/180.0)));
    425         b=3.0*intensity-r-g;
    426       }
    427     else
    428       {
    429         h-=240.0;
    430         g=intensity*(1.0-saturation);
    431         b=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
    432           (MagickPI/180.0)));
    433         r=3.0*intensity-g-b;
    434       }
    435   *red=QuantumRange*r;
    436   *green=QuantumRange*g;
    437   *blue=QuantumRange*b;
    438 }
    439 
    440 /*
    442 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    443 %                                                                             %
    444 %                                                                             %
    445 %                                                                             %
    446 %   C o n v e r t H S L T o R G B                                             %
    447 %                                                                             %
    448 %                                                                             %
    449 %                                                                             %
    450 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    451 %
    452 %  ConvertHSLToRGB() transforms a (hue, saturation, lightness) to a (red,
    453 %  green, blue) triple.
    454 %
    455 %  The format of the ConvertHSLToRGBImage method is:
    456 %
    457 %      void ConvertHSLToRGB(const double hue,const double saturation,
    458 %        const double lightness,double *red,double *green,double *blue)
    459 %
    460 %  A description of each parameter follows:
    461 %
    462 %    o hue, saturation, lightness: A double value representing a
    463 %      component of the HSL color space.
    464 %
    465 %    o red, green, blue: A pointer to a pixel component of type Quantum.
    466 %
    467 */
    468 MagickExport void ConvertHSLToRGB(const double hue,const double saturation,
    469   const double lightness,double *red,double *green,double *blue)
    470 {
    471   double
    472     c,
    473     h,
    474     min,
    475     x;
    476 
    477   /*
    478     Convert HSL to RGB colorspace.
    479   */
    480   assert(red != (double *) NULL);
    481   assert(green != (double *) NULL);
    482   assert(blue != (double *) NULL);
    483   h=hue*360.0;
    484   if (lightness <= 0.5)
    485     c=2.0*lightness*saturation;
    486   else
    487     c=(2.0-2.0*lightness)*saturation;
    488   min=lightness-0.5*c;
    489   h-=360.0*floor(h/360.0);
    490   h/=60.0;
    491   x=c*(1.0-fabs(h-2.0*floor(h/2.0)-1.0));
    492   switch ((int) floor(h))
    493   {
    494     case 0:
    495     {
    496       *red=QuantumRange*(min+c);
    497       *green=QuantumRange*(min+x);
    498       *blue=QuantumRange*min;
    499       break;
    500     }
    501     case 1:
    502     {
    503       *red=QuantumRange*(min+x);
    504       *green=QuantumRange*(min+c);
    505       *blue=QuantumRange*min;
    506       break;
    507     }
    508     case 2:
    509     {
    510       *red=QuantumRange*min;
    511       *green=QuantumRange*(min+c);
    512       *blue=QuantumRange*(min+x);
    513       break;
    514     }
    515     case 3:
    516     {
    517       *red=QuantumRange*min;
    518       *green=QuantumRange*(min+x);
    519       *blue=QuantumRange*(min+c);
    520       break;
    521     }
    522     case 4:
    523     {
    524       *red=QuantumRange*(min+x);
    525       *green=QuantumRange*min;
    526       *blue=QuantumRange*(min+c);
    527       break;
    528     }
    529     case 5:
    530     {
    531       *red=QuantumRange*(min+c);
    532       *green=QuantumRange*min;
    533       *blue=QuantumRange*(min+x);
    534       break;
    535     }
    536     default:
    537     {
    538       *red=0.0;
    539       *green=0.0;
    540       *blue=0.0;
    541     }
    542   }
    543 }
    544 
    545 /*
    547 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    548 %                                                                             %
    549 %                                                                             %
    550 %                                                                             %
    551 %   C o n v e r t H S V T o R G B                                             %
    552 %                                                                             %
    553 %                                                                             %
    554 %                                                                             %
    555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    556 %
    557 %  ConvertHSVToRGB() transforms a (hue, saturation, value) to a (red,
    558 %  green, blue) triple.
    559 %
    560 %  The format of the ConvertHSVToRGBImage method is:
    561 %
    562 %      void ConvertHSVToRGB(const double hue,const double saturation,
    563 %        const double value,double *red,double *green,double *blue)
    564 %
    565 %  A description of each parameter follows:
    566 %
    567 %    o hue, saturation, value: A double value representing a
    568 %      component of the HSV color space.
    569 %
    570 %    o red, green, blue: A pointer to a pixel component of type Quantum.
    571 %
    572 */
    573 MagickPrivate void ConvertHSVToRGB(const double hue,const double saturation,
    574   const double value,double *red,double *green,double *blue)
    575 {
    576   double
    577     c,
    578     h,
    579     min,
    580     x;
    581 
    582   /*
    583     Convert HSV to RGB colorspace.
    584   */
    585   assert(red != (double *) NULL);
    586   assert(green != (double *) NULL);
    587   assert(blue != (double *) NULL);
    588   h=hue*360.0;
    589   c=value*saturation;
    590   min=value-c;
    591   h-=360.0*floor(h/360.0);
    592   h/=60.0;
    593   x=c*(1.0-fabs(h-2.0*floor(h/2.0)-1.0));
    594   switch ((int) floor(h))
    595   {
    596     case 0:
    597     {
    598       *red=QuantumRange*(min+c);
    599       *green=QuantumRange*(min+x);
    600       *blue=QuantumRange*min;
    601       break;
    602     }
    603     case 1:
    604     {
    605       *red=QuantumRange*(min+x);
    606       *green=QuantumRange*(min+c);
    607       *blue=QuantumRange*min;
    608       break;
    609     }
    610     case 2:
    611     {
    612       *red=QuantumRange*min;
    613       *green=QuantumRange*(min+c);
    614       *blue=QuantumRange*(min+x);
    615       break;
    616     }
    617     case 3:
    618     {
    619       *red=QuantumRange*min;
    620       *green=QuantumRange*(min+x);
    621       *blue=QuantumRange*(min+c);
    622       break;
    623     }
    624     case 4:
    625     {
    626       *red=QuantumRange*(min+x);
    627       *green=QuantumRange*min;
    628       *blue=QuantumRange*(min+c);
    629       break;
    630     }
    631     case 5:
    632     {
    633       *red=QuantumRange*(min+c);
    634       *green=QuantumRange*min;
    635       *blue=QuantumRange*(min+x);
    636       break;
    637     }
    638     default:
    639     {
    640       *red=0.0;
    641       *green=0.0;
    642       *blue=0.0;
    643     }
    644   }
    645 }
    646 
    647 /*
    649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    650 %                                                                             %
    651 %                                                                             %
    652 %                                                                             %
    653 %   C o n v e r t H W B T o R G B                                             %
    654 %                                                                             %
    655 %                                                                             %
    656 %                                                                             %
    657 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    658 %
    659 %  ConvertHWBToRGB() transforms a (hue, whiteness, blackness) to a (red, green,
    660 %  blue) triple.
    661 %
    662 %  The format of the ConvertHWBToRGBImage method is:
    663 %
    664 %      void ConvertHWBToRGB(const double hue,const double whiteness,
    665 %        const double blackness,double *red,double *green,double *blue)
    666 %
    667 %  A description of each parameter follows:
    668 %
    669 %    o hue, whiteness, blackness: A double value representing a
    670 %      component of the HWB color space.
    671 %
    672 %    o red, green, blue: A pointer to a pixel component of type Quantum.
    673 %
    674 */
    675 MagickPrivate void ConvertHWBToRGB(const double hue,const double whiteness,
    676   const double blackness,double *red,double *green,double *blue)
    677 {
    678   double
    679     b,
    680     f,
    681     g,
    682     n,
    683     r,
    684     v;
    685 
    686   register ssize_t
    687     i;
    688 
    689   /*
    690     Convert HWB to RGB colorspace.
    691   */
    692   assert(red != (double *) NULL);
    693   assert(green != (double *) NULL);
    694   assert(blue != (double *) NULL);
    695   v=1.0-blackness;
    696   if (fabs(hue-(-1.0)) < MagickEpsilon)
    697     {
    698       *red=QuantumRange*v;
    699       *green=QuantumRange*v;
    700       *blue=QuantumRange*v;
    701       return;
    702     }
    703   i=(ssize_t) floor(6.0*hue);
    704   f=6.0*hue-i;
    705   if ((i & 0x01) != 0)
    706     f=1.0-f;
    707   n=whiteness+f*(v-whiteness);  /* linear interpolation */
    708   switch (i)
    709   {
    710     default:
    711     case 6:
    712     case 0: r=v; g=n; b=whiteness; break;
    713     case 1: r=n; g=v; b=whiteness; break;
    714     case 2: r=whiteness; g=v; b=n; break;
    715     case 3: r=whiteness; g=n; b=v; break;
    716     case 4: r=n; g=whiteness; b=v; break;
    717     case 5: r=v; g=whiteness; b=n; break;
    718   }
    719   *red=QuantumRange*r;
    720   *green=QuantumRange*g;
    721   *blue=QuantumRange*b;
    722 }
    723 
    724 /*
    726 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    727 %                                                                             %
    728 %                                                                             %
    729 %                                                                             %
    730 %   C o n v e r t L C H a b T o R G B                                         %
    731 %                                                                             %
    732 %                                                                             %
    733 %                                                                             %
    734 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    735 %
    736 %  ConvertLCHabToRGB() transforms a (luma, chroma, hue) to a (red, green,
    737 %  blue) triple.
    738 %
    739 %  The format of the ConvertLCHabToRGBImage method is:
    740 %
    741 %      void ConvertLCHabToRGB(const double luma,const double chroma,
    742 %        const double hue,double *red,double *green,double *blue)
    743 %
    744 %  A description of each parameter follows:
    745 %
    746 %    o luma, chroma, hue: A double value representing a component of the
    747 %      LCHab color space.
    748 %
    749 %    o red, green, blue: A pointer to a pixel component of type Quantum.
    750 %
    751 */
    752 
    753 static inline void ConvertLCHabToXYZ(const double luma,const double chroma,
    754   const double hue,double *X,double *Y,double *Z)
    755 {
    756   ConvertLabToXYZ(luma,chroma*cos(hue*MagickPI/180.0),chroma*
    757     sin(hue*MagickPI/180.0),X,Y,Z);
    758 }
    759 
    760 MagickPrivate void ConvertLCHabToRGB(const double luma,const double chroma,
    761   const double hue,double *red,double *green,double *blue)
    762 {
    763   double
    764     X,
    765     Y,
    766     Z;
    767 
    768   /*
    769     Convert LCHab to RGB colorspace.
    770   */
    771   assert(red != (double *) NULL);
    772   assert(green != (double *) NULL);
    773   assert(blue != (double *) NULL);
    774   ConvertLCHabToXYZ(100.0*luma,255.0*(chroma-0.5),360.0*hue,&X,&Y,&Z);
    775   ConvertXYZToRGB(X,Y,Z,red,green,blue);
    776 }
    777 
    778 /*
    780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    781 %                                                                             %
    782 %                                                                             %
    783 %                                                                             %
    784 %   C o n v e r t L C H u v T o R G B                                         %
    785 %                                                                             %
    786 %                                                                             %
    787 %                                                                             %
    788 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    789 %
    790 %  ConvertLCHuvToRGB() transforms a (luma, chroma, hue) to a (red, green,
    791 %  blue) triple.
    792 %
    793 %  The format of the ConvertLCHuvToRGBImage method is:
    794 %
    795 %      void ConvertLCHuvToRGB(const double luma,const double chroma,
    796 %        const double hue,double *red,double *green,double *blue)
    797 %
    798 %  A description of each parameter follows:
    799 %
    800 %    o luma, chroma, hue: A double value representing a component of the
    801 %      LCHuv color space.
    802 %
    803 %    o red, green, blue: A pointer to a pixel component of type Quantum.
    804 %
    805 */
    806 
    807 static inline void ConvertLCHuvToXYZ(const double luma,const double chroma,
    808   const double hue,double *X,double *Y,double *Z)
    809 {
    810   ConvertLuvToXYZ(luma,chroma*cos(hue*MagickPI/180.0),chroma*
    811     sin(hue*MagickPI/180.0),X,Y,Z);
    812 }
    813 
    814 MagickPrivate void ConvertLCHuvToRGB(const double luma,const double chroma,
    815   const double hue,double *red,double *green,double *blue)
    816 {
    817   double
    818     X,
    819     Y,
    820     Z;
    821 
    822   /*
    823     Convert LCHuv to RGB colorspace.
    824   */
    825   assert(red != (double *) NULL);
    826   assert(green != (double *) NULL);
    827   assert(blue != (double *) NULL);
    828   ConvertLCHuvToXYZ(100.0*luma,255.0*(chroma-0.5),360.0*hue,&X,&Y,&Z);
    829   ConvertXYZToRGB(X,Y,Z,red,green,blue);
    830 }
    831 
    832 /*
    834 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    835 %                                                                             %
    836 %                                                                             %
    837 %                                                                             %
    838 %   C o n v e r t R G B T o H C L                                             %
    839 %                                                                             %
    840 %                                                                             %
    841 %                                                                             %
    842 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    843 %
    844 %  ConvertRGBToHCL() transforms a (red, green, blue) to a (hue, chroma,
    845 %  luma) triple.
    846 %
    847 %  The format of the ConvertRGBToHCL method is:
    848 %
    849 %      void ConvertRGBToHCL(const double red,const double green,
    850 %        const double blue,double *hue,double *chroma,double *luma)
    851 %
    852 %  A description of each parameter follows:
    853 %
    854 %    o red, green, blue: A Quantum value representing the red, green, and
    855 %      blue component of a pixel.
    856 %
    857 %    o hue, chroma, luma: A pointer to a double value representing a
    858 %      component of the HCL color space.
    859 %
    860 */
    861 MagickPrivate void ConvertRGBToHCL(const double red,const double green,
    862   const double blue,double *hue,double *chroma,double *luma)
    863 {
    864   double
    865     c,
    866     h,
    867     max;
    868 
    869   /*
    870     Convert RGB to HCL colorspace.
    871   */
    872   assert(hue != (double *) NULL);
    873   assert(chroma != (double *) NULL);
    874   assert(luma != (double *) NULL);
    875   max=MagickMax(red,MagickMax(green,blue));
    876   c=max-(double) MagickMin(red,MagickMin(green,blue));
    877   h=0.0;
    878   if (fabs(c) < MagickEpsilon)
    879     h=0.0;
    880   else
    881     if (fabs(red-max) < MagickEpsilon)
    882       h=fmod((green-blue)/c+6.0,6.0);
    883     else
    884       if (fabs(green-max) < MagickEpsilon)
    885         h=((blue-red)/c)+2.0;
    886       else
    887         if (fabs(blue-max) < MagickEpsilon)
    888           h=((red-green)/c)+4.0;
    889   *hue=(h/6.0);
    890   *chroma=QuantumScale*c;
    891   *luma=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
    892 }
    893 
    894 /*
    896 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    897 %                                                                             %
    898 %                                                                             %
    899 %                                                                             %
    900 %   C o n v e r t R G B T o H C L p                                           %
    901 %                                                                             %
    902 %                                                                             %
    903 %                                                                             %
    904 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    905 %
    906 %  ConvertRGBToHCLp() transforms a (red, green, blue) to a (hue, chroma,
    907 %  luma) triple.
    908 %
    909 %  The format of the ConvertRGBToHCLp method is:
    910 %
    911 %      void ConvertRGBToHCLp(const double red,const double green,
    912 %        const double blue,double *hue,double *chroma,double *luma)
    913 %
    914 %  A description of each parameter follows:
    915 %
    916 %    o red, green, blue: A Quantum value representing the red, green, and
    917 %      blue component of a pixel.
    918 %
    919 %    o hue, chroma, luma: A pointer to a double value representing a
    920 %      component of the HCL color space.
    921 %
    922 */
    923 MagickPrivate void ConvertRGBToHCLp(const double red,const double green,
    924   const double blue,double *hue,double *chroma,double *luma)
    925 {
    926   double
    927     c,
    928     h,
    929     max;
    930 
    931   /*
    932     Convert RGB to HCL colorspace.
    933   */
    934   assert(hue != (double *) NULL);
    935   assert(chroma != (double *) NULL);
    936   assert(luma != (double *) NULL);
    937   max=MagickMax(red,MagickMax(green,blue));
    938   c=max-MagickMin(red,MagickMin(green,blue));
    939   h=0.0;
    940   if (fabs(c) < MagickEpsilon)
    941     h=0.0;
    942   else
    943     if (fabs(red-max) < MagickEpsilon)
    944       h=fmod((green-blue)/c+6.0,6.0);
    945     else
    946       if (fabs(green-max) < MagickEpsilon)
    947         h=((blue-red)/c)+2.0;
    948       else
    949         if (fabs(blue-max) < MagickEpsilon)
    950           h=((red-green)/c)+4.0;
    951   *hue=(h/6.0);
    952   *chroma=QuantumScale*c;
    953   *luma=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
    954 }
    955 
    956 /*
    958 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    959 %                                                                             %
    960 %                                                                             %
    961 %                                                                             %
    962 %   C o n v e r t R G B T o H S B                                             %
    963 %                                                                             %
    964 %                                                                             %
    965 %                                                                             %
    966 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    967 %
    968 %  ConvertRGBToHSB() transforms a (red, green, blue) to a (hue, saturation,
    969 %  brightness) triple.
    970 %
    971 %  The format of the ConvertRGBToHSB method is:
    972 %
    973 %      void ConvertRGBToHSB(const double red,const double green,
    974 %        const double blue,double *hue,double *saturation,double *brightness)
    975 %
    976 %  A description of each parameter follows:
    977 %
    978 %    o red, green, blue: A Quantum value representing the red, green, and
    979 %      blue component of a pixel..
    980 %
    981 %    o hue, saturation, brightness: A pointer to a double value representing a
    982 %      component of the HSB color space.
    983 %
    984 */
    985 MagickPrivate void ConvertRGBToHSB(const double red,const double green,
    986   const double blue,double *hue,double *saturation,double *brightness)
    987 {
    988   double
    989     delta,
    990     max,
    991     min;
    992 
    993   /*
    994     Convert RGB to HSB colorspace.
    995   */
    996   assert(hue != (double *) NULL);
    997   assert(saturation != (double *) NULL);
    998   assert(brightness != (double *) NULL);
    999   *hue=0.0;
   1000   *saturation=0.0;
   1001   *brightness=0.0;
   1002   min=red < green ? red : green;
   1003   if (blue < min)
   1004     min=blue;
   1005   max=red > green ? red : green;
   1006   if (blue > max)
   1007     max=blue;
   1008   if (fabs(max) < MagickEpsilon)
   1009     return;
   1010   delta=max-min;
   1011   *saturation=delta/max;
   1012   *brightness=QuantumScale*max;
   1013   if (fabs(delta) < MagickEpsilon)
   1014     return;
   1015   if (fabs(red-max) < MagickEpsilon)
   1016     *hue=(green-blue)/delta;
   1017   else
   1018     if (fabs(green-max) < MagickEpsilon)
   1019       *hue=2.0+(blue-red)/delta;
   1020     else
   1021       *hue=4.0+(red-green)/delta;
   1022   *hue/=6.0;
   1023   if (*hue < 0.0)
   1024     *hue+=1.0;
   1025 }
   1026 
   1027 /*
   1029 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1030 %                                                                             %
   1031 %                                                                             %
   1032 %                                                                             %
   1033 %   C o n v e r t R G B T o H S I                                             %
   1034 %                                                                             %
   1035 %                                                                             %
   1036 %                                                                             %
   1037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1038 %
   1039 %  ConvertRGBToHSI() transforms a (red, green, blue) to a (hue, saturation,
   1040 %  intensity) triple.
   1041 %
   1042 %  The format of the ConvertRGBToHSI method is:
   1043 %
   1044 %      void ConvertRGBToHSI(const double red,const double green,
   1045 %        const double blue,double *hue,double *saturation,double *intensity)
   1046 %
   1047 %  A description of each parameter follows:
   1048 %
   1049 %    o red, green, blue: A Quantum value representing the red, green, and
   1050 %      blue component of a pixel..
   1051 %
   1052 %    o hue, saturation, intensity: A pointer to a double value representing a
   1053 %      component of the HSI color space.
   1054 %
   1055 */
   1056 MagickPrivate void ConvertRGBToHSI(const double red,const double green,
   1057   const double blue,double *hue,double *saturation,double *intensity)
   1058 {
   1059   double
   1060     alpha,
   1061     beta;
   1062 
   1063   /*
   1064     Convert RGB to HSI colorspace.
   1065   */
   1066   assert(hue != (double *) NULL);
   1067   assert(saturation != (double *) NULL);
   1068   assert(intensity != (double *) NULL);
   1069   *intensity=(QuantumScale*red+QuantumScale*green+QuantumScale*blue)/3.0;
   1070   if (*intensity <= 0.0)
   1071     {
   1072       *hue=0.0;
   1073       *saturation=0.0;
   1074       return;
   1075     }
   1076   *saturation=1.0-MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
   1077     QuantumScale*blue))/(*intensity);
   1078   alpha=0.5*(2.0*QuantumScale*red-QuantumScale*green-QuantumScale*blue);
   1079   beta=0.8660254037844385*(QuantumScale*green-QuantumScale*blue);
   1080   *hue=atan2(beta,alpha)*(180.0/MagickPI)/360.0;
   1081   if (*hue < 0.0)
   1082     *hue+=1.0;
   1083 }
   1084 
   1085 /*
   1087 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1088 %                                                                             %
   1089 %                                                                             %
   1090 %                                                                             %
   1091 %   C o n v e r t R G B T o H S L                                             %
   1092 %                                                                             %
   1093 %                                                                             %
   1094 %                                                                             %
   1095 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1096 %
   1097 %  ConvertRGBToHSL() transforms a (red, green, blue) to a (hue, saturation,
   1098 %  lightness) triple.
   1099 %
   1100 %  The format of the ConvertRGBToHSL method is:
   1101 %
   1102 %      void ConvertRGBToHSL(const double red,const double green,
   1103 %        const double blue,double *hue,double *saturation,double *lightness)
   1104 %
   1105 %  A description of each parameter follows:
   1106 %
   1107 %    o red, green, blue: A Quantum value representing the red, green, and
   1108 %      blue component of a pixel..
   1109 %
   1110 %    o hue, saturation, lightness: A pointer to a double value representing a
   1111 %      component of the HSL color space.
   1112 %
   1113 */
   1114 MagickExport void ConvertRGBToHSL(const double red,const double green,
   1115   const double blue,double *hue,double *saturation,double *lightness)
   1116 {
   1117   double
   1118     c,
   1119     max,
   1120     min;
   1121 
   1122   /*
   1123     Convert RGB to HSL colorspace.
   1124   */
   1125   assert(hue != (double *) NULL);
   1126   assert(saturation != (double *) NULL);
   1127   assert(lightness != (double *) NULL);
   1128   max=MagickMax(QuantumScale*red,MagickMax(QuantumScale*green,
   1129     QuantumScale*blue));
   1130   min=MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
   1131     QuantumScale*blue));
   1132   c=max-min;
   1133   *lightness=(max+min)/2.0;
   1134   if (c <= 0.0)
   1135     {
   1136       *hue=0.0;
   1137       *saturation=0.0;
   1138       return;
   1139     }
   1140   if (fabs(max-QuantumScale*red) < MagickEpsilon)
   1141     {
   1142       *hue=(QuantumScale*green-QuantumScale*blue)/c;
   1143       if ((QuantumScale*green) < (QuantumScale*blue))
   1144         *hue+=6.0;
   1145     }
   1146   else
   1147     if (fabs(max-QuantumScale*green) < MagickEpsilon)
   1148       *hue=2.0+(QuantumScale*blue-QuantumScale*red)/c;
   1149     else
   1150       *hue=4.0+(QuantumScale*red-QuantumScale*green)/c;
   1151   *hue*=60.0/360.0;
   1152   if (*lightness <= 0.5)
   1153     *saturation=c/(2.0*(*lightness));
   1154   else
   1155     *saturation=c/(2.0-2.0*(*lightness));
   1156 }
   1157 
   1158 /*
   1160 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1161 %                                                                             %
   1162 %                                                                             %
   1163 %                                                                             %
   1164 %   C o n v e r t R G B T o H S V                                             %
   1165 %                                                                             %
   1166 %                                                                             %
   1167 %                                                                             %
   1168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1169 %
   1170 %  ConvertRGBToHSV() transforms a (red, green, blue) to a (hue, saturation,
   1171 %  value) triple.
   1172 %
   1173 %  The format of the ConvertRGBToHSV method is:
   1174 %
   1175 %      void ConvertRGBToHSV(const double red,const double green,
   1176 %        const double blue,double *hue,double *saturation,double *value)
   1177 %
   1178 %  A description of each parameter follows:
   1179 %
   1180 %    o red, green, blue: A Quantum value representing the red, green, and
   1181 %      blue component of a pixel..
   1182 %
   1183 %    o hue, saturation, value: A pointer to a double value representing a
   1184 %      component of the HSV color space.
   1185 %
   1186 */
   1187 MagickPrivate void ConvertRGBToHSV(const double red,const double green,
   1188   const double blue,double *hue,double *saturation,double *value)
   1189 {
   1190   double
   1191     c,
   1192     max,
   1193     min;
   1194 
   1195   /*
   1196     Convert RGB to HSV colorspace.
   1197   */
   1198   assert(hue != (double *) NULL);
   1199   assert(saturation != (double *) NULL);
   1200   assert(value != (double *) NULL);
   1201   max=MagickMax(QuantumScale*red,MagickMax(QuantumScale*green,
   1202     QuantumScale*blue));
   1203   min=MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
   1204     QuantumScale*blue));
   1205   c=max-min;
   1206   *value=max;
   1207   if (c <= 0.0)
   1208     {
   1209       *hue=0.0;
   1210       *saturation=0.0;
   1211       return;
   1212     }
   1213   if (fabs(max-QuantumScale*red) < MagickEpsilon)
   1214     {
   1215       *hue=(QuantumScale*green-QuantumScale*blue)/c;
   1216       if ((QuantumScale*green) < (QuantumScale*blue))
   1217         *hue+=6.0;
   1218     }
   1219   else
   1220     if (fabs(max-QuantumScale*green) < MagickEpsilon)
   1221       *hue=2.0+(QuantumScale*blue-QuantumScale*red)/c;
   1222     else
   1223       *hue=4.0+(QuantumScale*red-QuantumScale*green)/c;
   1224   *hue*=60.0/360.0;
   1225   *saturation=c/max;
   1226 }
   1227 
   1228 /*
   1230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1231 %                                                                             %
   1232 %                                                                             %
   1233 %                                                                             %
   1234 %   C o n v e r t R G B T o H W B                                             %
   1235 %                                                                             %
   1236 %                                                                             %
   1237 %                                                                             %
   1238 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1239 %
   1240 %  ConvertRGBToHWB() transforms a (red, green, blue) to a (hue, whiteness,
   1241 %  blackness) triple.
   1242 %
   1243 %  The format of the ConvertRGBToHWB method is:
   1244 %
   1245 %      void ConvertRGBToHWB(const double red,const double green,
   1246 %        const double blue,double *hue,double *whiteness,double *blackness)
   1247 %
   1248 %  A description of each parameter follows:
   1249 %
   1250 %    o red, green, blue: A Quantum value representing the red, green, and
   1251 %      blue component of a pixel.
   1252 %
   1253 %    o hue, whiteness, blackness: A pointer to a double value representing a
   1254 %      component of the HWB color space.
   1255 %
   1256 */
   1257 MagickPrivate void ConvertRGBToHWB(const double red,const double green,
   1258   const double blue,double *hue,double *whiteness,double *blackness)
   1259 {
   1260   double
   1261     f,
   1262     p,
   1263     v,
   1264     w;
   1265 
   1266   /*
   1267     Convert RGB to HWB colorspace.
   1268   */
   1269   assert(hue != (double *) NULL);
   1270   assert(whiteness != (double *) NULL);
   1271   assert(blackness != (double *) NULL);
   1272   w=MagickMin(red,MagickMin(green,blue));
   1273   v=MagickMax(red,MagickMax(green,blue));
   1274   *blackness=1.0-QuantumScale*v;
   1275   *whiteness=QuantumScale*w;
   1276   if (fabs(v-w) < MagickEpsilon)
   1277     {
   1278       *hue=(-1.0);
   1279       return;
   1280     }
   1281   f=(fabs(red-w) < MagickEpsilon) ? green-blue :
   1282     ((fabs(green-w) < MagickEpsilon) ? blue-red : red-green);
   1283   p=(fabs(red-w) < MagickEpsilon) ? 3.0 :
   1284     ((fabs(green-w) < MagickEpsilon) ? 5.0 : 1.0);
   1285   *hue=(p-f/(v-1.0*w))/6.0;
   1286 }
   1287 
   1288 /*
   1290 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1291 %                                                                             %
   1292 %                                                                             %
   1293 %                                                                             %
   1294 %   C o n v e r t R G B T o L C H a b                                         %
   1295 %                                                                             %
   1296 %                                                                             %
   1297 %                                                                             %
   1298 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1299 %
   1300 %  ConvertRGBToLCHab() transforms a (red, green, blue) to a (luma, chroma,
   1301 %  hue) triple.
   1302 %
   1303 %  The format of the ConvertRGBToLCHab method is:
   1304 %
   1305 %      void ConvertRGBToLCHab(const double red,const double green,
   1306 %        const double blue,double *luma,double *chroma,double *hue)
   1307 %
   1308 %  A description of each parameter follows:
   1309 %
   1310 %    o red, green, blue: A Quantum value representing the red, green, and
   1311 %      blue component of a pixel.
   1312 %
   1313 %    o luma, chroma, hue: A pointer to a double value representing a
   1314 %      component of the LCH color space.
   1315 %
   1316 */
   1317 
   1318 static inline void ConvertXYZToLCHab(const double X,const double Y,
   1319   const double Z,double *luma,double *chroma,double *hue)
   1320 {
   1321   double
   1322     a,
   1323     b;
   1324 
   1325   ConvertXYZToLab(X,Y,Z,luma,&a,&b);
   1326   *chroma=hypot(255.0*(a-0.5),255.0*(b-0.5))/255.0+0.5;
   1327   *hue=180.0*atan2(255.0*(b-0.5),255.0*(a-0.5))/MagickPI/360.0;
   1328   if (*hue < 0.0)
   1329     *hue+=1.0;
   1330 }
   1331 
   1332 MagickPrivate void ConvertRGBToLCHab(const double red,const double green,
   1333   const double blue,double *luma,double *chroma,double *hue)
   1334 {
   1335   double
   1336     X,
   1337     Y,
   1338     Z;
   1339 
   1340   /*
   1341     Convert RGB to LCHab colorspace.
   1342   */
   1343   assert(luma != (double *) NULL);
   1344   assert(chroma != (double *) NULL);
   1345   assert(hue != (double *) NULL);
   1346   ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
   1347   ConvertXYZToLCHab(X,Y,Z,luma,chroma,hue);
   1348 }
   1349 
   1350 /*
   1352 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1353 %                                                                             %
   1354 %                                                                             %
   1355 %                                                                             %
   1356 %   C o n v e r t R G B T o L C H u v                                         %
   1357 %                                                                             %
   1358 %                                                                             %
   1359 %                                                                             %
   1360 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1361 %
   1362 %  ConvertRGBToLCHuv() transforms a (red, green, blue) to a (luma, chroma,
   1363 %  hue) triple.
   1364 %
   1365 %  The format of the ConvertRGBToLCHuv method is:
   1366 %
   1367 %      void ConvertRGBToLCHuv(const double red,const double green,
   1368 %        const double blue,double *luma,double *chroma,double *hue)
   1369 %
   1370 %  A description of each parameter follows:
   1371 %
   1372 %    o red, green, blue: A Quantum value representing the red, green, and
   1373 %      blue component of a pixel.
   1374 %
   1375 %    o luma, chroma, hue: A pointer to a double value representing a
   1376 %      component of the LCHuv color space.
   1377 %
   1378 */
   1379 
   1380 static inline void ConvertXYZToLCHuv(const double X,const double Y,
   1381   const double Z,double *luma,double *chroma,double *hue)
   1382 {
   1383   double
   1384     u,
   1385     v;
   1386 
   1387   ConvertXYZToLuv(X,Y,Z,luma,&u,&v);
   1388   *chroma=hypot(354.0*u-134.0,262.0*v-140.0)/255.0+0.5;
   1389   *hue=180.0*atan2(262.0*v-140.0,354.0*u-134.0)/MagickPI/360.0;
   1390   if (*hue < 0.0)
   1391     *hue+=1.0;
   1392 }
   1393 
   1394 MagickPrivate void ConvertRGBToLCHuv(const double red,const double green,
   1395   const double blue,double *luma,double *chroma,double *hue)
   1396 {
   1397   double
   1398     X,
   1399     Y,
   1400     Z;
   1401 
   1402   /*
   1403     Convert RGB to LCHuv colorspace.
   1404   */
   1405   assert(luma != (double *) NULL);
   1406   assert(chroma != (double *) NULL);
   1407   assert(hue != (double *) NULL);
   1408   ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
   1409   ConvertXYZToLCHuv(X,Y,Z,luma,chroma,hue);
   1410 }
   1411 
   1412 /*
   1414 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1415 %                                                                             %
   1416 %                                                                             %
   1417 %                                                                             %
   1418 %   E x p a n d A f f i n e                                                   %
   1419 %                                                                             %
   1420 %                                                                             %
   1421 %                                                                             %
   1422 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1423 %
   1424 %  ExpandAffine() computes the affine's expansion factor, i.e. the square root
   1425 %  of the factor by which the affine transform affects area. In an affine
   1426 %  transform composed of scaling, rotation, shearing, and translation, returns
   1427 %  the amount of scaling.
   1428 %
   1429 %  The format of the ExpandAffine method is:
   1430 %
   1431 %      double ExpandAffine(const AffineMatrix *affine)
   1432 %
   1433 %  A description of each parameter follows:
   1434 %
   1435 %    o expansion: ExpandAffine returns the affine's expansion factor.
   1436 %
   1437 %    o affine: A pointer the affine transform of type AffineMatrix.
   1438 %
   1439 */
   1440 MagickExport double ExpandAffine(const AffineMatrix *affine)
   1441 {
   1442   assert(affine != (const AffineMatrix *) NULL);
   1443   return(sqrt(fabs(affine->sx*affine->sy-affine->rx*affine->ry)));
   1444 }
   1445 
   1446 /*
   1448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1449 %                                                                             %
   1450 %                                                                             %
   1451 %                                                                             %
   1452 %   G e n e r a t e D i f f e r e n t i a l N o i s e                         %
   1453 %                                                                             %
   1454 %                                                                             %
   1455 %                                                                             %
   1456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1457 %
   1458 %  GenerateDifferentialNoise() generates differentual noise.
   1459 %
   1460 %  The format of the GenerateDifferentialNoise method is:
   1461 %
   1462 %      double GenerateDifferentialNoise(RandomInfo *random_info,
   1463 %        const Quantum pixel,const NoiseType noise_type,const double attenuate)
   1464 %
   1465 %  A description of each parameter follows:
   1466 %
   1467 %    o random_info: the random info.
   1468 %
   1469 %    o pixel: noise is relative to this pixel value.
   1470 %
   1471 %    o noise_type: the type of noise.
   1472 %
   1473 %    o attenuate:  attenuate the noise.
   1474 %
   1475 */
   1476 MagickPrivate double GenerateDifferentialNoise(RandomInfo *random_info,
   1477   const Quantum pixel,const NoiseType noise_type,const double attenuate)
   1478 {
   1479 #define SigmaUniform  (attenuate*0.015625)
   1480 #define SigmaGaussian  (attenuate*0.015625)
   1481 #define SigmaImpulse  (attenuate*0.1)
   1482 #define SigmaLaplacian (attenuate*0.0390625)
   1483 #define SigmaMultiplicativeGaussian  (attenuate*0.5)
   1484 #define SigmaPoisson  (attenuate*12.5)
   1485 #define SigmaRandom  (attenuate)
   1486 #define TauGaussian  (attenuate*0.078125)
   1487 
   1488   double
   1489     alpha,
   1490     beta,
   1491     noise,
   1492     sigma;
   1493 
   1494   alpha=GetPseudoRandomValue(random_info);
   1495   switch (noise_type)
   1496   {
   1497     case UniformNoise:
   1498     default:
   1499     {
   1500       noise=(double) (pixel+QuantumRange*SigmaUniform*(alpha-0.5));
   1501       break;
   1502     }
   1503     case GaussianNoise:
   1504     {
   1505       double
   1506         gamma,
   1507         tau;
   1508 
   1509       if (fabs(alpha) < MagickEpsilon)
   1510         alpha=1.0;
   1511       beta=GetPseudoRandomValue(random_info);
   1512       gamma=sqrt(-2.0*log(alpha));
   1513       sigma=gamma*cos((double) (2.0*MagickPI*beta));
   1514       tau=gamma*sin((double) (2.0*MagickPI*beta));
   1515       noise=(double) (pixel+sqrt((double) pixel)*SigmaGaussian*sigma+
   1516         QuantumRange*TauGaussian*tau);
   1517       break;
   1518     }
   1519     case ImpulseNoise:
   1520     {
   1521       if (alpha < (SigmaImpulse/2.0))
   1522         noise=0.0;
   1523       else
   1524         if (alpha >= (1.0-(SigmaImpulse/2.0)))
   1525           noise=(double) QuantumRange;
   1526         else
   1527           noise=(double) pixel;
   1528       break;
   1529     }
   1530     case LaplacianNoise:
   1531     {
   1532       if (alpha <= 0.5)
   1533         {
   1534           if (alpha <= MagickEpsilon)
   1535             noise=(double) (pixel-QuantumRange);
   1536           else
   1537             noise=(double) (pixel+QuantumRange*SigmaLaplacian*log(2.0*alpha)+
   1538               0.5);
   1539           break;
   1540         }
   1541       beta=1.0-alpha;
   1542       if (beta <= (0.5*MagickEpsilon))
   1543         noise=(double) (pixel+QuantumRange);
   1544       else
   1545         noise=(double) (pixel-QuantumRange*SigmaLaplacian*log(2.0*beta)+0.5);
   1546       break;
   1547     }
   1548     case MultiplicativeGaussianNoise:
   1549     {
   1550       sigma=1.0;
   1551       if (alpha > MagickEpsilon)
   1552         sigma=sqrt(-2.0*log(alpha));
   1553       beta=GetPseudoRandomValue(random_info);
   1554       noise=(double) (pixel+pixel*SigmaMultiplicativeGaussian*sigma*
   1555         cos((double) (2.0*MagickPI*beta))/2.0);
   1556       break;
   1557     }
   1558     case PoissonNoise:
   1559     {
   1560       double
   1561         poisson;
   1562 
   1563       register ssize_t
   1564         i;
   1565 
   1566       poisson=exp(-SigmaPoisson*QuantumScale*pixel);
   1567       for (i=0; alpha > poisson; i++)
   1568       {
   1569         beta=GetPseudoRandomValue(random_info);
   1570         alpha*=beta;
   1571       }
   1572       noise=(double) (QuantumRange*i/SigmaPoisson);
   1573       break;
   1574     }
   1575     case RandomNoise:
   1576     {
   1577       noise=(double) (QuantumRange*SigmaRandom*alpha);
   1578       break;
   1579     }
   1580   }
   1581   return(noise);
   1582 }
   1583 
   1584 /*
   1586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1587 %                                                                             %
   1588 %                                                                             %
   1589 %                                                                             %
   1590 %   G e t O p t i m a l K e r n e l W i d t h                                 %
   1591 %                                                                             %
   1592 %                                                                             %
   1593 %                                                                             %
   1594 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1595 %
   1596 %  GetOptimalKernelWidth() computes the optimal kernel radius for a convolution
   1597 %  filter.  Start with the minimum value of 3 pixels and walk out until we drop
   1598 %  below the threshold of one pixel numerical accuracy.
   1599 %
   1600 %  The format of the GetOptimalKernelWidth method is:
   1601 %
   1602 %      size_t GetOptimalKernelWidth(const double radius,
   1603 %        const double sigma)
   1604 %
   1605 %  A description of each parameter follows:
   1606 %
   1607 %    o width: GetOptimalKernelWidth returns the optimal width of a
   1608 %      convolution kernel.
   1609 %
   1610 %    o radius: the radius of the Gaussian, in pixels, not counting the center
   1611 %      pixel.
   1612 %
   1613 %    o sigma: the standard deviation of the Gaussian, in pixels.
   1614 %
   1615 */
   1616 MagickPrivate size_t GetOptimalKernelWidth1D(const double radius,
   1617   const double sigma)
   1618 {
   1619   double
   1620     alpha,
   1621     beta,
   1622     gamma,
   1623     normalize,
   1624     value;
   1625 
   1626   register ssize_t
   1627     i;
   1628 
   1629   size_t
   1630     width;
   1631 
   1632   ssize_t
   1633     j;
   1634 
   1635   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   1636   if (radius > MagickEpsilon)
   1637     return((size_t) (2.0*ceil(radius)+1.0));
   1638   gamma=fabs(sigma);
   1639   if (gamma <= MagickEpsilon)
   1640     return(3UL);
   1641   alpha=PerceptibleReciprocal(2.0*gamma*gamma);
   1642   beta=(double) PerceptibleReciprocal((double) MagickSQ2PI*gamma);
   1643   for (width=5; ; )
   1644   {
   1645     normalize=0.0;
   1646     j=(ssize_t) (width-1)/2;
   1647     for (i=(-j); i <= j; i++)
   1648       normalize+=exp(-((double) (i*i))*alpha)*beta;
   1649     value=exp(-((double) (j*j))*alpha)*beta/normalize;
   1650     if ((value < QuantumScale) || (value < MagickEpsilon))
   1651       break;
   1652     width+=2;
   1653   }
   1654   return((size_t) (width-2));
   1655 }
   1656 
   1657 MagickPrivate size_t GetOptimalKernelWidth2D(const double radius,
   1658   const double sigma)
   1659 {
   1660   double
   1661     alpha,
   1662     beta,
   1663     gamma,
   1664     normalize,
   1665     value;
   1666 
   1667   size_t
   1668     width;
   1669 
   1670   ssize_t
   1671     j,
   1672     u,
   1673     v;
   1674 
   1675   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   1676   if (radius > MagickEpsilon)
   1677     return((size_t) (2.0*ceil(radius)+1.0));
   1678   gamma=fabs(sigma);
   1679   if (gamma <= MagickEpsilon)
   1680     return(3UL);
   1681   alpha=PerceptibleReciprocal(2.0*gamma*gamma);
   1682   beta=(double) PerceptibleReciprocal((double) Magick2PI*gamma*gamma);
   1683   for (width=5; ; )
   1684   {
   1685     normalize=0.0;
   1686     j=(ssize_t) (width-1)/2;
   1687     for (v=(-j); v <= j; v++)
   1688       for (u=(-j); u <= j; u++)
   1689         normalize+=exp(-((double) (u*u+v*v))*alpha)*beta;
   1690     value=exp(-((double) (j*j))*alpha)*beta/normalize;
   1691     if ((value < QuantumScale) || (value < MagickEpsilon))
   1692       break;
   1693     width+=2;
   1694   }
   1695   return((size_t) (width-2));
   1696 }
   1697 
   1698 MagickPrivate size_t  GetOptimalKernelWidth(const double radius,
   1699   const double sigma)
   1700 {
   1701   return(GetOptimalKernelWidth1D(radius,sigma));
   1702 }
   1703