13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              GGGG  EEEEE  M   M                             %
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                             G      E      MM MM                             %
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                             G GG   EEE    M M M                             %
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                             G   G  E      M   M                             %
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              GGGG  EEEEE  M   M                             %
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                    Graphic Gems - Graphic Support Methods                   %
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                               Software Design                               %
16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy%                                    Cristy                                   %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                 August 1996                                 %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
207ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy%  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  dedicated to making software imaging solutions freely available.           %
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  You may not use this file except in compliance with the License.  You may  %
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  obtain a copy of the License at                                            %
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    http://www.imagemagick.org/script/license.php                            %
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Unless required by applicable law or agreed to in writing, software        %
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  distributed under the License is distributed on an "AS IS" BASIS,          %
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  See the License for the specific language governing permissions and        %
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  limitations under the License.                                             %
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Include declarations.
423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
434c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h"
444c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color-private.h"
454c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/draw.h"
464c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/gem.h"
47d1dd6e4fefa0810b9893e6ac9418f79c97c1b39acristy#include "MagickCore/gem-private.h"
484c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image.h"
494c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image-private.h"
504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/log.h"
514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h"
524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel-accessor.h"
5335f1530f0591e7380a976a606080774c28bc4da2cristy#include "MagickCore/pixel-private.h"
544c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum.h"
554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum-private.h"
564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/random_.h"
574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/resize.h"
584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/transform.h"
594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/signature-private.h"
603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66722fc0cce634eb07588336accc3bb52979738a5ccristy%   C o n v e r t H C L T o R G B                                             %
67722fc0cce634eb07588336accc3bb52979738a5ccristy%                                                                             %
68722fc0cce634eb07588336accc3bb52979738a5ccristy%                                                                             %
69722fc0cce634eb07588336accc3bb52979738a5ccristy%                                                                             %
70722fc0cce634eb07588336accc3bb52979738a5ccristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
71722fc0cce634eb07588336accc3bb52979738a5ccristy%
72722fc0cce634eb07588336accc3bb52979738a5ccristy%  ConvertHCLToRGB() transforms a (hue, chroma, luma) to a (red, green,
73722fc0cce634eb07588336accc3bb52979738a5ccristy%  blue) triple.
74722fc0cce634eb07588336accc3bb52979738a5ccristy%
75722fc0cce634eb07588336accc3bb52979738a5ccristy%  The format of the ConvertHCLToRGBImage method is:
76722fc0cce634eb07588336accc3bb52979738a5ccristy%
77722fc0cce634eb07588336accc3bb52979738a5ccristy%      void ConvertHCLToRGB(const double hue,const double chroma,
78722fc0cce634eb07588336accc3bb52979738a5ccristy%        const double luma,double *red,double *green,double *blue)
79722fc0cce634eb07588336accc3bb52979738a5ccristy%
80722fc0cce634eb07588336accc3bb52979738a5ccristy%  A description of each parameter follows:
81722fc0cce634eb07588336accc3bb52979738a5ccristy%
829e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%    o hue, chroma, luma: A double value representing a component of the
839e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%      HCL color space.
84722fc0cce634eb07588336accc3bb52979738a5ccristy%
85722fc0cce634eb07588336accc3bb52979738a5ccristy%    o red, green, blue: A pointer to a pixel component of type Quantum.
86722fc0cce634eb07588336accc3bb52979738a5ccristy%
87722fc0cce634eb07588336accc3bb52979738a5ccristy*/
88722fc0cce634eb07588336accc3bb52979738a5ccristyMagickPrivate void ConvertHCLToRGB(const double hue,const double chroma,
89722fc0cce634eb07588336accc3bb52979738a5ccristy  const double luma,double *red,double *green,double *blue)
90722fc0cce634eb07588336accc3bb52979738a5ccristy{
91722fc0cce634eb07588336accc3bb52979738a5ccristy  double
925756d82f940337296549c59f25ff7f96eff132b1cristy    b,
935756d82f940337296549c59f25ff7f96eff132b1cristy    c,
945756d82f940337296549c59f25ff7f96eff132b1cristy    g,
955756d82f940337296549c59f25ff7f96eff132b1cristy    h,
965756d82f940337296549c59f25ff7f96eff132b1cristy    m,
975756d82f940337296549c59f25ff7f96eff132b1cristy    r,
989e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    x;
999e2436a78bdabef900e018dc77c0cc497bf6fbafcristy
1009e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  /*
1019e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    Convert HCL to RGB colorspace.
1029e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  */
1039e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  assert(red != (double *) NULL);
1049e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  assert(green != (double *) NULL);
1059e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  assert(blue != (double *) NULL);
1069e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  h=6.0*hue;
1079e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  c=chroma;
1089e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  x=c*(1.0-fabs(fmod(h,2.0)-1.0));
1099e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  r=0.0;
1109e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  g=0.0;
1119e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  b=0.0;
1129e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  if ((0.0 <= h) && (h < 1.0))
1139e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    {
1149e2436a78bdabef900e018dc77c0cc497bf6fbafcristy      r=c;
1159e2436a78bdabef900e018dc77c0cc497bf6fbafcristy      g=x;
1169e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    }
1179e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  else
1189e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    if ((1.0 <= h) && (h < 2.0))
1199e2436a78bdabef900e018dc77c0cc497bf6fbafcristy      {
1209e2436a78bdabef900e018dc77c0cc497bf6fbafcristy        r=x;
1219e2436a78bdabef900e018dc77c0cc497bf6fbafcristy        g=c;
1229e2436a78bdabef900e018dc77c0cc497bf6fbafcristy      }
1239e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    else
1249e2436a78bdabef900e018dc77c0cc497bf6fbafcristy      if ((2.0 <= h) && (h < 3.0))
1259e2436a78bdabef900e018dc77c0cc497bf6fbafcristy        {
1269e2436a78bdabef900e018dc77c0cc497bf6fbafcristy          g=c;
1279e2436a78bdabef900e018dc77c0cc497bf6fbafcristy          b=x;
1289e2436a78bdabef900e018dc77c0cc497bf6fbafcristy        }
1299e2436a78bdabef900e018dc77c0cc497bf6fbafcristy      else
1309e2436a78bdabef900e018dc77c0cc497bf6fbafcristy        if ((3.0 <= h) && (h < 4.0))
1319e2436a78bdabef900e018dc77c0cc497bf6fbafcristy          {
1329e2436a78bdabef900e018dc77c0cc497bf6fbafcristy            g=x;
1339e2436a78bdabef900e018dc77c0cc497bf6fbafcristy            b=c;
1349e2436a78bdabef900e018dc77c0cc497bf6fbafcristy          }
1359e2436a78bdabef900e018dc77c0cc497bf6fbafcristy        else
1369e2436a78bdabef900e018dc77c0cc497bf6fbafcristy          if ((4.0 <= h) && (h < 5.0))
1379e2436a78bdabef900e018dc77c0cc497bf6fbafcristy            {
1389e2436a78bdabef900e018dc77c0cc497bf6fbafcristy              r=x;
1399e2436a78bdabef900e018dc77c0cc497bf6fbafcristy              b=c;
1409e2436a78bdabef900e018dc77c0cc497bf6fbafcristy            }
1419e2436a78bdabef900e018dc77c0cc497bf6fbafcristy          else
1429e2436a78bdabef900e018dc77c0cc497bf6fbafcristy            if ((5.0 <= h) && (h < 6.0))
1439e2436a78bdabef900e018dc77c0cc497bf6fbafcristy              {
1449e2436a78bdabef900e018dc77c0cc497bf6fbafcristy                r=c;
1459e2436a78bdabef900e018dc77c0cc497bf6fbafcristy                b=x;
1469e2436a78bdabef900e018dc77c0cc497bf6fbafcristy              }
1479e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  m=luma-(0.298839*r+0.586811*g+0.114350*b);
1489e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  *red=QuantumRange*(r+m);
1499e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  *green=QuantumRange*(g+m);
1509e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  *blue=QuantumRange*(b+m);
1519e2436a78bdabef900e018dc77c0cc497bf6fbafcristy}
1529e2436a78bdabef900e018dc77c0cc497bf6fbafcristy
1539e2436a78bdabef900e018dc77c0cc497bf6fbafcristy/*
1549e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1559e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%                                                                             %
1569e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%                                                                             %
1579e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%                                                                             %
1589e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%   C o n v e r t H C L p T o R G B                                           %
1599e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%                                                                             %
1609e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%                                                                             %
1619e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%                                                                             %
1629e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1639e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%
1649e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%  ConvertHCLpToRGB() transforms a (hue, chroma, luma) to a (red, green,
1659e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%  blue) triple.  Since HCL colorspace is wider than RGB, we instead choose a
1669e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%  saturation strategy to project it on the RGB cube.
1679e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%
1689e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%  The format of the ConvertHCLpToRGBImage method is:
1699e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%
1709e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%      void ConvertHCLpToRGB(const double hue,const double chroma,
1719e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%        const double luma,double *red,double *green,double *blue)
1729e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%
1739e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%  A description of each parameter follows:
1749e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%
1759e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%    o hue, chroma, luma: A double value representing a componenet of the
1769e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%      HCLp color space.
1779e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%
1789e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%    o red, green, blue: A pointer to a pixel component of type Quantum.
1799e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%
1809e2436a78bdabef900e018dc77c0cc497bf6fbafcristy*/
1819e2436a78bdabef900e018dc77c0cc497bf6fbafcristyMagickPrivate void ConvertHCLpToRGB(const double hue,const double chroma,
1829e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  const double luma,double *red,double *green,double *blue)
1839e2436a78bdabef900e018dc77c0cc497bf6fbafcristy{
1849e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  double
1859e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    b,
1869e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    c,
1879e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    g,
1889e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    h,
1899e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    m,
1909e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    r,
191c41e5fa39a01f3b6e5d26cc7b32afe5556038f21cristy    x,
192c41e5fa39a01f3b6e5d26cc7b32afe5556038f21cristy    z;
193722fc0cce634eb07588336accc3bb52979738a5ccristy
194722fc0cce634eb07588336accc3bb52979738a5ccristy  /*
1959e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    Convert HCLp to RGB colorspace.
196722fc0cce634eb07588336accc3bb52979738a5ccristy  */
197722fc0cce634eb07588336accc3bb52979738a5ccristy  assert(red != (double *) NULL);
198722fc0cce634eb07588336accc3bb52979738a5ccristy  assert(green != (double *) NULL);
199722fc0cce634eb07588336accc3bb52979738a5ccristy  assert(blue != (double *) NULL);
2005756d82f940337296549c59f25ff7f96eff132b1cristy  h=6.0*hue;
2015756d82f940337296549c59f25ff7f96eff132b1cristy  c=chroma;
2025756d82f940337296549c59f25ff7f96eff132b1cristy  x=c*(1.0-fabs(fmod(h,2.0)-1.0));
2035756d82f940337296549c59f25ff7f96eff132b1cristy  r=0.0;
2045756d82f940337296549c59f25ff7f96eff132b1cristy  g=0.0;
2055756d82f940337296549c59f25ff7f96eff132b1cristy  b=0.0;
2065756d82f940337296549c59f25ff7f96eff132b1cristy  if ((0.0 <= h) && (h < 1.0))
2075756d82f940337296549c59f25ff7f96eff132b1cristy    {
2085756d82f940337296549c59f25ff7f96eff132b1cristy      r=c;
2095756d82f940337296549c59f25ff7f96eff132b1cristy      g=x;
2105756d82f940337296549c59f25ff7f96eff132b1cristy    }
2115756d82f940337296549c59f25ff7f96eff132b1cristy  else
2125756d82f940337296549c59f25ff7f96eff132b1cristy    if ((1.0 <= h) && (h < 2.0))
2135756d82f940337296549c59f25ff7f96eff132b1cristy      {
2145756d82f940337296549c59f25ff7f96eff132b1cristy        r=x;
2155756d82f940337296549c59f25ff7f96eff132b1cristy        g=c;
2165756d82f940337296549c59f25ff7f96eff132b1cristy      }
2175756d82f940337296549c59f25ff7f96eff132b1cristy    else
2185756d82f940337296549c59f25ff7f96eff132b1cristy      if ((2.0 <= h) && (h < 3.0))
2195756d82f940337296549c59f25ff7f96eff132b1cristy        {
2205756d82f940337296549c59f25ff7f96eff132b1cristy          g=c;
2215756d82f940337296549c59f25ff7f96eff132b1cristy          b=x;
2225756d82f940337296549c59f25ff7f96eff132b1cristy        }
2235756d82f940337296549c59f25ff7f96eff132b1cristy      else
2245756d82f940337296549c59f25ff7f96eff132b1cristy        if ((3.0 <= h) && (h < 4.0))
2255756d82f940337296549c59f25ff7f96eff132b1cristy          {
2265756d82f940337296549c59f25ff7f96eff132b1cristy            g=x;
2275756d82f940337296549c59f25ff7f96eff132b1cristy            b=c;
2285756d82f940337296549c59f25ff7f96eff132b1cristy          }
2295756d82f940337296549c59f25ff7f96eff132b1cristy        else
2305756d82f940337296549c59f25ff7f96eff132b1cristy          if ((4.0 <= h) && (h < 5.0))
2315756d82f940337296549c59f25ff7f96eff132b1cristy            {
2325756d82f940337296549c59f25ff7f96eff132b1cristy              r=x;
2335756d82f940337296549c59f25ff7f96eff132b1cristy              b=c;
2345756d82f940337296549c59f25ff7f96eff132b1cristy            }
2355756d82f940337296549c59f25ff7f96eff132b1cristy          else
2365756d82f940337296549c59f25ff7f96eff132b1cristy            if ((5.0 <= h) && (h < 6.0))
2375756d82f940337296549c59f25ff7f96eff132b1cristy              {
2385756d82f940337296549c59f25ff7f96eff132b1cristy                r=c;
2395756d82f940337296549c59f25ff7f96eff132b1cristy                b=x;
2405756d82f940337296549c59f25ff7f96eff132b1cristy              }
2419e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  m=luma-(0.298839*r+0.586811*g+0.114350*b);
242c41e5fa39a01f3b6e5d26cc7b32afe5556038f21cristy  z=1.0;
243c41e5fa39a01f3b6e5d26cc7b32afe5556038f21cristy  if (m < 0.0)
244c41e5fa39a01f3b6e5d26cc7b32afe5556038f21cristy    {
245c41e5fa39a01f3b6e5d26cc7b32afe5556038f21cristy      z=luma/(luma-m);
246c41e5fa39a01f3b6e5d26cc7b32afe5556038f21cristy      m=0.0;
247c41e5fa39a01f3b6e5d26cc7b32afe5556038f21cristy    }
248c41e5fa39a01f3b6e5d26cc7b32afe5556038f21cristy  else
249c41e5fa39a01f3b6e5d26cc7b32afe5556038f21cristy    if (m+c > 1.0)
250c41e5fa39a01f3b6e5d26cc7b32afe5556038f21cristy      {
251c41e5fa39a01f3b6e5d26cc7b32afe5556038f21cristy        z=(1.0-luma)/(m+c-luma);
252c41e5fa39a01f3b6e5d26cc7b32afe5556038f21cristy        m=1.0-z*c;
253c41e5fa39a01f3b6e5d26cc7b32afe5556038f21cristy      }
254a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  *red=QuantumRange*(z*r+m);
255a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  *green=QuantumRange*(z*g+m);
256a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  *blue=QuantumRange*(z*b+m);
257722fc0cce634eb07588336accc3bb52979738a5ccristy}
258722fc0cce634eb07588336accc3bb52979738a5ccristy
259722fc0cce634eb07588336accc3bb52979738a5ccristy/*
260722fc0cce634eb07588336accc3bb52979738a5ccristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261722fc0cce634eb07588336accc3bb52979738a5ccristy%                                                                             %
262722fc0cce634eb07588336accc3bb52979738a5ccristy%                                                                             %
263722fc0cce634eb07588336accc3bb52979738a5ccristy%                                                                             %
2640a39a5c567fca70403bc431d18890e89fc253eefcristy%   C o n v e r t H S B T o R G B                                             %
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2700a39a5c567fca70403bc431d18890e89fc253eefcristy%  ConvertHSBToRGB() transforms a (hue, saturation, brightness) to a (red,
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  green, blue) triple.
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2730a39a5c567fca70403bc431d18890e89fc253eefcristy%  The format of the ConvertHSBToRGBImage method is:
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2750a39a5c567fca70403bc431d18890e89fc253eefcristy%      void ConvertHSBToRGB(const double hue,const double saturation,
2763094b7f3243820cc5559d370412a9d406d074348cristy%        const double brightness,double *red,double *green,double *blue)
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o hue, saturation, brightness: A double value representing a
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      component of the HSB color space.
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o red, green, blue: A pointer to a pixel component of type Quantum.
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2860a39a5c567fca70403bc431d18890e89fc253eefcristyMagickPrivate void ConvertHSBToRGB(const double hue,const double saturation,
2873094b7f3243820cc5559d370412a9d406d074348cristy  const double brightness,double *red,double *green,double *blue)
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
289caf4580de0f80e561a5fcb59c89f2f8adac91006cristy  double
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    f,
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    h,
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p,
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q,
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    t;
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert HSB to RGB colorspace.
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2993094b7f3243820cc5559d370412a9d406d074348cristy  assert(red != (double *) NULL);
3003094b7f3243820cc5559d370412a9d406d074348cristy  assert(green != (double *) NULL);
3013094b7f3243820cc5559d370412a9d406d074348cristy  assert(blue != (double *) NULL);
30243974aca865ecd2f31fbf2972d92f9de78a3d900Cristy  if (fabs(saturation) < MagickEpsilon)
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
304caf4580de0f80e561a5fcb59c89f2f8adac91006cristy      *red=QuantumRange*brightness;
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *green=(*red);
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *blue=(*red);
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30998a65d5565159ce59b24013f0e3d148428af50d6cristy  h=6.0*(hue-floor(hue));
31098a65d5565159ce59b24013f0e3d148428af50d6cristy  f=h-floor((double) h);
31198a65d5565159ce59b24013f0e3d148428af50d6cristy  p=brightness*(1.0-saturation);
31298a65d5565159ce59b24013f0e3d148428af50d6cristy  q=brightness*(1.0-saturation*f);
31398a65d5565159ce59b24013f0e3d148428af50d6cristy  t=brightness*(1.0-(saturation*(1.0-f)));
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch ((int) h)
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 0:
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default:
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3190a39a5c567fca70403bc431d18890e89fc253eefcristy      *red=QuantumRange*brightness;
3200a39a5c567fca70403bc431d18890e89fc253eefcristy      *green=QuantumRange*t;
3210a39a5c567fca70403bc431d18890e89fc253eefcristy      *blue=QuantumRange*p;
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 1:
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3260a39a5c567fca70403bc431d18890e89fc253eefcristy      *red=QuantumRange*q;
3270a39a5c567fca70403bc431d18890e89fc253eefcristy      *green=QuantumRange*brightness;
3280a39a5c567fca70403bc431d18890e89fc253eefcristy      *blue=QuantumRange*p;
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 2:
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3330a39a5c567fca70403bc431d18890e89fc253eefcristy      *red=QuantumRange*p;
3340a39a5c567fca70403bc431d18890e89fc253eefcristy      *green=QuantumRange*brightness;
3350a39a5c567fca70403bc431d18890e89fc253eefcristy      *blue=QuantumRange*t;
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 3:
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3400a39a5c567fca70403bc431d18890e89fc253eefcristy      *red=QuantumRange*p;
3410a39a5c567fca70403bc431d18890e89fc253eefcristy      *green=QuantumRange*q;
3420a39a5c567fca70403bc431d18890e89fc253eefcristy      *blue=QuantumRange*brightness;
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 4:
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3470a39a5c567fca70403bc431d18890e89fc253eefcristy      *red=QuantumRange*t;
3480a39a5c567fca70403bc431d18890e89fc253eefcristy      *green=QuantumRange*p;
3490a39a5c567fca70403bc431d18890e89fc253eefcristy      *blue=QuantumRange*brightness;
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 5:
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3540a39a5c567fca70403bc431d18890e89fc253eefcristy      *red=QuantumRange*brightness;
3550a39a5c567fca70403bc431d18890e89fc253eefcristy      *green=QuantumRange*p;
3560a39a5c567fca70403bc431d18890e89fc253eefcristy      *blue=QuantumRange*q;
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
367af64eb219382bdf6243c4b8dc589268b8934304acristy%   C o n v e r t H S I T o R G B                                             %
368af64eb219382bdf6243c4b8dc589268b8934304acristy%                                                                             %
369af64eb219382bdf6243c4b8dc589268b8934304acristy%                                                                             %
370af64eb219382bdf6243c4b8dc589268b8934304acristy%                                                                             %
371af64eb219382bdf6243c4b8dc589268b8934304acristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
372af64eb219382bdf6243c4b8dc589268b8934304acristy%
373af64eb219382bdf6243c4b8dc589268b8934304acristy%  ConvertHSIToRGB() transforms a (hue, saturation, intensity) to a (red,
374af64eb219382bdf6243c4b8dc589268b8934304acristy%  green, blue) triple.
375af64eb219382bdf6243c4b8dc589268b8934304acristy%
376af64eb219382bdf6243c4b8dc589268b8934304acristy%  The format of the ConvertHSIToRGBImage method is:
377af64eb219382bdf6243c4b8dc589268b8934304acristy%
378af64eb219382bdf6243c4b8dc589268b8934304acristy%      void ConvertHSIToRGB(const double hue,const double saturation,
379af64eb219382bdf6243c4b8dc589268b8934304acristy%        const double intensity,double *red,double *green,double *blue)
380af64eb219382bdf6243c4b8dc589268b8934304acristy%
381af64eb219382bdf6243c4b8dc589268b8934304acristy%  A description of each parameter follows:
382af64eb219382bdf6243c4b8dc589268b8934304acristy%
383af64eb219382bdf6243c4b8dc589268b8934304acristy%    o hue, saturation, intensity: A double value representing a
384af64eb219382bdf6243c4b8dc589268b8934304acristy%      component of the HSI color space.
385af64eb219382bdf6243c4b8dc589268b8934304acristy%
386af64eb219382bdf6243c4b8dc589268b8934304acristy%    o red, green, blue: A pointer to a pixel component of type Quantum.
387af64eb219382bdf6243c4b8dc589268b8934304acristy%
388af64eb219382bdf6243c4b8dc589268b8934304acristy*/
389af64eb219382bdf6243c4b8dc589268b8934304acristyMagickPrivate void ConvertHSIToRGB(const double hue,const double saturation,
390af64eb219382bdf6243c4b8dc589268b8934304acristy  const double intensity,double *red,double *green,double *blue)
391af64eb219382bdf6243c4b8dc589268b8934304acristy{
392af64eb219382bdf6243c4b8dc589268b8934304acristy  double
393bed2d4b625e560c3dcfb8adb33b332bfecc21edfcristy    b,
3946eb18177dc30c18a0a6bc7ea0f729b6f0de84feecristy    g,
395bed2d4b625e560c3dcfb8adb33b332bfecc21edfcristy    h,
396bed2d4b625e560c3dcfb8adb33b332bfecc21edfcristy    r;
397af64eb219382bdf6243c4b8dc589268b8934304acristy
398af64eb219382bdf6243c4b8dc589268b8934304acristy  /*
399af64eb219382bdf6243c4b8dc589268b8934304acristy    Convert HSI to RGB colorspace.
400af64eb219382bdf6243c4b8dc589268b8934304acristy  */
401af64eb219382bdf6243c4b8dc589268b8934304acristy  assert(red != (double *) NULL);
402af64eb219382bdf6243c4b8dc589268b8934304acristy  assert(green != (double *) NULL);
403af64eb219382bdf6243c4b8dc589268b8934304acristy  assert(blue != (double *) NULL);
404af64eb219382bdf6243c4b8dc589268b8934304acristy  h=360.0*hue;
405af64eb219382bdf6243c4b8dc589268b8934304acristy  h-=360.0*floor(h/360.0);
406af64eb219382bdf6243c4b8dc589268b8934304acristy  if (h < 120.0)
407af64eb219382bdf6243c4b8dc589268b8934304acristy    {
408bed2d4b625e560c3dcfb8adb33b332bfecc21edfcristy      b=intensity*(1.0-saturation);
409bed2d4b625e560c3dcfb8adb33b332bfecc21edfcristy      r=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
410af64eb219382bdf6243c4b8dc589268b8934304acristy        (MagickPI/180.0)));
411bed2d4b625e560c3dcfb8adb33b332bfecc21edfcristy      g=3.0*intensity-r-b;
412af64eb219382bdf6243c4b8dc589268b8934304acristy    }
413af64eb219382bdf6243c4b8dc589268b8934304acristy  else
414af64eb219382bdf6243c4b8dc589268b8934304acristy    if (h < 240.0)
415af64eb219382bdf6243c4b8dc589268b8934304acristy      {
416af64eb219382bdf6243c4b8dc589268b8934304acristy        h-=120.0;
417bed2d4b625e560c3dcfb8adb33b332bfecc21edfcristy        r=intensity*(1.0-saturation);
418bed2d4b625e560c3dcfb8adb33b332bfecc21edfcristy        g=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
419af64eb219382bdf6243c4b8dc589268b8934304acristy          (MagickPI/180.0)));
420bed2d4b625e560c3dcfb8adb33b332bfecc21edfcristy        b=3.0*intensity-r-g;
421af64eb219382bdf6243c4b8dc589268b8934304acristy      }
422af64eb219382bdf6243c4b8dc589268b8934304acristy    else
423af64eb219382bdf6243c4b8dc589268b8934304acristy      {
424af64eb219382bdf6243c4b8dc589268b8934304acristy        h-=240.0;
425bed2d4b625e560c3dcfb8adb33b332bfecc21edfcristy        g=intensity*(1.0-saturation);
426bed2d4b625e560c3dcfb8adb33b332bfecc21edfcristy        b=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
427af64eb219382bdf6243c4b8dc589268b8934304acristy          (MagickPI/180.0)));
428bed2d4b625e560c3dcfb8adb33b332bfecc21edfcristy        r=3.0*intensity-g-b;
429af64eb219382bdf6243c4b8dc589268b8934304acristy      }
430bed2d4b625e560c3dcfb8adb33b332bfecc21edfcristy  *red=QuantumRange*r;
431bed2d4b625e560c3dcfb8adb33b332bfecc21edfcristy  *green=QuantumRange*g;
432bed2d4b625e560c3dcfb8adb33b332bfecc21edfcristy  *blue=QuantumRange*b;
433af64eb219382bdf6243c4b8dc589268b8934304acristy}
434af64eb219382bdf6243c4b8dc589268b8934304acristy
435af64eb219382bdf6243c4b8dc589268b8934304acristy/*
436af64eb219382bdf6243c4b8dc589268b8934304acristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
437af64eb219382bdf6243c4b8dc589268b8934304acristy%                                                                             %
438af64eb219382bdf6243c4b8dc589268b8934304acristy%                                                                             %
439af64eb219382bdf6243c4b8dc589268b8934304acristy%                                                                             %
4400a39a5c567fca70403bc431d18890e89fc253eefcristy%   C o n v e r t H S L T o R G B                                             %
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4460a39a5c567fca70403bc431d18890e89fc253eefcristy%  ConvertHSLToRGB() transforms a (hue, saturation, lightness) to a (red,
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  green, blue) triple.
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4490a39a5c567fca70403bc431d18890e89fc253eefcristy%  The format of the ConvertHSLToRGBImage method is:
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4510a39a5c567fca70403bc431d18890e89fc253eefcristy%      void ConvertHSLToRGB(const double hue,const double saturation,
4523094b7f3243820cc5559d370412a9d406d074348cristy%        const double lightness,double *red,double *green,double *blue)
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o hue, saturation, lightness: A double value representing a
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      component of the HSL color space.
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o red, green, blue: A pointer to a pixel component of type Quantum.
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4620a39a5c567fca70403bc431d18890e89fc253eefcristyMagickExport void ConvertHSLToRGB(const double hue,const double saturation,
4633094b7f3243820cc5559d370412a9d406d074348cristy  const double lightness,double *red,double *green,double *blue)
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
465caf4580de0f80e561a5fcb59c89f2f8adac91006cristy  double
466a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    c,
467a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    h,
468a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    min,
469a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    x;
4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert HSL to RGB colorspace.
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
4743094b7f3243820cc5559d370412a9d406d074348cristy  assert(red != (double *) NULL);
4753094b7f3243820cc5559d370412a9d406d074348cristy  assert(green != (double *) NULL);
4763094b7f3243820cc5559d370412a9d406d074348cristy  assert(blue != (double *) NULL);
477a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  h=hue*360.0;
478a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  if (lightness <= 0.5)
479a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    c=2.0*lightness*saturation;
480a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  else
481a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    c=(2.0-2.0*lightness)*saturation;
482a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  min=lightness-0.5*c;
483a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  h-=360.0*floor(h/360.0);
484a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  h/=60.0;
485a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  x=c*(1.0-fabs(h-2.0*floor(h/2.0)-1.0));
486a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  switch ((int) floor(h))
487a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  {
488a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    case 0:
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
490a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *red=QuantumRange*(min+c);
491a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *green=QuantumRange*(min+x);
492a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *blue=QuantumRange*min;
493a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      break;
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
495a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    case 1:
496a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    {
497a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *red=QuantumRange*(min+x);
498a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *green=QuantumRange*(min+c);
499a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *blue=QuantumRange*min;
500a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      break;
501a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    }
502a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    case 2:
503a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    {
504a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *red=QuantumRange*min;
505a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *green=QuantumRange*(min+c);
506a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *blue=QuantumRange*(min+x);
507a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      break;
508a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    }
509a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    case 3:
510a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    {
511a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *red=QuantumRange*min;
512a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *green=QuantumRange*(min+x);
513a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *blue=QuantumRange*(min+c);
514a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      break;
515a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    }
516a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    case 4:
517a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    {
518a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *red=QuantumRange*(min+x);
519a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *green=QuantumRange*min;
520a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *blue=QuantumRange*(min+c);
521a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      break;
522a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    }
523a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    case 5:
524a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    {
525a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *red=QuantumRange*(min+c);
526a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *green=QuantumRange*min;
527a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *blue=QuantumRange*(min+x);
528a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      break;
529a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    }
530a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    default:
531a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    {
532a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *red=0.0;
533a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *green=0.0;
534a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *blue=0.0;
535a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    }
536a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  }
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
544246c3135a833b00ed2e42448c85cc2ea1269b177cristy%   C o n v e r t H S V T o R G B                                             %
545246c3135a833b00ed2e42448c85cc2ea1269b177cristy%                                                                             %
546246c3135a833b00ed2e42448c85cc2ea1269b177cristy%                                                                             %
547246c3135a833b00ed2e42448c85cc2ea1269b177cristy%                                                                             %
548246c3135a833b00ed2e42448c85cc2ea1269b177cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
549246c3135a833b00ed2e42448c85cc2ea1269b177cristy%
550246c3135a833b00ed2e42448c85cc2ea1269b177cristy%  ConvertHSVToRGB() transforms a (hue, saturation, value) to a (red,
551246c3135a833b00ed2e42448c85cc2ea1269b177cristy%  green, blue) triple.
552246c3135a833b00ed2e42448c85cc2ea1269b177cristy%
553246c3135a833b00ed2e42448c85cc2ea1269b177cristy%  The format of the ConvertHSVToRGBImage method is:
554246c3135a833b00ed2e42448c85cc2ea1269b177cristy%
555246c3135a833b00ed2e42448c85cc2ea1269b177cristy%      void ConvertHSVToRGB(const double hue,const double saturation,
556246c3135a833b00ed2e42448c85cc2ea1269b177cristy%        const double value,double *red,double *green,double *blue)
557246c3135a833b00ed2e42448c85cc2ea1269b177cristy%
558246c3135a833b00ed2e42448c85cc2ea1269b177cristy%  A description of each parameter follows:
559246c3135a833b00ed2e42448c85cc2ea1269b177cristy%
560246c3135a833b00ed2e42448c85cc2ea1269b177cristy%    o hue, saturation, value: A double value representing a
561246c3135a833b00ed2e42448c85cc2ea1269b177cristy%      component of the HSV color space.
562246c3135a833b00ed2e42448c85cc2ea1269b177cristy%
563246c3135a833b00ed2e42448c85cc2ea1269b177cristy%    o red, green, blue: A pointer to a pixel component of type Quantum.
564246c3135a833b00ed2e42448c85cc2ea1269b177cristy%
565246c3135a833b00ed2e42448c85cc2ea1269b177cristy*/
566246c3135a833b00ed2e42448c85cc2ea1269b177cristyMagickPrivate void ConvertHSVToRGB(const double hue,const double saturation,
567246c3135a833b00ed2e42448c85cc2ea1269b177cristy  const double value,double *red,double *green,double *blue)
568246c3135a833b00ed2e42448c85cc2ea1269b177cristy{
569246c3135a833b00ed2e42448c85cc2ea1269b177cristy  double
570246c3135a833b00ed2e42448c85cc2ea1269b177cristy    c,
571246c3135a833b00ed2e42448c85cc2ea1269b177cristy    h,
572246c3135a833b00ed2e42448c85cc2ea1269b177cristy    min,
573246c3135a833b00ed2e42448c85cc2ea1269b177cristy    x;
574246c3135a833b00ed2e42448c85cc2ea1269b177cristy
575246c3135a833b00ed2e42448c85cc2ea1269b177cristy  /*
576246c3135a833b00ed2e42448c85cc2ea1269b177cristy    Convert HSV to RGB colorspace.
577246c3135a833b00ed2e42448c85cc2ea1269b177cristy  */
578246c3135a833b00ed2e42448c85cc2ea1269b177cristy  assert(red != (double *) NULL);
579246c3135a833b00ed2e42448c85cc2ea1269b177cristy  assert(green != (double *) NULL);
580246c3135a833b00ed2e42448c85cc2ea1269b177cristy  assert(blue != (double *) NULL);
581246c3135a833b00ed2e42448c85cc2ea1269b177cristy  h=hue*360.0;
582246c3135a833b00ed2e42448c85cc2ea1269b177cristy  c=value*saturation;
583246c3135a833b00ed2e42448c85cc2ea1269b177cristy  min=value-c;
584246c3135a833b00ed2e42448c85cc2ea1269b177cristy  h-=360.0*floor(h/360.0);
585246c3135a833b00ed2e42448c85cc2ea1269b177cristy  h/=60.0;
586246c3135a833b00ed2e42448c85cc2ea1269b177cristy  x=c*(1.0-fabs(h-2.0*floor(h/2.0)-1.0));
587246c3135a833b00ed2e42448c85cc2ea1269b177cristy  switch ((int) floor(h))
588246c3135a833b00ed2e42448c85cc2ea1269b177cristy  {
589246c3135a833b00ed2e42448c85cc2ea1269b177cristy    case 0:
590246c3135a833b00ed2e42448c85cc2ea1269b177cristy    {
591246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *red=QuantumRange*(min+c);
592246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *green=QuantumRange*(min+x);
593246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *blue=QuantumRange*min;
594246c3135a833b00ed2e42448c85cc2ea1269b177cristy      break;
595246c3135a833b00ed2e42448c85cc2ea1269b177cristy    }
596246c3135a833b00ed2e42448c85cc2ea1269b177cristy    case 1:
597246c3135a833b00ed2e42448c85cc2ea1269b177cristy    {
598246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *red=QuantumRange*(min+x);
599246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *green=QuantumRange*(min+c);
600246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *blue=QuantumRange*min;
601246c3135a833b00ed2e42448c85cc2ea1269b177cristy      break;
602246c3135a833b00ed2e42448c85cc2ea1269b177cristy    }
603246c3135a833b00ed2e42448c85cc2ea1269b177cristy    case 2:
604246c3135a833b00ed2e42448c85cc2ea1269b177cristy    {
605246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *red=QuantumRange*min;
606246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *green=QuantumRange*(min+c);
607246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *blue=QuantumRange*(min+x);
608246c3135a833b00ed2e42448c85cc2ea1269b177cristy      break;
609246c3135a833b00ed2e42448c85cc2ea1269b177cristy    }
610246c3135a833b00ed2e42448c85cc2ea1269b177cristy    case 3:
611246c3135a833b00ed2e42448c85cc2ea1269b177cristy    {
612246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *red=QuantumRange*min;
613246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *green=QuantumRange*(min+x);
614246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *blue=QuantumRange*(min+c);
615246c3135a833b00ed2e42448c85cc2ea1269b177cristy      break;
616246c3135a833b00ed2e42448c85cc2ea1269b177cristy    }
617246c3135a833b00ed2e42448c85cc2ea1269b177cristy    case 4:
618246c3135a833b00ed2e42448c85cc2ea1269b177cristy    {
619246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *red=QuantumRange*(min+x);
620246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *green=QuantumRange*min;
621246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *blue=QuantumRange*(min+c);
622246c3135a833b00ed2e42448c85cc2ea1269b177cristy      break;
623246c3135a833b00ed2e42448c85cc2ea1269b177cristy    }
624246c3135a833b00ed2e42448c85cc2ea1269b177cristy    case 5:
625246c3135a833b00ed2e42448c85cc2ea1269b177cristy    {
626246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *red=QuantumRange*(min+c);
627246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *green=QuantumRange*min;
628246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *blue=QuantumRange*(min+x);
629246c3135a833b00ed2e42448c85cc2ea1269b177cristy      break;
630246c3135a833b00ed2e42448c85cc2ea1269b177cristy    }
631246c3135a833b00ed2e42448c85cc2ea1269b177cristy    default:
632246c3135a833b00ed2e42448c85cc2ea1269b177cristy    {
633246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *red=0.0;
634246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *green=0.0;
635246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *blue=0.0;
636246c3135a833b00ed2e42448c85cc2ea1269b177cristy    }
637246c3135a833b00ed2e42448c85cc2ea1269b177cristy  }
638246c3135a833b00ed2e42448c85cc2ea1269b177cristy}
639246c3135a833b00ed2e42448c85cc2ea1269b177cristy
640246c3135a833b00ed2e42448c85cc2ea1269b177cristy/*
641246c3135a833b00ed2e42448c85cc2ea1269b177cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
642246c3135a833b00ed2e42448c85cc2ea1269b177cristy%                                                                             %
643246c3135a833b00ed2e42448c85cc2ea1269b177cristy%                                                                             %
644246c3135a833b00ed2e42448c85cc2ea1269b177cristy%                                                                             %
6450a39a5c567fca70403bc431d18890e89fc253eefcristy%   C o n v e r t H W B T o R G B                                             %
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6510a39a5c567fca70403bc431d18890e89fc253eefcristy%  ConvertHWBToRGB() transforms a (hue, whiteness, blackness) to a (red, green,
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  blue) triple.
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6540a39a5c567fca70403bc431d18890e89fc253eefcristy%  The format of the ConvertHWBToRGBImage method is:
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6560a39a5c567fca70403bc431d18890e89fc253eefcristy%      void ConvertHWBToRGB(const double hue,const double whiteness,
6573094b7f3243820cc5559d370412a9d406d074348cristy%        const double blackness,double *red,double *green,double *blue)
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o hue, whiteness, blackness: A double value representing a
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      component of the HWB color space.
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o red, green, blue: A pointer to a pixel component of type Quantum.
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6670a39a5c567fca70403bc431d18890e89fc253eefcristyMagickPrivate void ConvertHWBToRGB(const double hue,const double whiteness,
6683094b7f3243820cc5559d370412a9d406d074348cristy  const double blackness,double *red,double *green,double *blue)
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
670caf4580de0f80e561a5fcb59c89f2f8adac91006cristy  double
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b,
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    f,
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    g,
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    n,
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    r,
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    v;
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
678bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert HWB to RGB colorspace.
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6843094b7f3243820cc5559d370412a9d406d074348cristy  assert(red != (double *) NULL);
6853094b7f3243820cc5559d370412a9d406d074348cristy  assert(green != (double *) NULL);
6863094b7f3243820cc5559d370412a9d406d074348cristy  assert(blue != (double *) NULL);
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  v=1.0-blackness;
68843974aca865ecd2f31fbf2972d92f9de78a3d900Cristy  if (fabs(hue-(-1.0)) < MagickEpsilon)
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6900a39a5c567fca70403bc431d18890e89fc253eefcristy      *red=QuantumRange*v;
6910a39a5c567fca70403bc431d18890e89fc253eefcristy      *green=QuantumRange*v;
6920a39a5c567fca70403bc431d18890e89fc253eefcristy      *blue=QuantumRange*v;
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
695bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  i=(ssize_t) floor(6.0*hue);
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  f=6.0*hue-i;
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((i & 0x01) != 0)
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    f=1.0-f;
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  n=whiteness+f*(v-whiteness);  /* linear interpolation */
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (i)
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default:
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 6:
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 0: r=v; g=n; b=whiteness; break;
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 1: r=n; g=v; b=whiteness; break;
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 2: r=whiteness; g=v; b=n; break;
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 3: r=whiteness; g=n; b=v; break;
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 4: r=n; g=whiteness; b=v; break;
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 5: r=v; g=whiteness; b=n; break;
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7110a39a5c567fca70403bc431d18890e89fc253eefcristy  *red=QuantumRange*r;
7120a39a5c567fca70403bc431d18890e89fc253eefcristy  *green=QuantumRange*g;
7130a39a5c567fca70403bc431d18890e89fc253eefcristy  *blue=QuantumRange*b;
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
720722fc0cce634eb07588336accc3bb52979738a5ccristy%                                                                             %
721df42b17380e9d59e0ef874a62e553c9390157b7dcristy%   C o n v e r t L C H a b T o R G B                                         %
722b285095a81498ca0f0b24a0591e02aa599065b12cristy%                                                                             %
723b285095a81498ca0f0b24a0591e02aa599065b12cristy%                                                                             %
724b285095a81498ca0f0b24a0591e02aa599065b12cristy%                                                                             %
725b285095a81498ca0f0b24a0591e02aa599065b12cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
726b285095a81498ca0f0b24a0591e02aa599065b12cristy%
727df42b17380e9d59e0ef874a62e553c9390157b7dcristy%  ConvertLCHabToRGB() transforms a (luma, chroma, hue) to a (red, green,
728b285095a81498ca0f0b24a0591e02aa599065b12cristy%  blue) triple.
729b285095a81498ca0f0b24a0591e02aa599065b12cristy%
730df42b17380e9d59e0ef874a62e553c9390157b7dcristy%  The format of the ConvertLCHabToRGBImage method is:
731b285095a81498ca0f0b24a0591e02aa599065b12cristy%
732df42b17380e9d59e0ef874a62e553c9390157b7dcristy%      void ConvertLCHabToRGB(const double luma,const double chroma,
733b285095a81498ca0f0b24a0591e02aa599065b12cristy%        const double hue,double *red,double *green,double *blue)
734b285095a81498ca0f0b24a0591e02aa599065b12cristy%
735b285095a81498ca0f0b24a0591e02aa599065b12cristy%  A description of each parameter follows:
736b285095a81498ca0f0b24a0591e02aa599065b12cristy%
737df42b17380e9d59e0ef874a62e553c9390157b7dcristy%    o luma, chroma, hue: A double value representing a component of the
738df42b17380e9d59e0ef874a62e553c9390157b7dcristy%      LCHab color space.
739b285095a81498ca0f0b24a0591e02aa599065b12cristy%
740b285095a81498ca0f0b24a0591e02aa599065b12cristy%    o red, green, blue: A pointer to a pixel component of type Quantum.
741b285095a81498ca0f0b24a0591e02aa599065b12cristy%
742b285095a81498ca0f0b24a0591e02aa599065b12cristy*/
74335605e9ee687899cf1c79cf27572fba678ce636ecristy
74435605e9ee687899cf1c79cf27572fba678ce636ecristystatic inline void ConvertLCHabToXYZ(const double luma,const double chroma,
74535605e9ee687899cf1c79cf27572fba678ce636ecristy  const double hue,double *X,double *Y,double *Z)
74635605e9ee687899cf1c79cf27572fba678ce636ecristy{
74735605e9ee687899cf1c79cf27572fba678ce636ecristy  ConvertLabToXYZ(luma,chroma*cos(hue*MagickPI/180.0),chroma*
74835605e9ee687899cf1c79cf27572fba678ce636ecristy    sin(hue*MagickPI/180.0),X,Y,Z);
74935605e9ee687899cf1c79cf27572fba678ce636ecristy}
75035605e9ee687899cf1c79cf27572fba678ce636ecristy
751df42b17380e9d59e0ef874a62e553c9390157b7dcristyMagickPrivate void ConvertLCHabToRGB(const double luma,const double chroma,
752b285095a81498ca0f0b24a0591e02aa599065b12cristy  const double hue,double *red,double *green,double *blue)
753b285095a81498ca0f0b24a0591e02aa599065b12cristy{
754b285095a81498ca0f0b24a0591e02aa599065b12cristy  double
755b285095a81498ca0f0b24a0591e02aa599065b12cristy    X,
756b285095a81498ca0f0b24a0591e02aa599065b12cristy    Y,
757b285095a81498ca0f0b24a0591e02aa599065b12cristy    Z;
758b285095a81498ca0f0b24a0591e02aa599065b12cristy
759b285095a81498ca0f0b24a0591e02aa599065b12cristy  /*
760df42b17380e9d59e0ef874a62e553c9390157b7dcristy    Convert LCHab to RGB colorspace.
761b285095a81498ca0f0b24a0591e02aa599065b12cristy  */
762b285095a81498ca0f0b24a0591e02aa599065b12cristy  assert(red != (double *) NULL);
763b285095a81498ca0f0b24a0591e02aa599065b12cristy  assert(green != (double *) NULL);
764b285095a81498ca0f0b24a0591e02aa599065b12cristy  assert(blue != (double *) NULL);
7656d897c70de36922ef314127ac8a202e0605bbeadcristy  ConvertLCHabToXYZ(100.0*luma,255.0*(chroma-0.5),360.0*hue,&X,&Y,&Z);
766b285095a81498ca0f0b24a0591e02aa599065b12cristy  ConvertXYZToRGB(X,Y,Z,red,green,blue);
767b285095a81498ca0f0b24a0591e02aa599065b12cristy}
768b285095a81498ca0f0b24a0591e02aa599065b12cristy
769b285095a81498ca0f0b24a0591e02aa599065b12cristy/*
770b285095a81498ca0f0b24a0591e02aa599065b12cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
771b285095a81498ca0f0b24a0591e02aa599065b12cristy%                                                                             %
772b285095a81498ca0f0b24a0591e02aa599065b12cristy%                                                                             %
773b285095a81498ca0f0b24a0591e02aa599065b12cristy%                                                                             %
774df42b17380e9d59e0ef874a62e553c9390157b7dcristy%   C o n v e r t L C H u v T o R G B                                         %
775df42b17380e9d59e0ef874a62e553c9390157b7dcristy%                                                                             %
776df42b17380e9d59e0ef874a62e553c9390157b7dcristy%                                                                             %
777df42b17380e9d59e0ef874a62e553c9390157b7dcristy%                                                                             %
778df42b17380e9d59e0ef874a62e553c9390157b7dcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
779df42b17380e9d59e0ef874a62e553c9390157b7dcristy%
780df42b17380e9d59e0ef874a62e553c9390157b7dcristy%  ConvertLCHuvToRGB() transforms a (luma, chroma, hue) to a (red, green,
781df42b17380e9d59e0ef874a62e553c9390157b7dcristy%  blue) triple.
782df42b17380e9d59e0ef874a62e553c9390157b7dcristy%
783df42b17380e9d59e0ef874a62e553c9390157b7dcristy%  The format of the ConvertLCHuvToRGBImage method is:
784df42b17380e9d59e0ef874a62e553c9390157b7dcristy%
785df42b17380e9d59e0ef874a62e553c9390157b7dcristy%      void ConvertLCHuvToRGB(const double luma,const double chroma,
786df42b17380e9d59e0ef874a62e553c9390157b7dcristy%        const double hue,double *red,double *green,double *blue)
787df42b17380e9d59e0ef874a62e553c9390157b7dcristy%
788df42b17380e9d59e0ef874a62e553c9390157b7dcristy%  A description of each parameter follows:
789df42b17380e9d59e0ef874a62e553c9390157b7dcristy%
790df42b17380e9d59e0ef874a62e553c9390157b7dcristy%    o luma, chroma, hue: A double value representing a component of the
791df42b17380e9d59e0ef874a62e553c9390157b7dcristy%      LCHuv color space.
792df42b17380e9d59e0ef874a62e553c9390157b7dcristy%
793df42b17380e9d59e0ef874a62e553c9390157b7dcristy%    o red, green, blue: A pointer to a pixel component of type Quantum.
794df42b17380e9d59e0ef874a62e553c9390157b7dcristy%
795df42b17380e9d59e0ef874a62e553c9390157b7dcristy*/
796a8716919a55158a0c96230260000665d0db38a3acristy
797a8716919a55158a0c96230260000665d0db38a3acristystatic inline void ConvertLCHuvToXYZ(const double luma,const double chroma,
798a8716919a55158a0c96230260000665d0db38a3acristy  const double hue,double *X,double *Y,double *Z)
799a8716919a55158a0c96230260000665d0db38a3acristy{
800a8716919a55158a0c96230260000665d0db38a3acristy  ConvertLuvToXYZ(luma,chroma*cos(hue*MagickPI/180.0),chroma*
801a8716919a55158a0c96230260000665d0db38a3acristy    sin(hue*MagickPI/180.0),X,Y,Z);
802a8716919a55158a0c96230260000665d0db38a3acristy}
803a8716919a55158a0c96230260000665d0db38a3acristy
804df42b17380e9d59e0ef874a62e553c9390157b7dcristyMagickPrivate void ConvertLCHuvToRGB(const double luma,const double chroma,
805df42b17380e9d59e0ef874a62e553c9390157b7dcristy  const double hue,double *red,double *green,double *blue)
806df42b17380e9d59e0ef874a62e553c9390157b7dcristy{
807df42b17380e9d59e0ef874a62e553c9390157b7dcristy  double
808df42b17380e9d59e0ef874a62e553c9390157b7dcristy    X,
809df42b17380e9d59e0ef874a62e553c9390157b7dcristy    Y,
810df42b17380e9d59e0ef874a62e553c9390157b7dcristy    Z;
811df42b17380e9d59e0ef874a62e553c9390157b7dcristy
812df42b17380e9d59e0ef874a62e553c9390157b7dcristy  /*
813df42b17380e9d59e0ef874a62e553c9390157b7dcristy    Convert LCHuv to RGB colorspace.
814df42b17380e9d59e0ef874a62e553c9390157b7dcristy  */
815df42b17380e9d59e0ef874a62e553c9390157b7dcristy  assert(red != (double *) NULL);
816df42b17380e9d59e0ef874a62e553c9390157b7dcristy  assert(green != (double *) NULL);
817df42b17380e9d59e0ef874a62e553c9390157b7dcristy  assert(blue != (double *) NULL);
81851199219521eb593b280dce271a4fcd84fe411b3cristy  ConvertLCHuvToXYZ(100.0*luma,255.0*(chroma-0.5),360.0*hue,&X,&Y,&Z);
819df42b17380e9d59e0ef874a62e553c9390157b7dcristy  ConvertXYZToRGB(X,Y,Z,red,green,blue);
820df42b17380e9d59e0ef874a62e553c9390157b7dcristy}
821df42b17380e9d59e0ef874a62e553c9390157b7dcristy
822df42b17380e9d59e0ef874a62e553c9390157b7dcristy/*
823df42b17380e9d59e0ef874a62e553c9390157b7dcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
824df42b17380e9d59e0ef874a62e553c9390157b7dcristy%                                                                             %
825df42b17380e9d59e0ef874a62e553c9390157b7dcristy%                                                                             %
826df42b17380e9d59e0ef874a62e553c9390157b7dcristy%                                                                             %
827722fc0cce634eb07588336accc3bb52979738a5ccristy%   C o n v e r t R G B T o H C L                                             %
828722fc0cce634eb07588336accc3bb52979738a5ccristy%                                                                             %
829722fc0cce634eb07588336accc3bb52979738a5ccristy%                                                                             %
830722fc0cce634eb07588336accc3bb52979738a5ccristy%                                                                             %
831722fc0cce634eb07588336accc3bb52979738a5ccristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
832722fc0cce634eb07588336accc3bb52979738a5ccristy%
833722fc0cce634eb07588336accc3bb52979738a5ccristy%  ConvertRGBToHCL() transforms a (red, green, blue) to a (hue, chroma,
834722fc0cce634eb07588336accc3bb52979738a5ccristy%  luma) triple.
835722fc0cce634eb07588336accc3bb52979738a5ccristy%
836722fc0cce634eb07588336accc3bb52979738a5ccristy%  The format of the ConvertRGBToHCL method is:
837722fc0cce634eb07588336accc3bb52979738a5ccristy%
838722fc0cce634eb07588336accc3bb52979738a5ccristy%      void ConvertRGBToHCL(const double red,const double green,
839722fc0cce634eb07588336accc3bb52979738a5ccristy%        const double blue,double *hue,double *chroma,double *luma)
840722fc0cce634eb07588336accc3bb52979738a5ccristy%
841722fc0cce634eb07588336accc3bb52979738a5ccristy%  A description of each parameter follows:
842722fc0cce634eb07588336accc3bb52979738a5ccristy%
843722fc0cce634eb07588336accc3bb52979738a5ccristy%    o red, green, blue: A Quantum value representing the red, green, and
844722fc0cce634eb07588336accc3bb52979738a5ccristy%      blue component of a pixel.
845722fc0cce634eb07588336accc3bb52979738a5ccristy%
846722fc0cce634eb07588336accc3bb52979738a5ccristy%    o hue, chroma, luma: A pointer to a double value representing a
847722fc0cce634eb07588336accc3bb52979738a5ccristy%      component of the HCL color space.
848722fc0cce634eb07588336accc3bb52979738a5ccristy%
849722fc0cce634eb07588336accc3bb52979738a5ccristy*/
850722fc0cce634eb07588336accc3bb52979738a5ccristyMagickPrivate void ConvertRGBToHCL(const double red,const double green,
851722fc0cce634eb07588336accc3bb52979738a5ccristy  const double blue,double *hue,double *chroma,double *luma)
852722fc0cce634eb07588336accc3bb52979738a5ccristy{
853722fc0cce634eb07588336accc3bb52979738a5ccristy  double
8545756d82f940337296549c59f25ff7f96eff132b1cristy    c,
8555756d82f940337296549c59f25ff7f96eff132b1cristy    h,
856568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk    max;
857722fc0cce634eb07588336accc3bb52979738a5ccristy
858722fc0cce634eb07588336accc3bb52979738a5ccristy  /*
859722fc0cce634eb07588336accc3bb52979738a5ccristy    Convert RGB to HCL colorspace.
860722fc0cce634eb07588336accc3bb52979738a5ccristy  */
8619427c42b6fe25470c57cbb224651080a7813e7cccristy  assert(hue != (double *) NULL);
8625756d82f940337296549c59f25ff7f96eff132b1cristy  assert(chroma != (double *) NULL);
8635756d82f940337296549c59f25ff7f96eff132b1cristy  assert(luma != (double *) NULL);
864568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk  max=MagickMax(red,MagickMax(green,blue));
865568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk  c=max-(double) MagickMin(red,MagickMin(green,blue));
8665756d82f940337296549c59f25ff7f96eff132b1cristy  h=0.0;
86743974aca865ecd2f31fbf2972d92f9de78a3d900Cristy  if (fabs(c) < MagickEpsilon)
8685756d82f940337296549c59f25ff7f96eff132b1cristy    h=0.0;
8695756d82f940337296549c59f25ff7f96eff132b1cristy  else
87043974aca865ecd2f31fbf2972d92f9de78a3d900Cristy    if (fabs(red-max) < MagickEpsilon)
871568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk      h=fmod((green-blue)/c+6.0,6.0);
8725756d82f940337296549c59f25ff7f96eff132b1cristy    else
87343974aca865ecd2f31fbf2972d92f9de78a3d900Cristy      if (fabs(green-max) < MagickEpsilon)
874568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk        h=((blue-red)/c)+2.0;
8755756d82f940337296549c59f25ff7f96eff132b1cristy      else
87643974aca865ecd2f31fbf2972d92f9de78a3d900Cristy        if (fabs(blue-max) < MagickEpsilon)
877568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk          h=((red-green)/c)+4.0;
8785756d82f940337296549c59f25ff7f96eff132b1cristy  *hue=(h/6.0);
8795756d82f940337296549c59f25ff7f96eff132b1cristy  *chroma=QuantumScale*c;
880568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk  *luma=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
8819e2436a78bdabef900e018dc77c0cc497bf6fbafcristy}
8829e2436a78bdabef900e018dc77c0cc497bf6fbafcristy
8839e2436a78bdabef900e018dc77c0cc497bf6fbafcristy/*
8849e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8859e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%                                                                             %
8869e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%                                                                             %
8879e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%                                                                             %
8889e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%   C o n v e r t R G B T o H C L p                                           %
8899e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%                                                                             %
8909e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%                                                                             %
8919e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%                                                                             %
8929e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8939e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%
8949e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%  ConvertRGBToHCLp() transforms a (red, green, blue) to a (hue, chroma,
8959e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%  luma) triple.
8969e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%
8979e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%  The format of the ConvertRGBToHCLp method is:
8989e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%
8999e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%      void ConvertRGBToHCLp(const double red,const double green,
9009e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%        const double blue,double *hue,double *chroma,double *luma)
9019e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%
9029e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%  A description of each parameter follows:
9039e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%
9049e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%    o red, green, blue: A Quantum value representing the red, green, and
9059e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%      blue component of a pixel.
9069e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%
9079e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%    o hue, chroma, luma: A pointer to a double value representing a
9089e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%      component of the HCL color space.
9099e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%
9109e2436a78bdabef900e018dc77c0cc497bf6fbafcristy*/
9119e2436a78bdabef900e018dc77c0cc497bf6fbafcristyMagickPrivate void ConvertRGBToHCLp(const double red,const double green,
9129e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  const double blue,double *hue,double *chroma,double *luma)
9139e2436a78bdabef900e018dc77c0cc497bf6fbafcristy{
9149e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  double
9159e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    c,
9169e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    h,
917568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk    max;
9189e2436a78bdabef900e018dc77c0cc497bf6fbafcristy
9199e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  /*
9209e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    Convert RGB to HCL colorspace.
9219e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  */
9229e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  assert(hue != (double *) NULL);
9239e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  assert(chroma != (double *) NULL);
9249e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  assert(luma != (double *) NULL);
925568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk  max=MagickMax(red,MagickMax(green,blue));
926568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk  c=max-MagickMin(red,MagickMin(green,blue));
9279e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  h=0.0;
92843974aca865ecd2f31fbf2972d92f9de78a3d900Cristy  if (fabs(c) < MagickEpsilon)
9299e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    h=0.0;
9309e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  else
93143974aca865ecd2f31fbf2972d92f9de78a3d900Cristy    if (fabs(red-max) < MagickEpsilon)
932568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk      h=fmod((green-blue)/c+6.0,6.0);
9339e2436a78bdabef900e018dc77c0cc497bf6fbafcristy    else
93443974aca865ecd2f31fbf2972d92f9de78a3d900Cristy      if (fabs(green-max) < MagickEpsilon)
935568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk        h=((blue-red)/c)+2.0;
9369e2436a78bdabef900e018dc77c0cc497bf6fbafcristy      else
93743974aca865ecd2f31fbf2972d92f9de78a3d900Cristy        if (fabs(blue-max) < MagickEpsilon)
938568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk          h=((red-green)/c)+4.0;
9399e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  *hue=(h/6.0);
9409e2436a78bdabef900e018dc77c0cc497bf6fbafcristy  *chroma=QuantumScale*c;
941568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk  *luma=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
942722fc0cce634eb07588336accc3bb52979738a5ccristy}
943722fc0cce634eb07588336accc3bb52979738a5ccristy
944722fc0cce634eb07588336accc3bb52979738a5ccristy/*
945722fc0cce634eb07588336accc3bb52979738a5ccristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
946722fc0cce634eb07588336accc3bb52979738a5ccristy%                                                                             %
947722fc0cce634eb07588336accc3bb52979738a5ccristy%                                                                             %
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9490a39a5c567fca70403bc431d18890e89fc253eefcristy%   C o n v e r t R G B T o H S B                                             %
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9550a39a5c567fca70403bc431d18890e89fc253eefcristy%  ConvertRGBToHSB() transforms a (red, green, blue) to a (hue, saturation,
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  brightness) triple.
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9580a39a5c567fca70403bc431d18890e89fc253eefcristy%  The format of the ConvertRGBToHSB method is:
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9600a39a5c567fca70403bc431d18890e89fc253eefcristy%      void ConvertRGBToHSB(const double red,const double green,
9613094b7f3243820cc5559d370412a9d406d074348cristy%        const double blue,double *hue,double *saturation,double *brightness)
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o red, green, blue: A Quantum value representing the red, green, and
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      blue component of a pixel..
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o hue, saturation, brightness: A pointer to a double value representing a
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      component of the HSB color space.
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9720a39a5c567fca70403bc431d18890e89fc253eefcristyMagickPrivate void ConvertRGBToHSB(const double red,const double green,
9733094b7f3243820cc5559d370412a9d406d074348cristy  const double blue,double *hue,double *saturation,double *brightness)
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
975caf4580de0f80e561a5fcb59c89f2f8adac91006cristy  double
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    delta,
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    max,
978568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk    min;
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert RGB to HSB colorspace.
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(hue != (double *) NULL);
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(saturation != (double *) NULL);
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(brightness != (double *) NULL);
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *hue=0.0;
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *saturation=0.0;
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *brightness=0.0;
989568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk  min=red < green ? red : green;
990568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk  if (blue < min)
991568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk    min=blue;
992568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk  max=red > green ? red : green;
993568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk  if (blue > max)
994568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk    max=blue;
99543974aca865ecd2f31fbf2972d92f9de78a3d900Cristy  if (fabs(max) < MagickEpsilon)
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return;
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  delta=max-min;
998caf4580de0f80e561a5fcb59c89f2f8adac91006cristy  *saturation=delta/max;
999caf4580de0f80e561a5fcb59c89f2f8adac91006cristy  *brightness=QuantumScale*max;
100043974aca865ecd2f31fbf2972d92f9de78a3d900Cristy  if (fabs(delta) < MagickEpsilon)
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return;
100243974aca865ecd2f31fbf2972d92f9de78a3d900Cristy  if (fabs(red-max) < MagickEpsilon)
1003568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk    *hue=(green-blue)/delta;
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
100543974aca865ecd2f31fbf2972d92f9de78a3d900Cristy    if (fabs(green-max) < MagickEpsilon)
1006568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk      *hue=2.0+(blue-red)/delta;
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
1008568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk      *hue=4.0+(red-green)/delta;
100918b17443128598500357da7bff2f01683cf32890cristy  *hue/=6.0;
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*hue < 0.0)
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *hue+=1.0;
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1019af64eb219382bdf6243c4b8dc589268b8934304acristy%   C o n v e r t R G B T o H S I                                             %
1020af64eb219382bdf6243c4b8dc589268b8934304acristy%                                                                             %
1021af64eb219382bdf6243c4b8dc589268b8934304acristy%                                                                             %
1022af64eb219382bdf6243c4b8dc589268b8934304acristy%                                                                             %
1023af64eb219382bdf6243c4b8dc589268b8934304acristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1024af64eb219382bdf6243c4b8dc589268b8934304acristy%
1025af64eb219382bdf6243c4b8dc589268b8934304acristy%  ConvertRGBToHSI() transforms a (red, green, blue) to a (hue, saturation,
1026af64eb219382bdf6243c4b8dc589268b8934304acristy%  intensity) triple.
1027af64eb219382bdf6243c4b8dc589268b8934304acristy%
1028af64eb219382bdf6243c4b8dc589268b8934304acristy%  The format of the ConvertRGBToHSI method is:
1029af64eb219382bdf6243c4b8dc589268b8934304acristy%
1030af64eb219382bdf6243c4b8dc589268b8934304acristy%      void ConvertRGBToHSI(const double red,const double green,
1031af64eb219382bdf6243c4b8dc589268b8934304acristy%        const double blue,double *hue,double *saturation,double *intensity)
1032af64eb219382bdf6243c4b8dc589268b8934304acristy%
1033af64eb219382bdf6243c4b8dc589268b8934304acristy%  A description of each parameter follows:
1034af64eb219382bdf6243c4b8dc589268b8934304acristy%
1035af64eb219382bdf6243c4b8dc589268b8934304acristy%    o red, green, blue: A Quantum value representing the red, green, and
1036af64eb219382bdf6243c4b8dc589268b8934304acristy%      blue component of a pixel..
1037af64eb219382bdf6243c4b8dc589268b8934304acristy%
1038af64eb219382bdf6243c4b8dc589268b8934304acristy%    o hue, saturation, intensity: A pointer to a double value representing a
1039af64eb219382bdf6243c4b8dc589268b8934304acristy%      component of the HSI color space.
1040af64eb219382bdf6243c4b8dc589268b8934304acristy%
1041af64eb219382bdf6243c4b8dc589268b8934304acristy*/
1042af64eb219382bdf6243c4b8dc589268b8934304acristyMagickPrivate void ConvertRGBToHSI(const double red,const double green,
1043af64eb219382bdf6243c4b8dc589268b8934304acristy  const double blue,double *hue,double *saturation,double *intensity)
1044af64eb219382bdf6243c4b8dc589268b8934304acristy{
1045af64eb219382bdf6243c4b8dc589268b8934304acristy  double
1046af64eb219382bdf6243c4b8dc589268b8934304acristy    alpha,
1047af64eb219382bdf6243c4b8dc589268b8934304acristy    beta;
1048af64eb219382bdf6243c4b8dc589268b8934304acristy
1049af64eb219382bdf6243c4b8dc589268b8934304acristy  /*
1050af64eb219382bdf6243c4b8dc589268b8934304acristy    Convert RGB to HSI colorspace.
1051af64eb219382bdf6243c4b8dc589268b8934304acristy  */
1052af64eb219382bdf6243c4b8dc589268b8934304acristy  assert(hue != (double *) NULL);
1053af64eb219382bdf6243c4b8dc589268b8934304acristy  assert(saturation != (double *) NULL);
1054af64eb219382bdf6243c4b8dc589268b8934304acristy  assert(intensity != (double *) NULL);
1055af64eb219382bdf6243c4b8dc589268b8934304acristy  *intensity=(QuantumScale*red+QuantumScale*green+QuantumScale*blue)/3.0;
1056af64eb219382bdf6243c4b8dc589268b8934304acristy  if (*intensity <= 0.0)
1057af64eb219382bdf6243c4b8dc589268b8934304acristy    {
1058af64eb219382bdf6243c4b8dc589268b8934304acristy      *hue=0.0;
1059af64eb219382bdf6243c4b8dc589268b8934304acristy      *saturation=0.0;
1060a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      return;
1061af64eb219382bdf6243c4b8dc589268b8934304acristy    }
1062a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  *saturation=1.0-MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
1063a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    QuantumScale*blue))/(*intensity);
1064a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  alpha=0.5*(2.0*QuantumScale*red-QuantumScale*green-QuantumScale*blue);
1065be708af579eaa7bfae7d7ae760f3a8d177d3f79fcristy  beta=0.8660254037844385*(QuantumScale*green-QuantumScale*blue);
1066a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  *hue=atan2(beta,alpha)*(180.0/MagickPI)/360.0;
1067a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  if (*hue < 0.0)
1068a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    *hue+=1.0;
1069af64eb219382bdf6243c4b8dc589268b8934304acristy}
1070af64eb219382bdf6243c4b8dc589268b8934304acristy
1071af64eb219382bdf6243c4b8dc589268b8934304acristy/*
1072af64eb219382bdf6243c4b8dc589268b8934304acristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1073af64eb219382bdf6243c4b8dc589268b8934304acristy%                                                                             %
1074af64eb219382bdf6243c4b8dc589268b8934304acristy%                                                                             %
1075af64eb219382bdf6243c4b8dc589268b8934304acristy%                                                                             %
10760a39a5c567fca70403bc431d18890e89fc253eefcristy%   C o n v e r t R G B T o H S L                                             %
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10820a39a5c567fca70403bc431d18890e89fc253eefcristy%  ConvertRGBToHSL() transforms a (red, green, blue) to a (hue, saturation,
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  lightness) triple.
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10850a39a5c567fca70403bc431d18890e89fc253eefcristy%  The format of the ConvertRGBToHSL method is:
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10870a39a5c567fca70403bc431d18890e89fc253eefcristy%      void ConvertRGBToHSL(const double red,const double green,
10883094b7f3243820cc5559d370412a9d406d074348cristy%        const double blue,double *hue,double *saturation,double *lightness)
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o red, green, blue: A Quantum value representing the red, green, and
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      blue component of a pixel..
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o hue, saturation, lightness: A pointer to a double value representing a
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      component of the HSL color space.
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10990a39a5c567fca70403bc431d18890e89fc253eefcristyMagickExport void ConvertRGBToHSL(const double red,const double green,
11003094b7f3243820cc5559d370412a9d406d074348cristy  const double blue,double *hue,double *saturation,double *lightness)
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1102caf4580de0f80e561a5fcb59c89f2f8adac91006cristy  double
1103a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    c,
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    max,
1105a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    min;
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert RGB to HSL colorspace.
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(hue != (double *) NULL);
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(saturation != (double *) NULL);
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(lightness != (double *) NULL);
1113a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  max=MagickMax(QuantumScale*red,MagickMax(QuantumScale*green,
1114a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    QuantumScale*blue));
1115a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  min=MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
1116a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    QuantumScale*blue));
1117a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  c=max-min;
1118a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  *lightness=(max+min)/2.0;
1119a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  if (c <= 0.0)
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *hue=0.0;
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *saturation=0.0;
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
112543974aca865ecd2f31fbf2972d92f9de78a3d900Cristy  if (fabs(max-QuantumScale*red) < MagickEpsilon)
1126a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    {
1127a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *hue=(QuantumScale*green-QuantumScale*blue)/c;
1128a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      if ((QuantumScale*green) < (QuantumScale*blue))
1129a5a45a77350d84dcb9b38c02dca4c585c983888ccristy        *hue+=6.0;
1130a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    }
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
113243974aca865ecd2f31fbf2972d92f9de78a3d900Cristy    if (fabs(max-QuantumScale*green) < MagickEpsilon)
1133a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *hue=2.0+(QuantumScale*blue-QuantumScale*red)/c;
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
1135a5a45a77350d84dcb9b38c02dca4c585c983888ccristy      *hue=4.0+(QuantumScale*red-QuantumScale*green)/c;
1136a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  *hue*=60.0/360.0;
1137a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  if (*lightness <= 0.5)
1138a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    *saturation=c/(2.0*(*lightness));
1139a5a45a77350d84dcb9b38c02dca4c585c983888ccristy  else
1140a5a45a77350d84dcb9b38c02dca4c585c983888ccristy    *saturation=c/(2.0-2.0*(*lightness));
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1147246c3135a833b00ed2e42448c85cc2ea1269b177cristy%                                                                             %
1148246c3135a833b00ed2e42448c85cc2ea1269b177cristy%   C o n v e r t R G B T o H S V                                             %
1149246c3135a833b00ed2e42448c85cc2ea1269b177cristy%                                                                             %
1150246c3135a833b00ed2e42448c85cc2ea1269b177cristy%                                                                             %
1151246c3135a833b00ed2e42448c85cc2ea1269b177cristy%                                                                             %
1152246c3135a833b00ed2e42448c85cc2ea1269b177cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1153246c3135a833b00ed2e42448c85cc2ea1269b177cristy%
1154246c3135a833b00ed2e42448c85cc2ea1269b177cristy%  ConvertRGBToHSV() transforms a (red, green, blue) to a (hue, saturation,
1155246c3135a833b00ed2e42448c85cc2ea1269b177cristy%  value) triple.
1156246c3135a833b00ed2e42448c85cc2ea1269b177cristy%
1157246c3135a833b00ed2e42448c85cc2ea1269b177cristy%  The format of the ConvertRGBToHSV method is:
1158246c3135a833b00ed2e42448c85cc2ea1269b177cristy%
1159246c3135a833b00ed2e42448c85cc2ea1269b177cristy%      void ConvertRGBToHSV(const double red,const double green,
1160246c3135a833b00ed2e42448c85cc2ea1269b177cristy%        const double blue,double *hue,double *saturation,double *value)
1161246c3135a833b00ed2e42448c85cc2ea1269b177cristy%
1162246c3135a833b00ed2e42448c85cc2ea1269b177cristy%  A description of each parameter follows:
1163246c3135a833b00ed2e42448c85cc2ea1269b177cristy%
1164246c3135a833b00ed2e42448c85cc2ea1269b177cristy%    o red, green, blue: A Quantum value representing the red, green, and
1165246c3135a833b00ed2e42448c85cc2ea1269b177cristy%      blue component of a pixel..
1166246c3135a833b00ed2e42448c85cc2ea1269b177cristy%
1167246c3135a833b00ed2e42448c85cc2ea1269b177cristy%    o hue, saturation, value: A pointer to a double value representing a
1168246c3135a833b00ed2e42448c85cc2ea1269b177cristy%      component of the HSV color space.
1169246c3135a833b00ed2e42448c85cc2ea1269b177cristy%
1170246c3135a833b00ed2e42448c85cc2ea1269b177cristy*/
1171246c3135a833b00ed2e42448c85cc2ea1269b177cristyMagickPrivate void ConvertRGBToHSV(const double red,const double green,
1172246c3135a833b00ed2e42448c85cc2ea1269b177cristy  const double blue,double *hue,double *saturation,double *value)
1173246c3135a833b00ed2e42448c85cc2ea1269b177cristy{
1174246c3135a833b00ed2e42448c85cc2ea1269b177cristy  double
1175246c3135a833b00ed2e42448c85cc2ea1269b177cristy    c,
1176246c3135a833b00ed2e42448c85cc2ea1269b177cristy    max,
1177246c3135a833b00ed2e42448c85cc2ea1269b177cristy    min;
1178246c3135a833b00ed2e42448c85cc2ea1269b177cristy
1179246c3135a833b00ed2e42448c85cc2ea1269b177cristy  /*
1180246c3135a833b00ed2e42448c85cc2ea1269b177cristy    Convert RGB to HSV colorspace.
1181246c3135a833b00ed2e42448c85cc2ea1269b177cristy  */
1182246c3135a833b00ed2e42448c85cc2ea1269b177cristy  assert(hue != (double *) NULL);
1183246c3135a833b00ed2e42448c85cc2ea1269b177cristy  assert(saturation != (double *) NULL);
1184246c3135a833b00ed2e42448c85cc2ea1269b177cristy  assert(value != (double *) NULL);
1185246c3135a833b00ed2e42448c85cc2ea1269b177cristy  max=MagickMax(QuantumScale*red,MagickMax(QuantumScale*green,
1186246c3135a833b00ed2e42448c85cc2ea1269b177cristy    QuantumScale*blue));
1187246c3135a833b00ed2e42448c85cc2ea1269b177cristy  min=MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
1188246c3135a833b00ed2e42448c85cc2ea1269b177cristy    QuantumScale*blue));
1189246c3135a833b00ed2e42448c85cc2ea1269b177cristy  c=max-min;
1190246c3135a833b00ed2e42448c85cc2ea1269b177cristy  *value=max;
1191246c3135a833b00ed2e42448c85cc2ea1269b177cristy  if (c <= 0.0)
1192246c3135a833b00ed2e42448c85cc2ea1269b177cristy    {
1193246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *hue=0.0;
1194246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *saturation=0.0;
1195246c3135a833b00ed2e42448c85cc2ea1269b177cristy      return;
1196246c3135a833b00ed2e42448c85cc2ea1269b177cristy    }
119743974aca865ecd2f31fbf2972d92f9de78a3d900Cristy  if (fabs(max-QuantumScale*red) < MagickEpsilon)
1198246c3135a833b00ed2e42448c85cc2ea1269b177cristy    {
1199246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *hue=(QuantumScale*green-QuantumScale*blue)/c;
1200246c3135a833b00ed2e42448c85cc2ea1269b177cristy      if ((QuantumScale*green) < (QuantumScale*blue))
1201246c3135a833b00ed2e42448c85cc2ea1269b177cristy        *hue+=6.0;
1202246c3135a833b00ed2e42448c85cc2ea1269b177cristy    }
1203246c3135a833b00ed2e42448c85cc2ea1269b177cristy  else
120443974aca865ecd2f31fbf2972d92f9de78a3d900Cristy    if (fabs(max-QuantumScale*green) < MagickEpsilon)
1205246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *hue=2.0+(QuantumScale*blue-QuantumScale*red)/c;
1206246c3135a833b00ed2e42448c85cc2ea1269b177cristy    else
1207246c3135a833b00ed2e42448c85cc2ea1269b177cristy      *hue=4.0+(QuantumScale*red-QuantumScale*green)/c;
1208246c3135a833b00ed2e42448c85cc2ea1269b177cristy  *hue*=60.0/360.0;
1209246c3135a833b00ed2e42448c85cc2ea1269b177cristy  *saturation=c/max;
1210246c3135a833b00ed2e42448c85cc2ea1269b177cristy}
1211246c3135a833b00ed2e42448c85cc2ea1269b177cristy
1212246c3135a833b00ed2e42448c85cc2ea1269b177cristy/*
1213246c3135a833b00ed2e42448c85cc2ea1269b177cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1214246c3135a833b00ed2e42448c85cc2ea1269b177cristy%                                                                             %
1215246c3135a833b00ed2e42448c85cc2ea1269b177cristy%                                                                             %
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12170a39a5c567fca70403bc431d18890e89fc253eefcristy%   C o n v e r t R G B T o H W B                                             %
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12230a39a5c567fca70403bc431d18890e89fc253eefcristy%  ConvertRGBToHWB() transforms a (red, green, blue) to a (hue, whiteness,
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  blackness) triple.
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12260a39a5c567fca70403bc431d18890e89fc253eefcristy%  The format of the ConvertRGBToHWB method is:
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12280a39a5c567fca70403bc431d18890e89fc253eefcristy%      void ConvertRGBToHWB(const double red,const double green,
12293094b7f3243820cc5559d370412a9d406d074348cristy%        const double blue,double *hue,double *whiteness,double *blackness)
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o red, green, blue: A Quantum value representing the red, green, and
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      blue component of a pixel.
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o hue, whiteness, blackness: A pointer to a double value representing a
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      component of the HWB color space.
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
12400a39a5c567fca70403bc431d18890e89fc253eefcristyMagickPrivate void ConvertRGBToHWB(const double red,const double green,
12413094b7f3243820cc5559d370412a9d406d074348cristy  const double blue,double *hue,double *whiteness,double *blackness)
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1243caf4580de0f80e561a5fcb59c89f2f8adac91006cristy  double
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    f,
1245caf4580de0f80e561a5fcb59c89f2f8adac91006cristy    p,
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    v,
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    w;
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert RGB to HWB colorspace.
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(hue != (double *) NULL);
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(whiteness != (double *) NULL);
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(blackness != (double *) NULL);
1255568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk  w=MagickMin(red,MagickMin(green,blue));
1256568ce7a64b22cb8c4c961821ec5e7f437d082a90dirk  v=MagickMax(red,MagickMax(green,blue));
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *blackness=1.0-QuantumScale*v;
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *whiteness=QuantumScale*w;
125943974aca865ecd2f31fbf2972d92f9de78a3d900Cristy  if (fabs(v-w) < MagickEpsilon)
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1261af10b112a3fe7f0ca502f9cf0f8de2873ff7b97ecristy      *hue=(-1.0);
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
126443974aca865ecd2f31fbf2972d92f9de78a3d900Cristy  f=(fabs(red-w) < MagickEpsilon) ? green-blue :
126543974aca865ecd2f31fbf2972d92f9de78a3d900Cristy    ((fabs(green-w) < MagickEpsilon) ? blue-red : red-green);
126643974aca865ecd2f31fbf2972d92f9de78a3d900Cristy  p=(fabs(red-w) < MagickEpsilon) ? 3.0 :
126743974aca865ecd2f31fbf2972d92f9de78a3d900Cristy    ((fabs(green-w) < MagickEpsilon) ? 5.0 : 1.0);
1268caf4580de0f80e561a5fcb59c89f2f8adac91006cristy  *hue=(p-f/(v-1.0*w))/6.0;
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1276a83d4c0356b4f70fca3b6fb6c2ff9b52fa0e2ec5cristy%   C o n v e r t R G B T o L C H a b                                         %
1277b285095a81498ca0f0b24a0591e02aa599065b12cristy%                                                                             %
1278b285095a81498ca0f0b24a0591e02aa599065b12cristy%                                                                             %
1279b285095a81498ca0f0b24a0591e02aa599065b12cristy%                                                                             %
1280b285095a81498ca0f0b24a0591e02aa599065b12cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1281b285095a81498ca0f0b24a0591e02aa599065b12cristy%
1282df42b17380e9d59e0ef874a62e553c9390157b7dcristy%  ConvertRGBToLCHab() transforms a (red, green, blue) to a (luma, chroma,
1283b285095a81498ca0f0b24a0591e02aa599065b12cristy%  hue) triple.
1284b285095a81498ca0f0b24a0591e02aa599065b12cristy%
1285df42b17380e9d59e0ef874a62e553c9390157b7dcristy%  The format of the ConvertRGBToLCHab method is:
1286b285095a81498ca0f0b24a0591e02aa599065b12cristy%
1287df42b17380e9d59e0ef874a62e553c9390157b7dcristy%      void ConvertRGBToLCHab(const double red,const double green,
1288b285095a81498ca0f0b24a0591e02aa599065b12cristy%        const double blue,double *luma,double *chroma,double *hue)
1289b285095a81498ca0f0b24a0591e02aa599065b12cristy%
1290b285095a81498ca0f0b24a0591e02aa599065b12cristy%  A description of each parameter follows:
1291b285095a81498ca0f0b24a0591e02aa599065b12cristy%
1292b285095a81498ca0f0b24a0591e02aa599065b12cristy%    o red, green, blue: A Quantum value representing the red, green, and
1293b285095a81498ca0f0b24a0591e02aa599065b12cristy%      blue component of a pixel.
1294b285095a81498ca0f0b24a0591e02aa599065b12cristy%
1295b285095a81498ca0f0b24a0591e02aa599065b12cristy%    o luma, chroma, hue: A pointer to a double value representing a
1296b285095a81498ca0f0b24a0591e02aa599065b12cristy%      component of the LCH color space.
1297b285095a81498ca0f0b24a0591e02aa599065b12cristy%
1298b285095a81498ca0f0b24a0591e02aa599065b12cristy*/
1299c32cb02801af90aacf5ced4c59e246867078c912cristy
1300c32cb02801af90aacf5ced4c59e246867078c912cristystatic inline void ConvertXYZToLCHab(const double X,const double Y,
1301c32cb02801af90aacf5ced4c59e246867078c912cristy  const double Z,double *luma,double *chroma,double *hue)
1302c32cb02801af90aacf5ced4c59e246867078c912cristy{
1303c32cb02801af90aacf5ced4c59e246867078c912cristy  double
1304c32cb02801af90aacf5ced4c59e246867078c912cristy    a,
1305c32cb02801af90aacf5ced4c59e246867078c912cristy    b;
1306c32cb02801af90aacf5ced4c59e246867078c912cristy
1307c32cb02801af90aacf5ced4c59e246867078c912cristy  ConvertXYZToLab(X,Y,Z,luma,&a,&b);
1308846740b998cb0bf740d221ac20bd53e7fe3acaaccristy  *chroma=hypot(255.0*(a-0.5),255.0*(b-0.5))/255.0+0.5;
13096d897c70de36922ef314127ac8a202e0605bbeadcristy  *hue=180.0*atan2(255.0*(b-0.5),255.0*(a-0.5))/MagickPI/360.0;
131089106f86b28a27c7b7d9b07e13db58516ab8d01fcristy  if (*hue < 0.0)
131189106f86b28a27c7b7d9b07e13db58516ab8d01fcristy    *hue+=1.0;
1312c32cb02801af90aacf5ced4c59e246867078c912cristy}
1313c32cb02801af90aacf5ced4c59e246867078c912cristy
1314df42b17380e9d59e0ef874a62e553c9390157b7dcristyMagickPrivate void ConvertRGBToLCHab(const double red,const double green,
1315b285095a81498ca0f0b24a0591e02aa599065b12cristy  const double blue,double *luma,double *chroma,double *hue)
1316b285095a81498ca0f0b24a0591e02aa599065b12cristy{
1317b285095a81498ca0f0b24a0591e02aa599065b12cristy  double
1318b285095a81498ca0f0b24a0591e02aa599065b12cristy    X,
1319b285095a81498ca0f0b24a0591e02aa599065b12cristy    Y,
1320b285095a81498ca0f0b24a0591e02aa599065b12cristy    Z;
1321b285095a81498ca0f0b24a0591e02aa599065b12cristy
1322b285095a81498ca0f0b24a0591e02aa599065b12cristy  /*
13239427c42b6fe25470c57cbb224651080a7813e7cccristy    Convert RGB to LCHab colorspace.
1324b285095a81498ca0f0b24a0591e02aa599065b12cristy  */
1325b285095a81498ca0f0b24a0591e02aa599065b12cristy  assert(luma != (double *) NULL);
1326b285095a81498ca0f0b24a0591e02aa599065b12cristy  assert(chroma != (double *) NULL);
1327b285095a81498ca0f0b24a0591e02aa599065b12cristy  assert(hue != (double *) NULL);
1328b285095a81498ca0f0b24a0591e02aa599065b12cristy  ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
1329c32cb02801af90aacf5ced4c59e246867078c912cristy  ConvertXYZToLCHab(X,Y,Z,luma,chroma,hue);
1330b285095a81498ca0f0b24a0591e02aa599065b12cristy}
1331b285095a81498ca0f0b24a0591e02aa599065b12cristy
1332b285095a81498ca0f0b24a0591e02aa599065b12cristy/*
1333b285095a81498ca0f0b24a0591e02aa599065b12cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1334b285095a81498ca0f0b24a0591e02aa599065b12cristy%                                                                             %
1335b285095a81498ca0f0b24a0591e02aa599065b12cristy%                                                                             %
1336b285095a81498ca0f0b24a0591e02aa599065b12cristy%                                                                             %
1337a83d4c0356b4f70fca3b6fb6c2ff9b52fa0e2ec5cristy%   C o n v e r t R G B T o L C H u v                                         %
1338df42b17380e9d59e0ef874a62e553c9390157b7dcristy%                                                                             %
1339df42b17380e9d59e0ef874a62e553c9390157b7dcristy%                                                                             %
1340df42b17380e9d59e0ef874a62e553c9390157b7dcristy%                                                                             %
1341df42b17380e9d59e0ef874a62e553c9390157b7dcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1342df42b17380e9d59e0ef874a62e553c9390157b7dcristy%
1343df42b17380e9d59e0ef874a62e553c9390157b7dcristy%  ConvertRGBToLCHuv() transforms a (red, green, blue) to a (luma, chroma,
1344df42b17380e9d59e0ef874a62e553c9390157b7dcristy%  hue) triple.
1345df42b17380e9d59e0ef874a62e553c9390157b7dcristy%
1346df42b17380e9d59e0ef874a62e553c9390157b7dcristy%  The format of the ConvertRGBToLCHuv method is:
1347df42b17380e9d59e0ef874a62e553c9390157b7dcristy%
1348df42b17380e9d59e0ef874a62e553c9390157b7dcristy%      void ConvertRGBToLCHuv(const double red,const double green,
1349df42b17380e9d59e0ef874a62e553c9390157b7dcristy%        const double blue,double *luma,double *chroma,double *hue)
1350df42b17380e9d59e0ef874a62e553c9390157b7dcristy%
1351df42b17380e9d59e0ef874a62e553c9390157b7dcristy%  A description of each parameter follows:
1352df42b17380e9d59e0ef874a62e553c9390157b7dcristy%
1353df42b17380e9d59e0ef874a62e553c9390157b7dcristy%    o red, green, blue: A Quantum value representing the red, green, and
1354df42b17380e9d59e0ef874a62e553c9390157b7dcristy%      blue component of a pixel.
1355df42b17380e9d59e0ef874a62e553c9390157b7dcristy%
1356df42b17380e9d59e0ef874a62e553c9390157b7dcristy%    o luma, chroma, hue: A pointer to a double value representing a
1357df42b17380e9d59e0ef874a62e553c9390157b7dcristy%      component of the LCHuv color space.
1358df42b17380e9d59e0ef874a62e553c9390157b7dcristy%
1359df42b17380e9d59e0ef874a62e553c9390157b7dcristy*/
1360c32cb02801af90aacf5ced4c59e246867078c912cristy
1361c32cb02801af90aacf5ced4c59e246867078c912cristystatic inline void ConvertXYZToLCHuv(const double X,const double Y,
1362c32cb02801af90aacf5ced4c59e246867078c912cristy  const double Z,double *luma,double *chroma,double *hue)
1363c32cb02801af90aacf5ced4c59e246867078c912cristy{
1364c32cb02801af90aacf5ced4c59e246867078c912cristy  double
13659db2dba5a8e6618bbec0971f1b3b12423f46401dcristy    u,
13669db2dba5a8e6618bbec0971f1b3b12423f46401dcristy    v;
1367c32cb02801af90aacf5ced4c59e246867078c912cristy
13689db2dba5a8e6618bbec0971f1b3b12423f46401dcristy  ConvertXYZToLuv(X,Y,Z,luma,&u,&v);
1369846740b998cb0bf740d221ac20bd53e7fe3acaaccristy  *chroma=hypot(354.0*u-134.0,262.0*v-140.0)/255.0+0.5;
13706d897c70de36922ef314127ac8a202e0605bbeadcristy  *hue=180.0*atan2(262.0*v-140.0,354.0*u-134.0)/MagickPI/360.0;
137114a4e0fe0001bf46a434b2b40db5acd895b39331cristy  if (*hue < 0.0)
137214a4e0fe0001bf46a434b2b40db5acd895b39331cristy    *hue+=1.0;
1373c32cb02801af90aacf5ced4c59e246867078c912cristy}
1374c32cb02801af90aacf5ced4c59e246867078c912cristy
1375df42b17380e9d59e0ef874a62e553c9390157b7dcristyMagickPrivate void ConvertRGBToLCHuv(const double red,const double green,
1376df42b17380e9d59e0ef874a62e553c9390157b7dcristy  const double blue,double *luma,double *chroma,double *hue)
1377df42b17380e9d59e0ef874a62e553c9390157b7dcristy{
1378df42b17380e9d59e0ef874a62e553c9390157b7dcristy  double
1379df42b17380e9d59e0ef874a62e553c9390157b7dcristy    X,
1380df42b17380e9d59e0ef874a62e553c9390157b7dcristy    Y,
1381df42b17380e9d59e0ef874a62e553c9390157b7dcristy    Z;
1382df42b17380e9d59e0ef874a62e553c9390157b7dcristy
1383df42b17380e9d59e0ef874a62e553c9390157b7dcristy  /*
13849427c42b6fe25470c57cbb224651080a7813e7cccristy    Convert RGB to LCHuv colorspace.
1385df42b17380e9d59e0ef874a62e553c9390157b7dcristy  */
1386df42b17380e9d59e0ef874a62e553c9390157b7dcristy  assert(luma != (double *) NULL);
1387df42b17380e9d59e0ef874a62e553c9390157b7dcristy  assert(chroma != (double *) NULL);
1388df42b17380e9d59e0ef874a62e553c9390157b7dcristy  assert(hue != (double *) NULL);
1389df42b17380e9d59e0ef874a62e553c9390157b7dcristy  ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
1390c32cb02801af90aacf5ced4c59e246867078c912cristy  ConvertXYZToLCHuv(X,Y,Z,luma,chroma,hue);
1391df42b17380e9d59e0ef874a62e553c9390157b7dcristy}
1392df42b17380e9d59e0ef874a62e553c9390157b7dcristy
1393df42b17380e9d59e0ef874a62e553c9390157b7dcristy/*
1394df42b17380e9d59e0ef874a62e553c9390157b7dcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1395df42b17380e9d59e0ef874a62e553c9390157b7dcristy%                                                                             %
1396df42b17380e9d59e0ef874a62e553c9390157b7dcristy%                                                                             %
1397df42b17380e9d59e0ef874a62e553c9390157b7dcristy%                                                                             %
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   E x p a n d A f f i n e                                                   %
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ExpandAffine() computes the affine's expansion factor, i.e. the square root
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the factor by which the affine transform affects area. In an affine
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  transform composed of scaling, rotation, shearing, and translation, returns
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the amount of scaling.
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ExpandAffine method is:
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      double ExpandAffine(const AffineMatrix *affine)
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14152d7ffbbeca07eeb37beb7e8a246a4160aa9f2825cristy%    o expansion: ExpandAffine returns the affine's expansion factor.
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o affine: A pointer the affine transform of type AffineMatrix.
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport double ExpandAffine(const AffineMatrix *affine)
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(affine != (const AffineMatrix *) NULL);
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(sqrt(fabs(affine->sx*affine->sy-affine->rx*affine->ry)));
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   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                         %
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
143782b1583d4ca9179180de2754e6c25eef115cc181cristy%  GenerateDifferentialNoise() generates differentual noise.
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the GenerateDifferentialNoise method is:
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      double GenerateDifferentialNoise(RandomInfo *random_info,
14429ed1f810381187775960350780d4d619c111dc4bcristy%        const Quantum pixel,const NoiseType noise_type,const double attenuate)
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o random_info: the random info.
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o pixel: noise is relative to this pixel value.
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o noise_type: the type of noise.
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o attenuate:  attenuate the noise.
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14558ea81224e9ff022e56eb2cddb12860a8b2e90411cristyMagickPrivate double GenerateDifferentialNoise(RandomInfo *random_info,
14569ed1f810381187775960350780d4d619c111dc4bcristy  const Quantum pixel,const NoiseType noise_type,const double attenuate)
14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14587118edf0993ccec017e96e2172e6ac672d3e24cdcristy#define SigmaUniform  (attenuate*0.015625)
14597118edf0993ccec017e96e2172e6ac672d3e24cdcristy#define SigmaGaussian  (attenuate*0.015625)
14607118edf0993ccec017e96e2172e6ac672d3e24cdcristy#define SigmaImpulse  (attenuate*0.1)
14617118edf0993ccec017e96e2172e6ac672d3e24cdcristy#define SigmaLaplacian (attenuate*0.0390625)
14627118edf0993ccec017e96e2172e6ac672d3e24cdcristy#define SigmaMultiplicativeGaussian  (attenuate*0.5)
14634ce9df6057fcca6de6a4bbf18958c85ad22b106dcristy#define SigmaPoisson  (attenuate*12.5)
1464785eb590c771f467d6635fce646e366a6a3a2754cristy#define SigmaRandom  (attenuate)
14657118edf0993ccec017e96e2172e6ac672d3e24cdcristy#define TauGaussian  (attenuate*0.078125)
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1467adb41caab5f958d39a3466968df0be65ef2b1045cristy  double
14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha,
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    beta,
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    noise,
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sigma;
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha=GetPseudoRandomValue(random_info);
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (noise_type)
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case UniformNoise:
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default:
14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14796bbabe6bce89c2e8051ea16a47efd0cb42c708e2cristy      noise=(double) (pixel+QuantumRange*SigmaUniform*(alpha-0.5));
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case GaussianNoise:
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1484adb41caab5f958d39a3466968df0be65ef2b1045cristy      double
148562faa60a11bc656bbeb1b418a95de40815a4490ccristy        gamma,
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        tau;
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
148843974aca865ecd2f31fbf2972d92f9de78a3d900Cristy      if (fabs(alpha) < MagickEpsilon)
1489adb41caab5f958d39a3466968df0be65ef2b1045cristy        alpha=1.0;
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      beta=GetPseudoRandomValue(random_info);
149162faa60a11bc656bbeb1b418a95de40815a4490ccristy      gamma=sqrt(-2.0*log(alpha));
149255a91cddcdea3aa002893186a773e1704884a9dfcristy      sigma=gamma*cos((double) (2.0*MagickPI*beta));
149355a91cddcdea3aa002893186a773e1704884a9dfcristy      tau=gamma*sin((double) (2.0*MagickPI*beta));
14946bbabe6bce89c2e8051ea16a47efd0cb42c708e2cristy      noise=(double) (pixel+sqrt((double) pixel)*SigmaGaussian*sigma+
14956bbabe6bce89c2e8051ea16a47efd0cb42c708e2cristy        QuantumRange*TauGaussian*tau);
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
14973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case ImpulseNoise:
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (alpha < (SigmaImpulse/2.0))
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        noise=0.0;
150237c2407b40ceacf637731f133d9dbff27a39f669cristy      else
150337c2407b40ceacf637731f133d9dbff27a39f669cristy        if (alpha >= (1.0-(SigmaImpulse/2.0)))
150437c2407b40ceacf637731f133d9dbff27a39f669cristy          noise=(double) QuantumRange;
150537c2407b40ceacf637731f133d9dbff27a39f669cristy        else
150637c2407b40ceacf637731f133d9dbff27a39f669cristy          noise=(double) pixel;
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case LaplacianNoise:
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (alpha <= 0.5)
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
15137118edf0993ccec017e96e2172e6ac672d3e24cdcristy          if (alpha <= MagickEpsilon)
15146bbabe6bce89c2e8051ea16a47efd0cb42c708e2cristy            noise=(double) (pixel-QuantumRange);
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
1516785eb590c771f467d6635fce646e366a6a3a2754cristy            noise=(double) (pixel+QuantumRange*SigmaLaplacian*log(2.0*alpha)+
1517785eb590c771f467d6635fce646e366a6a3a2754cristy              0.5);
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      beta=1.0-alpha;
15217118edf0993ccec017e96e2172e6ac672d3e24cdcristy      if (beta <= (0.5*MagickEpsilon))
1522adb41caab5f958d39a3466968df0be65ef2b1045cristy        noise=(double) (pixel+QuantumRange);
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
15246bbabe6bce89c2e8051ea16a47efd0cb42c708e2cristy        noise=(double) (pixel-QuantumRange*SigmaLaplacian*log(2.0*beta)+0.5);
15257118edf0993ccec017e96e2172e6ac672d3e24cdcristy      break;
15267118edf0993ccec017e96e2172e6ac672d3e24cdcristy    }
15277118edf0993ccec017e96e2172e6ac672d3e24cdcristy    case MultiplicativeGaussianNoise:
15287118edf0993ccec017e96e2172e6ac672d3e24cdcristy    {
15297118edf0993ccec017e96e2172e6ac672d3e24cdcristy      sigma=1.0;
15307118edf0993ccec017e96e2172e6ac672d3e24cdcristy      if (alpha > MagickEpsilon)
15317118edf0993ccec017e96e2172e6ac672d3e24cdcristy        sigma=sqrt(-2.0*log(alpha));
15327118edf0993ccec017e96e2172e6ac672d3e24cdcristy      beta=GetPseudoRandomValue(random_info);
15336bbabe6bce89c2e8051ea16a47efd0cb42c708e2cristy      noise=(double) (pixel+pixel*SigmaMultiplicativeGaussian*sigma*
15346bbabe6bce89c2e8051ea16a47efd0cb42c708e2cristy        cos((double) (2.0*MagickPI*beta))/2.0);
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case PoissonNoise:
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1539adb41caab5f958d39a3466968df0be65ef2b1045cristy      double
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        poisson;
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1542bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15457118edf0993ccec017e96e2172e6ac672d3e24cdcristy      poisson=exp(-SigmaPoisson*QuantumScale*pixel);
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; alpha > poisson; i++)
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        beta=GetPseudoRandomValue(random_info);
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        alpha*=beta;
15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
15516bbabe6bce89c2e8051ea16a47efd0cb42c708e2cristy      noise=(double) (QuantumRange*i/SigmaPoisson);
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case RandomNoise:
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1556785eb590c771f467d6635fce646e366a6a3a2754cristy      noise=(double) (QuantumRange*SigmaRandom*alpha);
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(noise);
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   G e t O p t i m a l K e r n e l W i d t h                                 %
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  GetOptimalKernelWidth() computes the optimal kernel radius for a convolution
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  filter.  Start with the minimum value of 3 pixels and walk out until we drop
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  below the threshold of one pixel numerical accuracy.
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the GetOptimalKernelWidth method is:
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1580bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t GetOptimalKernelWidth(const double radius,
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        const double sigma)
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15852d7ffbbeca07eeb37beb7e8a246a4160aa9f2825cristy%    o width: GetOptimalKernelWidth returns the optimal width of a
15862d7ffbbeca07eeb37beb7e8a246a4160aa9f2825cristy%      convolution kernel.
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o radius: the radius of the Gaussian, in pixels, not counting the center
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      pixel.
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o sigma: the standard deviation of the Gaussian, in pixels.
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
15948ea81224e9ff022e56eb2cddb12860a8b2e90411cristyMagickPrivate size_t GetOptimalKernelWidth1D(const double radius,
1595e96405a0f45f803fb9c26f75e7bdee252437febbcristy  const double sigma)
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1597e96405a0f45f803fb9c26f75e7bdee252437febbcristy  double
1598e96405a0f45f803fb9c26f75e7bdee252437febbcristy    alpha,
1599e96405a0f45f803fb9c26f75e7bdee252437febbcristy    beta,
1600e96405a0f45f803fb9c26f75e7bdee252437febbcristy    gamma,
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    normalize,
1602e96405a0f45f803fb9c26f75e7bdee252437febbcristy    value;
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1604bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
160547e00508ba238041491b7e0daf628ae3f21ab91ecristy    i;
160647e00508ba238041491b7e0daf628ae3f21ab91ecristy
1607bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
160847e00508ba238041491b7e0daf628ae3f21ab91ecristy    width;
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16109d314ff2c17a77996c05413c2013880387e50f0ecristy  ssize_t
16119d314ff2c17a77996c05413c2013880387e50f0ecristy    j;
16129d314ff2c17a77996c05413c2013880387e50f0ecristy
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
161447e00508ba238041491b7e0daf628ae3f21ab91ecristy  if (radius > MagickEpsilon)
1615bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    return((size_t) (2.0*ceil(radius)+1.0));
1616e96405a0f45f803fb9c26f75e7bdee252437febbcristy  gamma=fabs(sigma);
1617e96405a0f45f803fb9c26f75e7bdee252437febbcristy  if (gamma <= MagickEpsilon)
1618c106172cd6da00b6c8fd6a4c06efdd4aa32c7f06anthony    return(3UL);
16193e3ec3afbb0782697f201cbe30a56794c10dc7efcristy  alpha=PerceptibleReciprocal(2.0*gamma*gamma);
16203e3ec3afbb0782697f201cbe30a56794c10dc7efcristy  beta=(double) PerceptibleReciprocal((double) MagickSQ2PI*gamma);
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (width=5; ; )
16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
16233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    normalize=0.0;
162435faaa73b04611ce5419c2bf48903d71ffea9869cristy    j=(ssize_t) (width-1)/2;
162547e00508ba238041491b7e0daf628ae3f21ab91ecristy    for (i=(-j); i <= j; i++)
1626e96405a0f45f803fb9c26f75e7bdee252437febbcristy      normalize+=exp(-((double) (i*i))*alpha)*beta;
1627e96405a0f45f803fb9c26f75e7bdee252437febbcristy    value=exp(-((double) (j*j))*alpha)*beta/normalize;
162820908dac8b2f15a9c0289728e57698bde5b74094cristy    if ((value < QuantumScale) || (value < MagickEpsilon))
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width+=2;
16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1632bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  return((size_t) (width-2));
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16358ea81224e9ff022e56eb2cddb12860a8b2e90411cristyMagickPrivate size_t GetOptimalKernelWidth2D(const double radius,
1636e96405a0f45f803fb9c26f75e7bdee252437febbcristy  const double sigma)
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
163847e00508ba238041491b7e0daf628ae3f21ab91ecristy  double
1639e96405a0f45f803fb9c26f75e7bdee252437febbcristy    alpha,
1640e96405a0f45f803fb9c26f75e7bdee252437febbcristy    beta,
1641e96405a0f45f803fb9c26f75e7bdee252437febbcristy    gamma,
16423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    normalize,
1643e96405a0f45f803fb9c26f75e7bdee252437febbcristy    value;
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16459d314ff2c17a77996c05413c2013880387e50f0ecristy  size_t
16469d314ff2c17a77996c05413c2013880387e50f0ecristy    width;
16479d314ff2c17a77996c05413c2013880387e50f0ecristy
1648bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
164947e00508ba238041491b7e0daf628ae3f21ab91ecristy    j,
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    u,
16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    v;
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
165447e00508ba238041491b7e0daf628ae3f21ab91ecristy  if (radius > MagickEpsilon)
1655bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    return((size_t) (2.0*ceil(radius)+1.0));
1656e96405a0f45f803fb9c26f75e7bdee252437febbcristy  gamma=fabs(sigma);
1657e96405a0f45f803fb9c26f75e7bdee252437febbcristy  if (gamma <= MagickEpsilon)
1658c106172cd6da00b6c8fd6a4c06efdd4aa32c7f06anthony    return(3UL);
16593e3ec3afbb0782697f201cbe30a56794c10dc7efcristy  alpha=PerceptibleReciprocal(2.0*gamma*gamma);
16603e3ec3afbb0782697f201cbe30a56794c10dc7efcristy  beta=(double) PerceptibleReciprocal((double) Magick2PI*gamma*gamma);
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (width=5; ; )
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    normalize=0.0;
166435faaa73b04611ce5419c2bf48903d71ffea9869cristy    j=(ssize_t) (width-1)/2;
166547e00508ba238041491b7e0daf628ae3f21ab91ecristy    for (v=(-j); v <= j; v++)
166647e00508ba238041491b7e0daf628ae3f21ab91ecristy      for (u=(-j); u <= j; u++)
1667e96405a0f45f803fb9c26f75e7bdee252437febbcristy        normalize+=exp(-((double) (u*u+v*v))*alpha)*beta;
1668e96405a0f45f803fb9c26f75e7bdee252437febbcristy    value=exp(-((double) (j*j))*alpha)*beta/normalize;
166920908dac8b2f15a9c0289728e57698bde5b74094cristy    if ((value < QuantumScale) || (value < MagickEpsilon))
16703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
16713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width+=2;
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1673bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  return((size_t) (width-2));
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16768ea81224e9ff022e56eb2cddb12860a8b2e90411cristyMagickPrivate size_t  GetOptimalKernelWidth(const double radius,
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const double sigma)
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetOptimalKernelWidth1D(radius,sigma));
16803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1681