gem.c revision 89106f86b28a27c7b7d9b07e13db58516ab8d01f
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 % 163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% John Cristy % 173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% August 1996 % 183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2045ef08fd6a09813e4a8f5ddadf85ba9e0ec2cdc7cristy% Copyright 1999-2013 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); 30298a65d5565159ce59b24013f0e3d148428af50d6cristy if (saturation == 0.0) 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 393af64eb219382bdf6243c4b8dc589268b8934304acristy h; 394af64eb219382bdf6243c4b8dc589268b8934304acristy 395af64eb219382bdf6243c4b8dc589268b8934304acristy /* 396af64eb219382bdf6243c4b8dc589268b8934304acristy Convert HSI to RGB colorspace. 397af64eb219382bdf6243c4b8dc589268b8934304acristy */ 398af64eb219382bdf6243c4b8dc589268b8934304acristy assert(red != (double *) NULL); 399af64eb219382bdf6243c4b8dc589268b8934304acristy assert(green != (double *) NULL); 400af64eb219382bdf6243c4b8dc589268b8934304acristy assert(blue != (double *) NULL); 401af64eb219382bdf6243c4b8dc589268b8934304acristy h=360.0*hue; 402af64eb219382bdf6243c4b8dc589268b8934304acristy h-=360.0*floor(h/360.0); 403af64eb219382bdf6243c4b8dc589268b8934304acristy if (h < 120.0) 404af64eb219382bdf6243c4b8dc589268b8934304acristy { 405af64eb219382bdf6243c4b8dc589268b8934304acristy *blue=intensity*(1.0-saturation); 406af64eb219382bdf6243c4b8dc589268b8934304acristy *red=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)* 407af64eb219382bdf6243c4b8dc589268b8934304acristy (MagickPI/180.0))); 408af64eb219382bdf6243c4b8dc589268b8934304acristy *green=3.0*intensity-*red-*blue; 409af64eb219382bdf6243c4b8dc589268b8934304acristy } 410af64eb219382bdf6243c4b8dc589268b8934304acristy else 411af64eb219382bdf6243c4b8dc589268b8934304acristy if (h < 240.0) 412af64eb219382bdf6243c4b8dc589268b8934304acristy { 413af64eb219382bdf6243c4b8dc589268b8934304acristy h-=120.0; 414af64eb219382bdf6243c4b8dc589268b8934304acristy *red=intensity*(1.0-saturation); 415af64eb219382bdf6243c4b8dc589268b8934304acristy *green=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)* 416af64eb219382bdf6243c4b8dc589268b8934304acristy (MagickPI/180.0))); 417af64eb219382bdf6243c4b8dc589268b8934304acristy *blue=3.0*intensity-*red-*green; 418af64eb219382bdf6243c4b8dc589268b8934304acristy } 419af64eb219382bdf6243c4b8dc589268b8934304acristy else 420af64eb219382bdf6243c4b8dc589268b8934304acristy { 421af64eb219382bdf6243c4b8dc589268b8934304acristy h-=240.0; 422af64eb219382bdf6243c4b8dc589268b8934304acristy *green=intensity*(1.0-saturation); 423af64eb219382bdf6243c4b8dc589268b8934304acristy *blue=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)* 424af64eb219382bdf6243c4b8dc589268b8934304acristy (MagickPI/180.0))); 425af64eb219382bdf6243c4b8dc589268b8934304acristy *red=3.0*intensity-*green-*blue; 426af64eb219382bdf6243c4b8dc589268b8934304acristy } 427af64eb219382bdf6243c4b8dc589268b8934304acristy *red*=QuantumRange; 428af64eb219382bdf6243c4b8dc589268b8934304acristy *green*=QuantumRange; 429af64eb219382bdf6243c4b8dc589268b8934304acristy *blue*=QuantumRange; 430af64eb219382bdf6243c4b8dc589268b8934304acristy} 431af64eb219382bdf6243c4b8dc589268b8934304acristy 432af64eb219382bdf6243c4b8dc589268b8934304acristy/* 433af64eb219382bdf6243c4b8dc589268b8934304acristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 434af64eb219382bdf6243c4b8dc589268b8934304acristy% % 435af64eb219382bdf6243c4b8dc589268b8934304acristy% % 436af64eb219382bdf6243c4b8dc589268b8934304acristy% % 4370a39a5c567fca70403bc431d18890e89fc253eefcristy% C o n v e r t H S L T o R G B % 4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 4430a39a5c567fca70403bc431d18890e89fc253eefcristy% ConvertHSLToRGB() transforms a (hue, saturation, lightness) to a (red, 4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% green, blue) triple. 4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 4460a39a5c567fca70403bc431d18890e89fc253eefcristy% The format of the ConvertHSLToRGBImage method is: 4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 4480a39a5c567fca70403bc431d18890e89fc253eefcristy% void ConvertHSLToRGB(const double hue,const double saturation, 4493094b7f3243820cc5559d370412a9d406d074348cristy% const double lightness,double *red,double *green,double *blue) 4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o hue, saturation, lightness: A double value representing a 4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% component of the HSL color space. 4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o red, green, blue: A pointer to a pixel component of type Quantum. 4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 4590a39a5c567fca70403bc431d18890e89fc253eefcristyMagickExport void ConvertHSLToRGB(const double hue,const double saturation, 4603094b7f3243820cc5559d370412a9d406d074348cristy const double lightness,double *red,double *green,double *blue) 4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 462caf4580de0f80e561a5fcb59c89f2f8adac91006cristy double 463a5a45a77350d84dcb9b38c02dca4c585c983888ccristy c, 464a5a45a77350d84dcb9b38c02dca4c585c983888ccristy h, 465a5a45a77350d84dcb9b38c02dca4c585c983888ccristy min, 466a5a45a77350d84dcb9b38c02dca4c585c983888ccristy x; 4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Convert HSL to RGB colorspace. 4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 4713094b7f3243820cc5559d370412a9d406d074348cristy assert(red != (double *) NULL); 4723094b7f3243820cc5559d370412a9d406d074348cristy assert(green != (double *) NULL); 4733094b7f3243820cc5559d370412a9d406d074348cristy assert(blue != (double *) NULL); 474a5a45a77350d84dcb9b38c02dca4c585c983888ccristy h=hue*360.0; 475a5a45a77350d84dcb9b38c02dca4c585c983888ccristy if (lightness <= 0.5) 476a5a45a77350d84dcb9b38c02dca4c585c983888ccristy c=2.0*lightness*saturation; 477a5a45a77350d84dcb9b38c02dca4c585c983888ccristy else 478a5a45a77350d84dcb9b38c02dca4c585c983888ccristy c=(2.0-2.0*lightness)*saturation; 479a5a45a77350d84dcb9b38c02dca4c585c983888ccristy min=lightness-0.5*c; 480a5a45a77350d84dcb9b38c02dca4c585c983888ccristy h-=360.0*floor(h/360.0); 481a5a45a77350d84dcb9b38c02dca4c585c983888ccristy h/=60.0; 482a5a45a77350d84dcb9b38c02dca4c585c983888ccristy x=c*(1.0-fabs(h-2.0*floor(h/2.0)-1.0)); 483a5a45a77350d84dcb9b38c02dca4c585c983888ccristy switch ((int) floor(h)) 484a5a45a77350d84dcb9b38c02dca4c585c983888ccristy { 485a5a45a77350d84dcb9b38c02dca4c585c983888ccristy case 0: 4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 487a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *red=QuantumRange*(min+c); 488a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *green=QuantumRange*(min+x); 489a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *blue=QuantumRange*min; 490a5a45a77350d84dcb9b38c02dca4c585c983888ccristy break; 4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 492a5a45a77350d84dcb9b38c02dca4c585c983888ccristy case 1: 493a5a45a77350d84dcb9b38c02dca4c585c983888ccristy { 494a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *red=QuantumRange*(min+x); 495a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *green=QuantumRange*(min+c); 496a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *blue=QuantumRange*min; 497a5a45a77350d84dcb9b38c02dca4c585c983888ccristy break; 498a5a45a77350d84dcb9b38c02dca4c585c983888ccristy } 499a5a45a77350d84dcb9b38c02dca4c585c983888ccristy case 2: 500a5a45a77350d84dcb9b38c02dca4c585c983888ccristy { 501a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *red=QuantumRange*min; 502a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *green=QuantumRange*(min+c); 503a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *blue=QuantumRange*(min+x); 504a5a45a77350d84dcb9b38c02dca4c585c983888ccristy break; 505a5a45a77350d84dcb9b38c02dca4c585c983888ccristy } 506a5a45a77350d84dcb9b38c02dca4c585c983888ccristy case 3: 507a5a45a77350d84dcb9b38c02dca4c585c983888ccristy { 508a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *red=QuantumRange*min; 509a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *green=QuantumRange*(min+x); 510a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *blue=QuantumRange*(min+c); 511a5a45a77350d84dcb9b38c02dca4c585c983888ccristy break; 512a5a45a77350d84dcb9b38c02dca4c585c983888ccristy } 513a5a45a77350d84dcb9b38c02dca4c585c983888ccristy case 4: 514a5a45a77350d84dcb9b38c02dca4c585c983888ccristy { 515a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *red=QuantumRange*(min+x); 516a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *green=QuantumRange*min; 517a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *blue=QuantumRange*(min+c); 518a5a45a77350d84dcb9b38c02dca4c585c983888ccristy break; 519a5a45a77350d84dcb9b38c02dca4c585c983888ccristy } 520a5a45a77350d84dcb9b38c02dca4c585c983888ccristy case 5: 521a5a45a77350d84dcb9b38c02dca4c585c983888ccristy { 522a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *red=QuantumRange*(min+c); 523a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *green=QuantumRange*min; 524a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *blue=QuantumRange*(min+x); 525a5a45a77350d84dcb9b38c02dca4c585c983888ccristy break; 526a5a45a77350d84dcb9b38c02dca4c585c983888ccristy } 527a5a45a77350d84dcb9b38c02dca4c585c983888ccristy default: 528a5a45a77350d84dcb9b38c02dca4c585c983888ccristy { 529a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *red=0.0; 530a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *green=0.0; 531a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *blue=0.0; 532a5a45a77350d84dcb9b38c02dca4c585c983888ccristy } 533a5a45a77350d84dcb9b38c02dca4c585c983888ccristy } 5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 541246c3135a833b00ed2e42448c85cc2ea1269b177cristy% C o n v e r t H S V T o R G B % 542246c3135a833b00ed2e42448c85cc2ea1269b177cristy% % 543246c3135a833b00ed2e42448c85cc2ea1269b177cristy% % 544246c3135a833b00ed2e42448c85cc2ea1269b177cristy% % 545246c3135a833b00ed2e42448c85cc2ea1269b177cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 546246c3135a833b00ed2e42448c85cc2ea1269b177cristy% 547246c3135a833b00ed2e42448c85cc2ea1269b177cristy% ConvertHSVToRGB() transforms a (hue, saturation, value) to a (red, 548246c3135a833b00ed2e42448c85cc2ea1269b177cristy% green, blue) triple. 549246c3135a833b00ed2e42448c85cc2ea1269b177cristy% 550246c3135a833b00ed2e42448c85cc2ea1269b177cristy% The format of the ConvertHSVToRGBImage method is: 551246c3135a833b00ed2e42448c85cc2ea1269b177cristy% 552246c3135a833b00ed2e42448c85cc2ea1269b177cristy% void ConvertHSVToRGB(const double hue,const double saturation, 553246c3135a833b00ed2e42448c85cc2ea1269b177cristy% const double value,double *red,double *green,double *blue) 554246c3135a833b00ed2e42448c85cc2ea1269b177cristy% 555246c3135a833b00ed2e42448c85cc2ea1269b177cristy% A description of each parameter follows: 556246c3135a833b00ed2e42448c85cc2ea1269b177cristy% 557246c3135a833b00ed2e42448c85cc2ea1269b177cristy% o hue, saturation, value: A double value representing a 558246c3135a833b00ed2e42448c85cc2ea1269b177cristy% component of the HSV color space. 559246c3135a833b00ed2e42448c85cc2ea1269b177cristy% 560246c3135a833b00ed2e42448c85cc2ea1269b177cristy% o red, green, blue: A pointer to a pixel component of type Quantum. 561246c3135a833b00ed2e42448c85cc2ea1269b177cristy% 562246c3135a833b00ed2e42448c85cc2ea1269b177cristy*/ 563246c3135a833b00ed2e42448c85cc2ea1269b177cristyMagickPrivate void ConvertHSVToRGB(const double hue,const double saturation, 564246c3135a833b00ed2e42448c85cc2ea1269b177cristy const double value,double *red,double *green,double *blue) 565246c3135a833b00ed2e42448c85cc2ea1269b177cristy{ 566246c3135a833b00ed2e42448c85cc2ea1269b177cristy double 567246c3135a833b00ed2e42448c85cc2ea1269b177cristy c, 568246c3135a833b00ed2e42448c85cc2ea1269b177cristy h, 569246c3135a833b00ed2e42448c85cc2ea1269b177cristy min, 570246c3135a833b00ed2e42448c85cc2ea1269b177cristy x; 571246c3135a833b00ed2e42448c85cc2ea1269b177cristy 572246c3135a833b00ed2e42448c85cc2ea1269b177cristy /* 573246c3135a833b00ed2e42448c85cc2ea1269b177cristy Convert HSV to RGB colorspace. 574246c3135a833b00ed2e42448c85cc2ea1269b177cristy */ 575246c3135a833b00ed2e42448c85cc2ea1269b177cristy assert(red != (double *) NULL); 576246c3135a833b00ed2e42448c85cc2ea1269b177cristy assert(green != (double *) NULL); 577246c3135a833b00ed2e42448c85cc2ea1269b177cristy assert(blue != (double *) NULL); 578246c3135a833b00ed2e42448c85cc2ea1269b177cristy h=hue*360.0; 579246c3135a833b00ed2e42448c85cc2ea1269b177cristy c=value*saturation; 580246c3135a833b00ed2e42448c85cc2ea1269b177cristy min=value-c; 581246c3135a833b00ed2e42448c85cc2ea1269b177cristy h-=360.0*floor(h/360.0); 582246c3135a833b00ed2e42448c85cc2ea1269b177cristy h/=60.0; 583246c3135a833b00ed2e42448c85cc2ea1269b177cristy x=c*(1.0-fabs(h-2.0*floor(h/2.0)-1.0)); 584246c3135a833b00ed2e42448c85cc2ea1269b177cristy switch ((int) floor(h)) 585246c3135a833b00ed2e42448c85cc2ea1269b177cristy { 586246c3135a833b00ed2e42448c85cc2ea1269b177cristy case 0: 587246c3135a833b00ed2e42448c85cc2ea1269b177cristy { 588246c3135a833b00ed2e42448c85cc2ea1269b177cristy *red=QuantumRange*(min+c); 589246c3135a833b00ed2e42448c85cc2ea1269b177cristy *green=QuantumRange*(min+x); 590246c3135a833b00ed2e42448c85cc2ea1269b177cristy *blue=QuantumRange*min; 591246c3135a833b00ed2e42448c85cc2ea1269b177cristy break; 592246c3135a833b00ed2e42448c85cc2ea1269b177cristy } 593246c3135a833b00ed2e42448c85cc2ea1269b177cristy case 1: 594246c3135a833b00ed2e42448c85cc2ea1269b177cristy { 595246c3135a833b00ed2e42448c85cc2ea1269b177cristy *red=QuantumRange*(min+x); 596246c3135a833b00ed2e42448c85cc2ea1269b177cristy *green=QuantumRange*(min+c); 597246c3135a833b00ed2e42448c85cc2ea1269b177cristy *blue=QuantumRange*min; 598246c3135a833b00ed2e42448c85cc2ea1269b177cristy break; 599246c3135a833b00ed2e42448c85cc2ea1269b177cristy } 600246c3135a833b00ed2e42448c85cc2ea1269b177cristy case 2: 601246c3135a833b00ed2e42448c85cc2ea1269b177cristy { 602246c3135a833b00ed2e42448c85cc2ea1269b177cristy *red=QuantumRange*min; 603246c3135a833b00ed2e42448c85cc2ea1269b177cristy *green=QuantumRange*(min+c); 604246c3135a833b00ed2e42448c85cc2ea1269b177cristy *blue=QuantumRange*(min+x); 605246c3135a833b00ed2e42448c85cc2ea1269b177cristy break; 606246c3135a833b00ed2e42448c85cc2ea1269b177cristy } 607246c3135a833b00ed2e42448c85cc2ea1269b177cristy case 3: 608246c3135a833b00ed2e42448c85cc2ea1269b177cristy { 609246c3135a833b00ed2e42448c85cc2ea1269b177cristy *red=QuantumRange*min; 610246c3135a833b00ed2e42448c85cc2ea1269b177cristy *green=QuantumRange*(min+x); 611246c3135a833b00ed2e42448c85cc2ea1269b177cristy *blue=QuantumRange*(min+c); 612246c3135a833b00ed2e42448c85cc2ea1269b177cristy break; 613246c3135a833b00ed2e42448c85cc2ea1269b177cristy } 614246c3135a833b00ed2e42448c85cc2ea1269b177cristy case 4: 615246c3135a833b00ed2e42448c85cc2ea1269b177cristy { 616246c3135a833b00ed2e42448c85cc2ea1269b177cristy *red=QuantumRange*(min+x); 617246c3135a833b00ed2e42448c85cc2ea1269b177cristy *green=QuantumRange*min; 618246c3135a833b00ed2e42448c85cc2ea1269b177cristy *blue=QuantumRange*(min+c); 619246c3135a833b00ed2e42448c85cc2ea1269b177cristy break; 620246c3135a833b00ed2e42448c85cc2ea1269b177cristy } 621246c3135a833b00ed2e42448c85cc2ea1269b177cristy case 5: 622246c3135a833b00ed2e42448c85cc2ea1269b177cristy { 623246c3135a833b00ed2e42448c85cc2ea1269b177cristy *red=QuantumRange*(min+c); 624246c3135a833b00ed2e42448c85cc2ea1269b177cristy *green=QuantumRange*min; 625246c3135a833b00ed2e42448c85cc2ea1269b177cristy *blue=QuantumRange*(min+x); 626246c3135a833b00ed2e42448c85cc2ea1269b177cristy break; 627246c3135a833b00ed2e42448c85cc2ea1269b177cristy } 628246c3135a833b00ed2e42448c85cc2ea1269b177cristy default: 629246c3135a833b00ed2e42448c85cc2ea1269b177cristy { 630246c3135a833b00ed2e42448c85cc2ea1269b177cristy *red=0.0; 631246c3135a833b00ed2e42448c85cc2ea1269b177cristy *green=0.0; 632246c3135a833b00ed2e42448c85cc2ea1269b177cristy *blue=0.0; 633246c3135a833b00ed2e42448c85cc2ea1269b177cristy } 634246c3135a833b00ed2e42448c85cc2ea1269b177cristy } 635246c3135a833b00ed2e42448c85cc2ea1269b177cristy} 636246c3135a833b00ed2e42448c85cc2ea1269b177cristy 637246c3135a833b00ed2e42448c85cc2ea1269b177cristy/* 638246c3135a833b00ed2e42448c85cc2ea1269b177cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 639246c3135a833b00ed2e42448c85cc2ea1269b177cristy% % 640246c3135a833b00ed2e42448c85cc2ea1269b177cristy% % 641246c3135a833b00ed2e42448c85cc2ea1269b177cristy% % 6420a39a5c567fca70403bc431d18890e89fc253eefcristy% C o n v e r t H W B T o R G B % 6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6480a39a5c567fca70403bc431d18890e89fc253eefcristy% ConvertHWBToRGB() transforms a (hue, whiteness, blackness) to a (red, green, 6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% blue) triple. 6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6510a39a5c567fca70403bc431d18890e89fc253eefcristy% The format of the ConvertHWBToRGBImage method is: 6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6530a39a5c567fca70403bc431d18890e89fc253eefcristy% void ConvertHWBToRGB(const double hue,const double whiteness, 6543094b7f3243820cc5559d370412a9d406d074348cristy% const double blackness,double *red,double *green,double *blue) 6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o hue, whiteness, blackness: A double value representing a 6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% component of the HWB color space. 6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o red, green, blue: A pointer to a pixel component of type Quantum. 6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 6640a39a5c567fca70403bc431d18890e89fc253eefcristyMagickPrivate void ConvertHWBToRGB(const double hue,const double whiteness, 6653094b7f3243820cc5559d370412a9d406d074348cristy const double blackness,double *red,double *green,double *blue) 6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 667caf4580de0f80e561a5fcb59c89f2f8adac91006cristy double 6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy b, 6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy f, 6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy g, 6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy n, 6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy r, 6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy v; 6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 675bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Convert HWB to RGB colorspace. 6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 6813094b7f3243820cc5559d370412a9d406d074348cristy assert(red != (double *) NULL); 6823094b7f3243820cc5559d370412a9d406d074348cristy assert(green != (double *) NULL); 6833094b7f3243820cc5559d370412a9d406d074348cristy assert(blue != (double *) NULL); 6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy v=1.0-blackness; 685af10b112a3fe7f0ca502f9cf0f8de2873ff7b97ecristy if (hue == -1.0) 6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6870a39a5c567fca70403bc431d18890e89fc253eefcristy *red=QuantumRange*v; 6880a39a5c567fca70403bc431d18890e89fc253eefcristy *green=QuantumRange*v; 6890a39a5c567fca70403bc431d18890e89fc253eefcristy *blue=QuantumRange*v; 6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return; 6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 692bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy i=(ssize_t) floor(6.0*hue); 6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy f=6.0*hue-i; 6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((i & 0x01) != 0) 6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy f=1.0-f; 6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy n=whiteness+f*(v-whiteness); /* linear interpolation */ 6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy switch (i) 6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy default: 7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 6: 7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 0: r=v; g=n; b=whiteness; break; 7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 1: r=n; g=v; b=whiteness; break; 7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 2: r=whiteness; g=v; b=n; break; 7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 3: r=whiteness; g=n; b=v; break; 7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 4: r=n; g=whiteness; b=v; break; 7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 5: r=v; g=whiteness; b=n; break; 7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 7080a39a5c567fca70403bc431d18890e89fc253eefcristy *red=QuantumRange*r; 7090a39a5c567fca70403bc431d18890e89fc253eefcristy *green=QuantumRange*g; 7100a39a5c567fca70403bc431d18890e89fc253eefcristy *blue=QuantumRange*b; 7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 717722fc0cce634eb07588336accc3bb52979738a5ccristy% % 718df42b17380e9d59e0ef874a62e553c9390157b7dcristy% C o n v e r t L C H a b T o R G B % 719b285095a81498ca0f0b24a0591e02aa599065b12cristy% % 720b285095a81498ca0f0b24a0591e02aa599065b12cristy% % 721b285095a81498ca0f0b24a0591e02aa599065b12cristy% % 722b285095a81498ca0f0b24a0591e02aa599065b12cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 723b285095a81498ca0f0b24a0591e02aa599065b12cristy% 724df42b17380e9d59e0ef874a62e553c9390157b7dcristy% ConvertLCHabToRGB() transforms a (luma, chroma, hue) to a (red, green, 725b285095a81498ca0f0b24a0591e02aa599065b12cristy% blue) triple. 726b285095a81498ca0f0b24a0591e02aa599065b12cristy% 727df42b17380e9d59e0ef874a62e553c9390157b7dcristy% The format of the ConvertLCHabToRGBImage method is: 728b285095a81498ca0f0b24a0591e02aa599065b12cristy% 729df42b17380e9d59e0ef874a62e553c9390157b7dcristy% void ConvertLCHabToRGB(const double luma,const double chroma, 730b285095a81498ca0f0b24a0591e02aa599065b12cristy% const double hue,double *red,double *green,double *blue) 731b285095a81498ca0f0b24a0591e02aa599065b12cristy% 732b285095a81498ca0f0b24a0591e02aa599065b12cristy% A description of each parameter follows: 733b285095a81498ca0f0b24a0591e02aa599065b12cristy% 734df42b17380e9d59e0ef874a62e553c9390157b7dcristy% o luma, chroma, hue: A double value representing a component of the 735df42b17380e9d59e0ef874a62e553c9390157b7dcristy% LCHab color space. 736b285095a81498ca0f0b24a0591e02aa599065b12cristy% 737b285095a81498ca0f0b24a0591e02aa599065b12cristy% o red, green, blue: A pointer to a pixel component of type Quantum. 738b285095a81498ca0f0b24a0591e02aa599065b12cristy% 739b285095a81498ca0f0b24a0591e02aa599065b12cristy*/ 74035605e9ee687899cf1c79cf27572fba678ce636ecristy 74135605e9ee687899cf1c79cf27572fba678ce636ecristystatic inline void ConvertLCHabToXYZ(const double luma,const double chroma, 74235605e9ee687899cf1c79cf27572fba678ce636ecristy const double hue,double *X,double *Y,double *Z) 74335605e9ee687899cf1c79cf27572fba678ce636ecristy{ 74435605e9ee687899cf1c79cf27572fba678ce636ecristy ConvertLabToXYZ(luma,chroma*cos(hue*MagickPI/180.0),chroma* 74535605e9ee687899cf1c79cf27572fba678ce636ecristy sin(hue*MagickPI/180.0),X,Y,Z); 74635605e9ee687899cf1c79cf27572fba678ce636ecristy} 74735605e9ee687899cf1c79cf27572fba678ce636ecristy 748df42b17380e9d59e0ef874a62e553c9390157b7dcristyMagickPrivate void ConvertLCHabToRGB(const double luma,const double chroma, 749b285095a81498ca0f0b24a0591e02aa599065b12cristy const double hue,double *red,double *green,double *blue) 750b285095a81498ca0f0b24a0591e02aa599065b12cristy{ 751b285095a81498ca0f0b24a0591e02aa599065b12cristy double 752b285095a81498ca0f0b24a0591e02aa599065b12cristy X, 753b285095a81498ca0f0b24a0591e02aa599065b12cristy Y, 754b285095a81498ca0f0b24a0591e02aa599065b12cristy Z; 755b285095a81498ca0f0b24a0591e02aa599065b12cristy 756b285095a81498ca0f0b24a0591e02aa599065b12cristy /* 757df42b17380e9d59e0ef874a62e553c9390157b7dcristy Convert LCHab to RGB colorspace. 758b285095a81498ca0f0b24a0591e02aa599065b12cristy */ 759b285095a81498ca0f0b24a0591e02aa599065b12cristy assert(red != (double *) NULL); 760b285095a81498ca0f0b24a0591e02aa599065b12cristy assert(green != (double *) NULL); 761b285095a81498ca0f0b24a0591e02aa599065b12cristy assert(blue != (double *) NULL); 7620c125416d27796cd9becc0df8cbb763ee1c5e189cristy ConvertLCHabToXYZ(100.0*luma,255.0*(chroma-0.5),255.0*(hue-0.5),&X,&Y,&Z); 763b285095a81498ca0f0b24a0591e02aa599065b12cristy ConvertXYZToRGB(X,Y,Z,red,green,blue); 764b285095a81498ca0f0b24a0591e02aa599065b12cristy} 765b285095a81498ca0f0b24a0591e02aa599065b12cristy 766b285095a81498ca0f0b24a0591e02aa599065b12cristy/* 767b285095a81498ca0f0b24a0591e02aa599065b12cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 768b285095a81498ca0f0b24a0591e02aa599065b12cristy% % 769b285095a81498ca0f0b24a0591e02aa599065b12cristy% % 770b285095a81498ca0f0b24a0591e02aa599065b12cristy% % 771df42b17380e9d59e0ef874a62e553c9390157b7dcristy% C o n v e r t L C H u v T o R G B % 772df42b17380e9d59e0ef874a62e553c9390157b7dcristy% % 773df42b17380e9d59e0ef874a62e553c9390157b7dcristy% % 774df42b17380e9d59e0ef874a62e553c9390157b7dcristy% % 775df42b17380e9d59e0ef874a62e553c9390157b7dcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 776df42b17380e9d59e0ef874a62e553c9390157b7dcristy% 777df42b17380e9d59e0ef874a62e553c9390157b7dcristy% ConvertLCHuvToRGB() transforms a (luma, chroma, hue) to a (red, green, 778df42b17380e9d59e0ef874a62e553c9390157b7dcristy% blue) triple. 779df42b17380e9d59e0ef874a62e553c9390157b7dcristy% 780df42b17380e9d59e0ef874a62e553c9390157b7dcristy% The format of the ConvertLCHuvToRGBImage method is: 781df42b17380e9d59e0ef874a62e553c9390157b7dcristy% 782df42b17380e9d59e0ef874a62e553c9390157b7dcristy% void ConvertLCHuvToRGB(const double luma,const double chroma, 783df42b17380e9d59e0ef874a62e553c9390157b7dcristy% const double hue,double *red,double *green,double *blue) 784df42b17380e9d59e0ef874a62e553c9390157b7dcristy% 785df42b17380e9d59e0ef874a62e553c9390157b7dcristy% A description of each parameter follows: 786df42b17380e9d59e0ef874a62e553c9390157b7dcristy% 787df42b17380e9d59e0ef874a62e553c9390157b7dcristy% o luma, chroma, hue: A double value representing a component of the 788df42b17380e9d59e0ef874a62e553c9390157b7dcristy% LCHuv color space. 789df42b17380e9d59e0ef874a62e553c9390157b7dcristy% 790df42b17380e9d59e0ef874a62e553c9390157b7dcristy% o red, green, blue: A pointer to a pixel component of type Quantum. 791df42b17380e9d59e0ef874a62e553c9390157b7dcristy% 792df42b17380e9d59e0ef874a62e553c9390157b7dcristy*/ 793a8716919a55158a0c96230260000665d0db38a3acristy 794a8716919a55158a0c96230260000665d0db38a3acristystatic inline void ConvertLCHuvToXYZ(const double luma,const double chroma, 795a8716919a55158a0c96230260000665d0db38a3acristy const double hue,double *X,double *Y,double *Z) 796a8716919a55158a0c96230260000665d0db38a3acristy{ 797a8716919a55158a0c96230260000665d0db38a3acristy ConvertLuvToXYZ(luma,chroma*cos(hue*MagickPI/180.0),chroma* 798a8716919a55158a0c96230260000665d0db38a3acristy sin(hue*MagickPI/180.0),X,Y,Z); 799a8716919a55158a0c96230260000665d0db38a3acristy} 800a8716919a55158a0c96230260000665d0db38a3acristy 801df42b17380e9d59e0ef874a62e553c9390157b7dcristyMagickPrivate void ConvertLCHuvToRGB(const double luma,const double chroma, 802df42b17380e9d59e0ef874a62e553c9390157b7dcristy const double hue,double *red,double *green,double *blue) 803df42b17380e9d59e0ef874a62e553c9390157b7dcristy{ 804df42b17380e9d59e0ef874a62e553c9390157b7dcristy double 805df42b17380e9d59e0ef874a62e553c9390157b7dcristy X, 806df42b17380e9d59e0ef874a62e553c9390157b7dcristy Y, 807df42b17380e9d59e0ef874a62e553c9390157b7dcristy Z; 808df42b17380e9d59e0ef874a62e553c9390157b7dcristy 809df42b17380e9d59e0ef874a62e553c9390157b7dcristy /* 810df42b17380e9d59e0ef874a62e553c9390157b7dcristy Convert LCHuv to RGB colorspace. 811df42b17380e9d59e0ef874a62e553c9390157b7dcristy */ 812df42b17380e9d59e0ef874a62e553c9390157b7dcristy assert(red != (double *) NULL); 813df42b17380e9d59e0ef874a62e553c9390157b7dcristy assert(green != (double *) NULL); 814df42b17380e9d59e0ef874a62e553c9390157b7dcristy assert(blue != (double *) NULL); 815a8716919a55158a0c96230260000665d0db38a3acristy ConvertLCHuvToXYZ(100.0*luma,354.0*chroma-134.0,262.0*hue-140.0,&X,&Y,&Z); 816df42b17380e9d59e0ef874a62e553c9390157b7dcristy ConvertXYZToRGB(X,Y,Z,red,green,blue); 817df42b17380e9d59e0ef874a62e553c9390157b7dcristy} 818df42b17380e9d59e0ef874a62e553c9390157b7dcristy 819df42b17380e9d59e0ef874a62e553c9390157b7dcristy/* 820df42b17380e9d59e0ef874a62e553c9390157b7dcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 821df42b17380e9d59e0ef874a62e553c9390157b7dcristy% % 822df42b17380e9d59e0ef874a62e553c9390157b7dcristy% % 823df42b17380e9d59e0ef874a62e553c9390157b7dcristy% % 824722fc0cce634eb07588336accc3bb52979738a5ccristy% C o n v e r t R G B T o H C L % 825722fc0cce634eb07588336accc3bb52979738a5ccristy% % 826722fc0cce634eb07588336accc3bb52979738a5ccristy% % 827722fc0cce634eb07588336accc3bb52979738a5ccristy% % 828722fc0cce634eb07588336accc3bb52979738a5ccristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 829722fc0cce634eb07588336accc3bb52979738a5ccristy% 830722fc0cce634eb07588336accc3bb52979738a5ccristy% ConvertRGBToHCL() transforms a (red, green, blue) to a (hue, chroma, 831722fc0cce634eb07588336accc3bb52979738a5ccristy% luma) triple. 832722fc0cce634eb07588336accc3bb52979738a5ccristy% 833722fc0cce634eb07588336accc3bb52979738a5ccristy% The format of the ConvertRGBToHCL method is: 834722fc0cce634eb07588336accc3bb52979738a5ccristy% 835722fc0cce634eb07588336accc3bb52979738a5ccristy% void ConvertRGBToHCL(const double red,const double green, 836722fc0cce634eb07588336accc3bb52979738a5ccristy% const double blue,double *hue,double *chroma,double *luma) 837722fc0cce634eb07588336accc3bb52979738a5ccristy% 838722fc0cce634eb07588336accc3bb52979738a5ccristy% A description of each parameter follows: 839722fc0cce634eb07588336accc3bb52979738a5ccristy% 840722fc0cce634eb07588336accc3bb52979738a5ccristy% o red, green, blue: A Quantum value representing the red, green, and 841722fc0cce634eb07588336accc3bb52979738a5ccristy% blue component of a pixel. 842722fc0cce634eb07588336accc3bb52979738a5ccristy% 843722fc0cce634eb07588336accc3bb52979738a5ccristy% o hue, chroma, luma: A pointer to a double value representing a 844722fc0cce634eb07588336accc3bb52979738a5ccristy% component of the HCL color space. 845722fc0cce634eb07588336accc3bb52979738a5ccristy% 846722fc0cce634eb07588336accc3bb52979738a5ccristy*/ 8475756d82f940337296549c59f25ff7f96eff132b1cristy 8485756d82f940337296549c59f25ff7f96eff132b1cristystatic inline double MagickMax(const double x,const double y) 8495756d82f940337296549c59f25ff7f96eff132b1cristy{ 8505756d82f940337296549c59f25ff7f96eff132b1cristy if (x > y) 8515756d82f940337296549c59f25ff7f96eff132b1cristy return(x); 8525756d82f940337296549c59f25ff7f96eff132b1cristy return(y); 8535756d82f940337296549c59f25ff7f96eff132b1cristy} 8545756d82f940337296549c59f25ff7f96eff132b1cristy 8555756d82f940337296549c59f25ff7f96eff132b1cristystatic inline double MagickMin(const double x,const double y) 8565756d82f940337296549c59f25ff7f96eff132b1cristy{ 8575756d82f940337296549c59f25ff7f96eff132b1cristy if (x < y) 8585756d82f940337296549c59f25ff7f96eff132b1cristy return(x); 8595756d82f940337296549c59f25ff7f96eff132b1cristy return(y); 8605756d82f940337296549c59f25ff7f96eff132b1cristy} 8615756d82f940337296549c59f25ff7f96eff132b1cristy 862722fc0cce634eb07588336accc3bb52979738a5ccristyMagickPrivate void ConvertRGBToHCL(const double red,const double green, 863722fc0cce634eb07588336accc3bb52979738a5ccristy const double blue,double *hue,double *chroma,double *luma) 864722fc0cce634eb07588336accc3bb52979738a5ccristy{ 865722fc0cce634eb07588336accc3bb52979738a5ccristy double 8665756d82f940337296549c59f25ff7f96eff132b1cristy b, 8675756d82f940337296549c59f25ff7f96eff132b1cristy c, 8685756d82f940337296549c59f25ff7f96eff132b1cristy g, 8695756d82f940337296549c59f25ff7f96eff132b1cristy h, 8705756d82f940337296549c59f25ff7f96eff132b1cristy max, 8715756d82f940337296549c59f25ff7f96eff132b1cristy r; 872722fc0cce634eb07588336accc3bb52979738a5ccristy 873722fc0cce634eb07588336accc3bb52979738a5ccristy /* 874722fc0cce634eb07588336accc3bb52979738a5ccristy Convert RGB to HCL colorspace. 875722fc0cce634eb07588336accc3bb52979738a5ccristy */ 8769427c42b6fe25470c57cbb224651080a7813e7cccristy assert(hue != (double *) NULL); 8775756d82f940337296549c59f25ff7f96eff132b1cristy assert(chroma != (double *) NULL); 8785756d82f940337296549c59f25ff7f96eff132b1cristy assert(luma != (double *) NULL); 8795756d82f940337296549c59f25ff7f96eff132b1cristy r=red; 8805756d82f940337296549c59f25ff7f96eff132b1cristy g=green; 8815756d82f940337296549c59f25ff7f96eff132b1cristy b=blue; 8825756d82f940337296549c59f25ff7f96eff132b1cristy max=MagickMax(r,MagickMax(g,b)); 8835756d82f940337296549c59f25ff7f96eff132b1cristy c=max-(double) MagickMin(r,MagickMin(g,b)); 8845756d82f940337296549c59f25ff7f96eff132b1cristy h=0.0; 8855756d82f940337296549c59f25ff7f96eff132b1cristy if (c == 0.0) 8865756d82f940337296549c59f25ff7f96eff132b1cristy h=0.0; 8875756d82f940337296549c59f25ff7f96eff132b1cristy else 8885756d82f940337296549c59f25ff7f96eff132b1cristy if (red == max) 8895756d82f940337296549c59f25ff7f96eff132b1cristy h=fmod((g-b)/c+6.0,6.0); 8905756d82f940337296549c59f25ff7f96eff132b1cristy else 8915756d82f940337296549c59f25ff7f96eff132b1cristy if (green == max) 8925756d82f940337296549c59f25ff7f96eff132b1cristy h=((b-r)/c)+2.0; 8935756d82f940337296549c59f25ff7f96eff132b1cristy else 8945756d82f940337296549c59f25ff7f96eff132b1cristy if (blue == max) 8955756d82f940337296549c59f25ff7f96eff132b1cristy h=((r-g)/c)+4.0; 8965756d82f940337296549c59f25ff7f96eff132b1cristy *hue=(h/6.0); 8975756d82f940337296549c59f25ff7f96eff132b1cristy *chroma=QuantumScale*c; 8989e2436a78bdabef900e018dc77c0cc497bf6fbafcristy *luma=QuantumScale*(0.298839*r+0.586811*g+0.114350*b); 8999e2436a78bdabef900e018dc77c0cc497bf6fbafcristy} 9009e2436a78bdabef900e018dc77c0cc497bf6fbafcristy 9019e2436a78bdabef900e018dc77c0cc497bf6fbafcristy/* 9029e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9039e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% % 9049e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% % 9059e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% % 9069e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% C o n v e r t R G B T o H C L p % 9079e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% % 9089e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% % 9099e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% % 9109e2436a78bdabef900e018dc77c0cc497bf6fbafcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9119e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% 9129e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% ConvertRGBToHCLp() transforms a (red, green, blue) to a (hue, chroma, 9139e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% luma) triple. 9149e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% 9159e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% The format of the ConvertRGBToHCLp method is: 9169e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% 9179e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% void ConvertRGBToHCLp(const double red,const double green, 9189e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% const double blue,double *hue,double *chroma,double *luma) 9199e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% 9209e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% A description of each parameter follows: 9219e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% 9229e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% o red, green, blue: A Quantum value representing the red, green, and 9239e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% blue component of a pixel. 9249e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% 9259e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% o hue, chroma, luma: A pointer to a double value representing a 9269e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% component of the HCL color space. 9279e2436a78bdabef900e018dc77c0cc497bf6fbafcristy% 9289e2436a78bdabef900e018dc77c0cc497bf6fbafcristy*/ 9299e2436a78bdabef900e018dc77c0cc497bf6fbafcristyMagickPrivate void ConvertRGBToHCLp(const double red,const double green, 9309e2436a78bdabef900e018dc77c0cc497bf6fbafcristy const double blue,double *hue,double *chroma,double *luma) 9319e2436a78bdabef900e018dc77c0cc497bf6fbafcristy{ 9329e2436a78bdabef900e018dc77c0cc497bf6fbafcristy double 9339e2436a78bdabef900e018dc77c0cc497bf6fbafcristy b, 9349e2436a78bdabef900e018dc77c0cc497bf6fbafcristy c, 9359e2436a78bdabef900e018dc77c0cc497bf6fbafcristy g, 9369e2436a78bdabef900e018dc77c0cc497bf6fbafcristy h, 9379e2436a78bdabef900e018dc77c0cc497bf6fbafcristy max, 9389e2436a78bdabef900e018dc77c0cc497bf6fbafcristy r; 9399e2436a78bdabef900e018dc77c0cc497bf6fbafcristy 9409e2436a78bdabef900e018dc77c0cc497bf6fbafcristy /* 9419e2436a78bdabef900e018dc77c0cc497bf6fbafcristy Convert RGB to HCL colorspace. 9429e2436a78bdabef900e018dc77c0cc497bf6fbafcristy */ 9439e2436a78bdabef900e018dc77c0cc497bf6fbafcristy assert(hue != (double *) NULL); 9449e2436a78bdabef900e018dc77c0cc497bf6fbafcristy assert(chroma != (double *) NULL); 9459e2436a78bdabef900e018dc77c0cc497bf6fbafcristy assert(luma != (double *) NULL); 9469e2436a78bdabef900e018dc77c0cc497bf6fbafcristy r=red; 9479e2436a78bdabef900e018dc77c0cc497bf6fbafcristy g=green; 9489e2436a78bdabef900e018dc77c0cc497bf6fbafcristy b=blue; 9499e2436a78bdabef900e018dc77c0cc497bf6fbafcristy max=MagickMax(r,MagickMax(g,b)); 9509e2436a78bdabef900e018dc77c0cc497bf6fbafcristy c=max-(double) MagickMin(r,MagickMin(g,b)); 9519e2436a78bdabef900e018dc77c0cc497bf6fbafcristy h=0.0; 9529e2436a78bdabef900e018dc77c0cc497bf6fbafcristy if (c == 0.0) 9539e2436a78bdabef900e018dc77c0cc497bf6fbafcristy h=0.0; 9549e2436a78bdabef900e018dc77c0cc497bf6fbafcristy else 9559e2436a78bdabef900e018dc77c0cc497bf6fbafcristy if (red == max) 9569e2436a78bdabef900e018dc77c0cc497bf6fbafcristy h=fmod((g-b)/c+6.0,6.0); 9579e2436a78bdabef900e018dc77c0cc497bf6fbafcristy else 9589e2436a78bdabef900e018dc77c0cc497bf6fbafcristy if (green == max) 9599e2436a78bdabef900e018dc77c0cc497bf6fbafcristy h=((b-r)/c)+2.0; 9609e2436a78bdabef900e018dc77c0cc497bf6fbafcristy else 9619e2436a78bdabef900e018dc77c0cc497bf6fbafcristy if (blue == max) 9629e2436a78bdabef900e018dc77c0cc497bf6fbafcristy h=((r-g)/c)+4.0; 9639e2436a78bdabef900e018dc77c0cc497bf6fbafcristy *hue=(h/6.0); 9649e2436a78bdabef900e018dc77c0cc497bf6fbafcristy *chroma=QuantumScale*c; 9659e2436a78bdabef900e018dc77c0cc497bf6fbafcristy *luma=QuantumScale*(0.298839*r+0.586811*g+0.114350*b); 966722fc0cce634eb07588336accc3bb52979738a5ccristy} 967722fc0cce634eb07588336accc3bb52979738a5ccristy 968722fc0cce634eb07588336accc3bb52979738a5ccristy/* 969722fc0cce634eb07588336accc3bb52979738a5ccristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 970722fc0cce634eb07588336accc3bb52979738a5ccristy% % 971722fc0cce634eb07588336accc3bb52979738a5ccristy% % 9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9730a39a5c567fca70403bc431d18890e89fc253eefcristy% C o n v e r t R G B T o H S B % 9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9790a39a5c567fca70403bc431d18890e89fc253eefcristy% ConvertRGBToHSB() transforms a (red, green, blue) to a (hue, saturation, 9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% brightness) triple. 9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9820a39a5c567fca70403bc431d18890e89fc253eefcristy% The format of the ConvertRGBToHSB method is: 9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9840a39a5c567fca70403bc431d18890e89fc253eefcristy% void ConvertRGBToHSB(const double red,const double green, 9853094b7f3243820cc5559d370412a9d406d074348cristy% const double blue,double *hue,double *saturation,double *brightness) 9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o red, green, blue: A Quantum value representing the red, green, and 9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% blue component of a pixel.. 9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o hue, saturation, brightness: A pointer to a double value representing a 9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% component of the HSB color space. 9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 9960a39a5c567fca70403bc431d18890e89fc253eefcristyMagickPrivate void ConvertRGBToHSB(const double red,const double green, 9973094b7f3243820cc5559d370412a9d406d074348cristy const double blue,double *hue,double *saturation,double *brightness) 9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 999caf4580de0f80e561a5fcb59c89f2f8adac91006cristy double 1000caf4580de0f80e561a5fcb59c89f2f8adac91006cristy b, 10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy delta, 1002caf4580de0f80e561a5fcb59c89f2f8adac91006cristy g, 10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy max, 1004caf4580de0f80e561a5fcb59c89f2f8adac91006cristy min, 1005caf4580de0f80e561a5fcb59c89f2f8adac91006cristy r; 10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Convert RGB to HSB colorspace. 10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(hue != (double *) NULL); 10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(saturation != (double *) NULL); 10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(brightness != (double *) NULL); 10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *hue=0.0; 10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *saturation=0.0; 10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *brightness=0.0; 10160a39a5c567fca70403bc431d18890e89fc253eefcristy r=red; 10170a39a5c567fca70403bc431d18890e89fc253eefcristy g=green; 10180a39a5c567fca70403bc431d18890e89fc253eefcristy b=blue; 1019caf4580de0f80e561a5fcb59c89f2f8adac91006cristy min=r < g ? r : g; 1020caf4580de0f80e561a5fcb59c89f2f8adac91006cristy if (b < min) 1021caf4580de0f80e561a5fcb59c89f2f8adac91006cristy min=b; 1022caf4580de0f80e561a5fcb59c89f2f8adac91006cristy max=r > g ? r : g; 1023caf4580de0f80e561a5fcb59c89f2f8adac91006cristy if (b > max) 1024caf4580de0f80e561a5fcb59c89f2f8adac91006cristy max=b; 10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (max == 0.0) 10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return; 10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy delta=max-min; 1028caf4580de0f80e561a5fcb59c89f2f8adac91006cristy *saturation=delta/max; 1029caf4580de0f80e561a5fcb59c89f2f8adac91006cristy *brightness=QuantumScale*max; 10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (delta == 0.0) 10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return; 1032caf4580de0f80e561a5fcb59c89f2f8adac91006cristy if (r == max) 1033caf4580de0f80e561a5fcb59c89f2f8adac91006cristy *hue=(g-b)/delta; 10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 1035caf4580de0f80e561a5fcb59c89f2f8adac91006cristy if (g == max) 1036caf4580de0f80e561a5fcb59c89f2f8adac91006cristy *hue=2.0+(b-r)/delta; 10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 1038caf4580de0f80e561a5fcb59c89f2f8adac91006cristy *hue=4.0+(r-g)/delta; 103918b17443128598500357da7bff2f01683cf32890cristy *hue/=6.0; 10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (*hue < 0.0) 10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *hue+=1.0; 10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1049af64eb219382bdf6243c4b8dc589268b8934304acristy% C o n v e r t R G B T o H S I % 1050af64eb219382bdf6243c4b8dc589268b8934304acristy% % 1051af64eb219382bdf6243c4b8dc589268b8934304acristy% % 1052af64eb219382bdf6243c4b8dc589268b8934304acristy% % 1053af64eb219382bdf6243c4b8dc589268b8934304acristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1054af64eb219382bdf6243c4b8dc589268b8934304acristy% 1055af64eb219382bdf6243c4b8dc589268b8934304acristy% ConvertRGBToHSI() transforms a (red, green, blue) to a (hue, saturation, 1056af64eb219382bdf6243c4b8dc589268b8934304acristy% intensity) triple. 1057af64eb219382bdf6243c4b8dc589268b8934304acristy% 1058af64eb219382bdf6243c4b8dc589268b8934304acristy% The format of the ConvertRGBToHSI method is: 1059af64eb219382bdf6243c4b8dc589268b8934304acristy% 1060af64eb219382bdf6243c4b8dc589268b8934304acristy% void ConvertRGBToHSI(const double red,const double green, 1061af64eb219382bdf6243c4b8dc589268b8934304acristy% const double blue,double *hue,double *saturation,double *intensity) 1062af64eb219382bdf6243c4b8dc589268b8934304acristy% 1063af64eb219382bdf6243c4b8dc589268b8934304acristy% A description of each parameter follows: 1064af64eb219382bdf6243c4b8dc589268b8934304acristy% 1065af64eb219382bdf6243c4b8dc589268b8934304acristy% o red, green, blue: A Quantum value representing the red, green, and 1066af64eb219382bdf6243c4b8dc589268b8934304acristy% blue component of a pixel.. 1067af64eb219382bdf6243c4b8dc589268b8934304acristy% 1068af64eb219382bdf6243c4b8dc589268b8934304acristy% o hue, saturation, intensity: A pointer to a double value representing a 1069af64eb219382bdf6243c4b8dc589268b8934304acristy% component of the HSI color space. 1070af64eb219382bdf6243c4b8dc589268b8934304acristy% 1071af64eb219382bdf6243c4b8dc589268b8934304acristy*/ 1072af64eb219382bdf6243c4b8dc589268b8934304acristyMagickPrivate void ConvertRGBToHSI(const double red,const double green, 1073af64eb219382bdf6243c4b8dc589268b8934304acristy const double blue,double *hue,double *saturation,double *intensity) 1074af64eb219382bdf6243c4b8dc589268b8934304acristy{ 1075af64eb219382bdf6243c4b8dc589268b8934304acristy double 1076af64eb219382bdf6243c4b8dc589268b8934304acristy alpha, 1077af64eb219382bdf6243c4b8dc589268b8934304acristy beta; 1078af64eb219382bdf6243c4b8dc589268b8934304acristy 1079af64eb219382bdf6243c4b8dc589268b8934304acristy /* 1080af64eb219382bdf6243c4b8dc589268b8934304acristy Convert RGB to HSI colorspace. 1081af64eb219382bdf6243c4b8dc589268b8934304acristy */ 1082af64eb219382bdf6243c4b8dc589268b8934304acristy assert(hue != (double *) NULL); 1083af64eb219382bdf6243c4b8dc589268b8934304acristy assert(saturation != (double *) NULL); 1084af64eb219382bdf6243c4b8dc589268b8934304acristy assert(intensity != (double *) NULL); 1085af64eb219382bdf6243c4b8dc589268b8934304acristy *intensity=(QuantumScale*red+QuantumScale*green+QuantumScale*blue)/3.0; 1086af64eb219382bdf6243c4b8dc589268b8934304acristy if (*intensity <= 0.0) 1087af64eb219382bdf6243c4b8dc589268b8934304acristy { 1088af64eb219382bdf6243c4b8dc589268b8934304acristy *hue=0.0; 1089af64eb219382bdf6243c4b8dc589268b8934304acristy *saturation=0.0; 1090a5a45a77350d84dcb9b38c02dca4c585c983888ccristy return; 1091af64eb219382bdf6243c4b8dc589268b8934304acristy } 1092a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *saturation=1.0-MagickMin(QuantumScale*red,MagickMin(QuantumScale*green, 1093a5a45a77350d84dcb9b38c02dca4c585c983888ccristy QuantumScale*blue))/(*intensity); 1094a5a45a77350d84dcb9b38c02dca4c585c983888ccristy alpha=0.5*(2.0*QuantumScale*red-QuantumScale*green-QuantumScale*blue); 1095be708af579eaa7bfae7d7ae760f3a8d177d3f79fcristy beta=0.8660254037844385*(QuantumScale*green-QuantumScale*blue); 1096a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *hue=atan2(beta,alpha)*(180.0/MagickPI)/360.0; 1097a5a45a77350d84dcb9b38c02dca4c585c983888ccristy if (*hue < 0.0) 1098a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *hue+=1.0; 1099af64eb219382bdf6243c4b8dc589268b8934304acristy} 1100af64eb219382bdf6243c4b8dc589268b8934304acristy 1101af64eb219382bdf6243c4b8dc589268b8934304acristy/* 1102af64eb219382bdf6243c4b8dc589268b8934304acristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1103af64eb219382bdf6243c4b8dc589268b8934304acristy% % 1104af64eb219382bdf6243c4b8dc589268b8934304acristy% % 1105af64eb219382bdf6243c4b8dc589268b8934304acristy% % 11060a39a5c567fca70403bc431d18890e89fc253eefcristy% C o n v e r t R G B T o H S L % 11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 11120a39a5c567fca70403bc431d18890e89fc253eefcristy% ConvertRGBToHSL() transforms a (red, green, blue) to a (hue, saturation, 11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% lightness) triple. 11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 11150a39a5c567fca70403bc431d18890e89fc253eefcristy% The format of the ConvertRGBToHSL method is: 11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 11170a39a5c567fca70403bc431d18890e89fc253eefcristy% void ConvertRGBToHSL(const double red,const double green, 11183094b7f3243820cc5559d370412a9d406d074348cristy% const double blue,double *hue,double *saturation,double *lightness) 11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o red, green, blue: A Quantum value representing the red, green, and 11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% blue component of a pixel.. 11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o hue, saturation, lightness: A pointer to a double value representing a 11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% component of the HSL color space. 11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 11290a39a5c567fca70403bc431d18890e89fc253eefcristyMagickExport void ConvertRGBToHSL(const double red,const double green, 11303094b7f3243820cc5559d370412a9d406d074348cristy const double blue,double *hue,double *saturation,double *lightness) 11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 1132caf4580de0f80e561a5fcb59c89f2f8adac91006cristy double 1133a5a45a77350d84dcb9b38c02dca4c585c983888ccristy c, 11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy max, 1135a5a45a77350d84dcb9b38c02dca4c585c983888ccristy min; 11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Convert RGB to HSL colorspace. 11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(hue != (double *) NULL); 11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(saturation != (double *) NULL); 11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(lightness != (double *) NULL); 1143a5a45a77350d84dcb9b38c02dca4c585c983888ccristy max=MagickMax(QuantumScale*red,MagickMax(QuantumScale*green, 1144a5a45a77350d84dcb9b38c02dca4c585c983888ccristy QuantumScale*blue)); 1145a5a45a77350d84dcb9b38c02dca4c585c983888ccristy min=MagickMin(QuantumScale*red,MagickMin(QuantumScale*green, 1146a5a45a77350d84dcb9b38c02dca4c585c983888ccristy QuantumScale*blue)); 1147a5a45a77350d84dcb9b38c02dca4c585c983888ccristy c=max-min; 1148a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *lightness=(max+min)/2.0; 1149a5a45a77350d84dcb9b38c02dca4c585c983888ccristy if (c <= 0.0) 11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *hue=0.0; 11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *saturation=0.0; 11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return; 11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1155a5a45a77350d84dcb9b38c02dca4c585c983888ccristy if (max == (QuantumScale*red)) 1156a5a45a77350d84dcb9b38c02dca4c585c983888ccristy { 1157a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *hue=(QuantumScale*green-QuantumScale*blue)/c; 1158a5a45a77350d84dcb9b38c02dca4c585c983888ccristy if ((QuantumScale*green) < (QuantumScale*blue)) 1159a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *hue+=6.0; 1160a5a45a77350d84dcb9b38c02dca4c585c983888ccristy } 11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 1162a5a45a77350d84dcb9b38c02dca4c585c983888ccristy if (max == (QuantumScale*green)) 1163a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *hue=2.0+(QuantumScale*blue-QuantumScale*red)/c; 11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 1165a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *hue=4.0+(QuantumScale*red-QuantumScale*green)/c; 1166a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *hue*=60.0/360.0; 1167a5a45a77350d84dcb9b38c02dca4c585c983888ccristy if (*lightness <= 0.5) 1168a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *saturation=c/(2.0*(*lightness)); 1169a5a45a77350d84dcb9b38c02dca4c585c983888ccristy else 1170a5a45a77350d84dcb9b38c02dca4c585c983888ccristy *saturation=c/(2.0-2.0*(*lightness)); 11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1177246c3135a833b00ed2e42448c85cc2ea1269b177cristy% % 1178246c3135a833b00ed2e42448c85cc2ea1269b177cristy% C o n v e r t R G B T o H S V % 1179246c3135a833b00ed2e42448c85cc2ea1269b177cristy% % 1180246c3135a833b00ed2e42448c85cc2ea1269b177cristy% % 1181246c3135a833b00ed2e42448c85cc2ea1269b177cristy% % 1182246c3135a833b00ed2e42448c85cc2ea1269b177cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1183246c3135a833b00ed2e42448c85cc2ea1269b177cristy% 1184246c3135a833b00ed2e42448c85cc2ea1269b177cristy% ConvertRGBToHSV() transforms a (red, green, blue) to a (hue, saturation, 1185246c3135a833b00ed2e42448c85cc2ea1269b177cristy% value) triple. 1186246c3135a833b00ed2e42448c85cc2ea1269b177cristy% 1187246c3135a833b00ed2e42448c85cc2ea1269b177cristy% The format of the ConvertRGBToHSV method is: 1188246c3135a833b00ed2e42448c85cc2ea1269b177cristy% 1189246c3135a833b00ed2e42448c85cc2ea1269b177cristy% void ConvertRGBToHSV(const double red,const double green, 1190246c3135a833b00ed2e42448c85cc2ea1269b177cristy% const double blue,double *hue,double *saturation,double *value) 1191246c3135a833b00ed2e42448c85cc2ea1269b177cristy% 1192246c3135a833b00ed2e42448c85cc2ea1269b177cristy% A description of each parameter follows: 1193246c3135a833b00ed2e42448c85cc2ea1269b177cristy% 1194246c3135a833b00ed2e42448c85cc2ea1269b177cristy% o red, green, blue: A Quantum value representing the red, green, and 1195246c3135a833b00ed2e42448c85cc2ea1269b177cristy% blue component of a pixel.. 1196246c3135a833b00ed2e42448c85cc2ea1269b177cristy% 1197246c3135a833b00ed2e42448c85cc2ea1269b177cristy% o hue, saturation, value: A pointer to a double value representing a 1198246c3135a833b00ed2e42448c85cc2ea1269b177cristy% component of the HSV color space. 1199246c3135a833b00ed2e42448c85cc2ea1269b177cristy% 1200246c3135a833b00ed2e42448c85cc2ea1269b177cristy*/ 1201246c3135a833b00ed2e42448c85cc2ea1269b177cristyMagickPrivate void ConvertRGBToHSV(const double red,const double green, 1202246c3135a833b00ed2e42448c85cc2ea1269b177cristy const double blue,double *hue,double *saturation,double *value) 1203246c3135a833b00ed2e42448c85cc2ea1269b177cristy{ 1204246c3135a833b00ed2e42448c85cc2ea1269b177cristy double 1205246c3135a833b00ed2e42448c85cc2ea1269b177cristy c, 1206246c3135a833b00ed2e42448c85cc2ea1269b177cristy max, 1207246c3135a833b00ed2e42448c85cc2ea1269b177cristy min; 1208246c3135a833b00ed2e42448c85cc2ea1269b177cristy 1209246c3135a833b00ed2e42448c85cc2ea1269b177cristy /* 1210246c3135a833b00ed2e42448c85cc2ea1269b177cristy Convert RGB to HSV colorspace. 1211246c3135a833b00ed2e42448c85cc2ea1269b177cristy */ 1212246c3135a833b00ed2e42448c85cc2ea1269b177cristy assert(hue != (double *) NULL); 1213246c3135a833b00ed2e42448c85cc2ea1269b177cristy assert(saturation != (double *) NULL); 1214246c3135a833b00ed2e42448c85cc2ea1269b177cristy assert(value != (double *) NULL); 1215246c3135a833b00ed2e42448c85cc2ea1269b177cristy max=MagickMax(QuantumScale*red,MagickMax(QuantumScale*green, 1216246c3135a833b00ed2e42448c85cc2ea1269b177cristy QuantumScale*blue)); 1217246c3135a833b00ed2e42448c85cc2ea1269b177cristy min=MagickMin(QuantumScale*red,MagickMin(QuantumScale*green, 1218246c3135a833b00ed2e42448c85cc2ea1269b177cristy QuantumScale*blue)); 1219246c3135a833b00ed2e42448c85cc2ea1269b177cristy c=max-min; 1220246c3135a833b00ed2e42448c85cc2ea1269b177cristy *value=max; 1221246c3135a833b00ed2e42448c85cc2ea1269b177cristy if (c <= 0.0) 1222246c3135a833b00ed2e42448c85cc2ea1269b177cristy { 1223246c3135a833b00ed2e42448c85cc2ea1269b177cristy *hue=0.0; 1224246c3135a833b00ed2e42448c85cc2ea1269b177cristy *saturation=0.0; 1225246c3135a833b00ed2e42448c85cc2ea1269b177cristy return; 1226246c3135a833b00ed2e42448c85cc2ea1269b177cristy } 1227246c3135a833b00ed2e42448c85cc2ea1269b177cristy if (max == (QuantumScale*red)) 1228246c3135a833b00ed2e42448c85cc2ea1269b177cristy { 1229246c3135a833b00ed2e42448c85cc2ea1269b177cristy *hue=(QuantumScale*green-QuantumScale*blue)/c; 1230246c3135a833b00ed2e42448c85cc2ea1269b177cristy if ((QuantumScale*green) < (QuantumScale*blue)) 1231246c3135a833b00ed2e42448c85cc2ea1269b177cristy *hue+=6.0; 1232246c3135a833b00ed2e42448c85cc2ea1269b177cristy } 1233246c3135a833b00ed2e42448c85cc2ea1269b177cristy else 1234246c3135a833b00ed2e42448c85cc2ea1269b177cristy if (max == (QuantumScale*green)) 1235246c3135a833b00ed2e42448c85cc2ea1269b177cristy *hue=2.0+(QuantumScale*blue-QuantumScale*red)/c; 1236246c3135a833b00ed2e42448c85cc2ea1269b177cristy else 1237246c3135a833b00ed2e42448c85cc2ea1269b177cristy *hue=4.0+(QuantumScale*red-QuantumScale*green)/c; 1238246c3135a833b00ed2e42448c85cc2ea1269b177cristy *hue*=60.0/360.0; 1239246c3135a833b00ed2e42448c85cc2ea1269b177cristy *saturation=c/max; 1240246c3135a833b00ed2e42448c85cc2ea1269b177cristy} 1241246c3135a833b00ed2e42448c85cc2ea1269b177cristy 1242246c3135a833b00ed2e42448c85cc2ea1269b177cristy/* 1243246c3135a833b00ed2e42448c85cc2ea1269b177cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1244246c3135a833b00ed2e42448c85cc2ea1269b177cristy% % 1245246c3135a833b00ed2e42448c85cc2ea1269b177cristy% % 12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12470a39a5c567fca70403bc431d18890e89fc253eefcristy% C o n v e r t R G B T o H W B % 12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12530a39a5c567fca70403bc431d18890e89fc253eefcristy% ConvertRGBToHWB() transforms a (red, green, blue) to a (hue, whiteness, 12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% blackness) triple. 12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12560a39a5c567fca70403bc431d18890e89fc253eefcristy% The format of the ConvertRGBToHWB method is: 12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12580a39a5c567fca70403bc431d18890e89fc253eefcristy% void ConvertRGBToHWB(const double red,const double green, 12593094b7f3243820cc5559d370412a9d406d074348cristy% const double blue,double *hue,double *whiteness,double *blackness) 12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o red, green, blue: A Quantum value representing the red, green, and 12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% blue component of a pixel. 12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o hue, whiteness, blackness: A pointer to a double value representing a 12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% component of the HWB color space. 12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 12700a39a5c567fca70403bc431d18890e89fc253eefcristyMagickPrivate void ConvertRGBToHWB(const double red,const double green, 12713094b7f3243820cc5559d370412a9d406d074348cristy const double blue,double *hue,double *whiteness,double *blackness) 12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 1273caf4580de0f80e561a5fcb59c89f2f8adac91006cristy double 1274caf4580de0f80e561a5fcb59c89f2f8adac91006cristy b, 12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy f, 1276caf4580de0f80e561a5fcb59c89f2f8adac91006cristy g, 1277caf4580de0f80e561a5fcb59c89f2f8adac91006cristy p, 1278caf4580de0f80e561a5fcb59c89f2f8adac91006cristy r, 12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy v, 12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy w; 12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Convert RGB to HWB colorspace. 12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(hue != (double *) NULL); 12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(whiteness != (double *) NULL); 12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(blackness != (double *) NULL); 12880a39a5c567fca70403bc431d18890e89fc253eefcristy r=red; 12890a39a5c567fca70403bc431d18890e89fc253eefcristy g=green; 12900a39a5c567fca70403bc431d18890e89fc253eefcristy b=blue; 1291caf4580de0f80e561a5fcb59c89f2f8adac91006cristy w=MagickMin(r,MagickMin(g,b)); 1292caf4580de0f80e561a5fcb59c89f2f8adac91006cristy v=MagickMax(r,MagickMax(g,b)); 12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *blackness=1.0-QuantumScale*v; 12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *whiteness=QuantumScale*w; 12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (v == w) 12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1297af10b112a3fe7f0ca502f9cf0f8de2873ff7b97ecristy *hue=(-1.0); 12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return; 12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1300caf4580de0f80e561a5fcb59c89f2f8adac91006cristy f=(r == w) ? g-b : ((g == w) ? b-r : r-g); 1301caf4580de0f80e561a5fcb59c89f2f8adac91006cristy p=(r == w) ? 3.0 : ((g == w) ? 5.0 : 1.0); 1302caf4580de0f80e561a5fcb59c89f2f8adac91006cristy *hue=(p-f/(v-1.0*w))/6.0; 13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1310a83d4c0356b4f70fca3b6fb6c2ff9b52fa0e2ec5cristy% C o n v e r t R G B T o L C H a b % 1311b285095a81498ca0f0b24a0591e02aa599065b12cristy% % 1312b285095a81498ca0f0b24a0591e02aa599065b12cristy% % 1313b285095a81498ca0f0b24a0591e02aa599065b12cristy% % 1314b285095a81498ca0f0b24a0591e02aa599065b12cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1315b285095a81498ca0f0b24a0591e02aa599065b12cristy% 1316df42b17380e9d59e0ef874a62e553c9390157b7dcristy% ConvertRGBToLCHab() transforms a (red, green, blue) to a (luma, chroma, 1317b285095a81498ca0f0b24a0591e02aa599065b12cristy% hue) triple. 1318b285095a81498ca0f0b24a0591e02aa599065b12cristy% 1319df42b17380e9d59e0ef874a62e553c9390157b7dcristy% The format of the ConvertRGBToLCHab method is: 1320b285095a81498ca0f0b24a0591e02aa599065b12cristy% 1321df42b17380e9d59e0ef874a62e553c9390157b7dcristy% void ConvertRGBToLCHab(const double red,const double green, 1322b285095a81498ca0f0b24a0591e02aa599065b12cristy% const double blue,double *luma,double *chroma,double *hue) 1323b285095a81498ca0f0b24a0591e02aa599065b12cristy% 1324b285095a81498ca0f0b24a0591e02aa599065b12cristy% A description of each parameter follows: 1325b285095a81498ca0f0b24a0591e02aa599065b12cristy% 1326b285095a81498ca0f0b24a0591e02aa599065b12cristy% o red, green, blue: A Quantum value representing the red, green, and 1327b285095a81498ca0f0b24a0591e02aa599065b12cristy% blue component of a pixel. 1328b285095a81498ca0f0b24a0591e02aa599065b12cristy% 1329b285095a81498ca0f0b24a0591e02aa599065b12cristy% o luma, chroma, hue: A pointer to a double value representing a 1330b285095a81498ca0f0b24a0591e02aa599065b12cristy% component of the LCH color space. 1331b285095a81498ca0f0b24a0591e02aa599065b12cristy% 1332b285095a81498ca0f0b24a0591e02aa599065b12cristy*/ 1333c32cb02801af90aacf5ced4c59e246867078c912cristy 1334c32cb02801af90aacf5ced4c59e246867078c912cristystatic inline void ConvertXYZToLCHab(const double X,const double Y, 1335c32cb02801af90aacf5ced4c59e246867078c912cristy const double Z,double *luma,double *chroma,double *hue) 1336c32cb02801af90aacf5ced4c59e246867078c912cristy{ 1337c32cb02801af90aacf5ced4c59e246867078c912cristy double 1338c32cb02801af90aacf5ced4c59e246867078c912cristy a, 1339c32cb02801af90aacf5ced4c59e246867078c912cristy b; 1340c32cb02801af90aacf5ced4c59e246867078c912cristy 1341c32cb02801af90aacf5ced4c59e246867078c912cristy ConvertXYZToLab(X,Y,Z,luma,&a,&b); 13429db2dba5a8e6618bbec0971f1b3b12423f46401dcristy *chroma=hypot(255.0*(a-0.5),255.0*(b-0.5)); 13439db2dba5a8e6618bbec0971f1b3b12423f46401dcristy *hue=180.0*atan2(255.0*(b-0.5),255.0*(a-0.5))/MagickPI; 13449db2dba5a8e6618bbec0971f1b3b12423f46401dcristy *chroma=(*chroma)/255.0+0.5; 13459db2dba5a8e6618bbec0971f1b3b12423f46401dcristy *hue=(*hue)/255.0+0.5; 134689106f86b28a27c7b7d9b07e13db58516ab8d01fcristy if (*hue < 0.0) 134789106f86b28a27c7b7d9b07e13db58516ab8d01fcristy *hue+=1.0; 1348c32cb02801af90aacf5ced4c59e246867078c912cristy} 1349c32cb02801af90aacf5ced4c59e246867078c912cristy 1350df42b17380e9d59e0ef874a62e553c9390157b7dcristyMagickPrivate void ConvertRGBToLCHab(const double red,const double green, 1351b285095a81498ca0f0b24a0591e02aa599065b12cristy const double blue,double *luma,double *chroma,double *hue) 1352b285095a81498ca0f0b24a0591e02aa599065b12cristy{ 1353b285095a81498ca0f0b24a0591e02aa599065b12cristy double 1354b285095a81498ca0f0b24a0591e02aa599065b12cristy X, 1355b285095a81498ca0f0b24a0591e02aa599065b12cristy Y, 1356b285095a81498ca0f0b24a0591e02aa599065b12cristy Z; 1357b285095a81498ca0f0b24a0591e02aa599065b12cristy 1358b285095a81498ca0f0b24a0591e02aa599065b12cristy /* 13599427c42b6fe25470c57cbb224651080a7813e7cccristy Convert RGB to LCHab colorspace. 1360b285095a81498ca0f0b24a0591e02aa599065b12cristy */ 1361b285095a81498ca0f0b24a0591e02aa599065b12cristy assert(luma != (double *) NULL); 1362b285095a81498ca0f0b24a0591e02aa599065b12cristy assert(chroma != (double *) NULL); 1363b285095a81498ca0f0b24a0591e02aa599065b12cristy assert(hue != (double *) NULL); 1364b285095a81498ca0f0b24a0591e02aa599065b12cristy ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z); 1365c32cb02801af90aacf5ced4c59e246867078c912cristy ConvertXYZToLCHab(X,Y,Z,luma,chroma,hue); 1366b285095a81498ca0f0b24a0591e02aa599065b12cristy} 1367b285095a81498ca0f0b24a0591e02aa599065b12cristy 1368b285095a81498ca0f0b24a0591e02aa599065b12cristy/* 1369b285095a81498ca0f0b24a0591e02aa599065b12cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1370b285095a81498ca0f0b24a0591e02aa599065b12cristy% % 1371b285095a81498ca0f0b24a0591e02aa599065b12cristy% % 1372b285095a81498ca0f0b24a0591e02aa599065b12cristy% % 1373a83d4c0356b4f70fca3b6fb6c2ff9b52fa0e2ec5cristy% C o n v e r t R G B T o L C H u v % 1374df42b17380e9d59e0ef874a62e553c9390157b7dcristy% % 1375df42b17380e9d59e0ef874a62e553c9390157b7dcristy% % 1376df42b17380e9d59e0ef874a62e553c9390157b7dcristy% % 1377df42b17380e9d59e0ef874a62e553c9390157b7dcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1378df42b17380e9d59e0ef874a62e553c9390157b7dcristy% 1379df42b17380e9d59e0ef874a62e553c9390157b7dcristy% ConvertRGBToLCHuv() transforms a (red, green, blue) to a (luma, chroma, 1380df42b17380e9d59e0ef874a62e553c9390157b7dcristy% hue) triple. 1381df42b17380e9d59e0ef874a62e553c9390157b7dcristy% 1382df42b17380e9d59e0ef874a62e553c9390157b7dcristy% The format of the ConvertRGBToLCHuv method is: 1383df42b17380e9d59e0ef874a62e553c9390157b7dcristy% 1384df42b17380e9d59e0ef874a62e553c9390157b7dcristy% void ConvertRGBToLCHuv(const double red,const double green, 1385df42b17380e9d59e0ef874a62e553c9390157b7dcristy% const double blue,double *luma,double *chroma,double *hue) 1386df42b17380e9d59e0ef874a62e553c9390157b7dcristy% 1387df42b17380e9d59e0ef874a62e553c9390157b7dcristy% A description of each parameter follows: 1388df42b17380e9d59e0ef874a62e553c9390157b7dcristy% 1389df42b17380e9d59e0ef874a62e553c9390157b7dcristy% o red, green, blue: A Quantum value representing the red, green, and 1390df42b17380e9d59e0ef874a62e553c9390157b7dcristy% blue component of a pixel. 1391df42b17380e9d59e0ef874a62e553c9390157b7dcristy% 1392df42b17380e9d59e0ef874a62e553c9390157b7dcristy% o luma, chroma, hue: A pointer to a double value representing a 1393df42b17380e9d59e0ef874a62e553c9390157b7dcristy% component of the LCHuv color space. 1394df42b17380e9d59e0ef874a62e553c9390157b7dcristy% 1395df42b17380e9d59e0ef874a62e553c9390157b7dcristy*/ 1396c32cb02801af90aacf5ced4c59e246867078c912cristy 1397c32cb02801af90aacf5ced4c59e246867078c912cristystatic inline void ConvertXYZToLCHuv(const double X,const double Y, 1398c32cb02801af90aacf5ced4c59e246867078c912cristy const double Z,double *luma,double *chroma,double *hue) 1399c32cb02801af90aacf5ced4c59e246867078c912cristy{ 1400c32cb02801af90aacf5ced4c59e246867078c912cristy double 14019db2dba5a8e6618bbec0971f1b3b12423f46401dcristy u, 14029db2dba5a8e6618bbec0971f1b3b12423f46401dcristy v; 1403c32cb02801af90aacf5ced4c59e246867078c912cristy 14049db2dba5a8e6618bbec0971f1b3b12423f46401dcristy ConvertXYZToLuv(X,Y,Z,luma,&u,&v); 14059db2dba5a8e6618bbec0971f1b3b12423f46401dcristy *chroma=hypot(354.0*u-134.0,262.0*v-140.0); 14069db2dba5a8e6618bbec0971f1b3b12423f46401dcristy *hue=180.0*atan2(262.0*v-140.0,354.0*u-134.0)/MagickPI; 1407c32cb02801af90aacf5ced4c59e246867078c912cristy if (*hue < 0.0) 1408c32cb02801af90aacf5ced4c59e246867078c912cristy *hue+=360.0; 14099db2dba5a8e6618bbec0971f1b3b12423f46401dcristy *chroma=(*chroma+134.0)/354.0; 14109db2dba5a8e6618bbec0971f1b3b12423f46401dcristy *hue=(*hue+140.0)/262.0; 1411c32cb02801af90aacf5ced4c59e246867078c912cristy} 1412c32cb02801af90aacf5ced4c59e246867078c912cristy 1413df42b17380e9d59e0ef874a62e553c9390157b7dcristyMagickPrivate void ConvertRGBToLCHuv(const double red,const double green, 1414df42b17380e9d59e0ef874a62e553c9390157b7dcristy const double blue,double *luma,double *chroma,double *hue) 1415df42b17380e9d59e0ef874a62e553c9390157b7dcristy{ 1416df42b17380e9d59e0ef874a62e553c9390157b7dcristy double 1417df42b17380e9d59e0ef874a62e553c9390157b7dcristy X, 1418df42b17380e9d59e0ef874a62e553c9390157b7dcristy Y, 1419df42b17380e9d59e0ef874a62e553c9390157b7dcristy Z; 1420df42b17380e9d59e0ef874a62e553c9390157b7dcristy 1421df42b17380e9d59e0ef874a62e553c9390157b7dcristy /* 14229427c42b6fe25470c57cbb224651080a7813e7cccristy Convert RGB to LCHuv colorspace. 1423df42b17380e9d59e0ef874a62e553c9390157b7dcristy */ 1424df42b17380e9d59e0ef874a62e553c9390157b7dcristy assert(luma != (double *) NULL); 1425df42b17380e9d59e0ef874a62e553c9390157b7dcristy assert(chroma != (double *) NULL); 1426df42b17380e9d59e0ef874a62e553c9390157b7dcristy assert(hue != (double *) NULL); 1427df42b17380e9d59e0ef874a62e553c9390157b7dcristy ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z); 1428c32cb02801af90aacf5ced4c59e246867078c912cristy ConvertXYZToLCHuv(X,Y,Z,luma,chroma,hue); 1429df42b17380e9d59e0ef874a62e553c9390157b7dcristy} 1430df42b17380e9d59e0ef874a62e553c9390157b7dcristy 1431df42b17380e9d59e0ef874a62e553c9390157b7dcristy/* 1432df42b17380e9d59e0ef874a62e553c9390157b7dcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1433df42b17380e9d59e0ef874a62e553c9390157b7dcristy% % 1434df42b17380e9d59e0ef874a62e553c9390157b7dcristy% % 1435df42b17380e9d59e0ef874a62e553c9390157b7dcristy% % 14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% E x p a n d A f f i n e % 14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% ExpandAffine() computes the affine's expansion factor, i.e. the square root 14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% of the factor by which the affine transform affects area. In an affine 14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% transform composed of scaling, rotation, shearing, and translation, returns 14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% the amount of scaling. 14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the ExpandAffine method is: 14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% double ExpandAffine(const AffineMatrix *affine) 14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14532d7ffbbeca07eeb37beb7e8a246a4160aa9f2825cristy% o expansion: ExpandAffine returns the affine's expansion factor. 14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o affine: A pointer the affine transform of type AffineMatrix. 14563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport double ExpandAffine(const AffineMatrix *affine) 14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(affine != (const AffineMatrix *) NULL); 14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(sqrt(fabs(affine->sx*affine->sy-affine->rx*affine->ry))); 14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 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 % 14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 147582b1583d4ca9179180de2754e6c25eef115cc181cristy% GenerateDifferentialNoise() generates differentual noise. 14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the GenerateDifferentialNoise method is: 14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% double GenerateDifferentialNoise(RandomInfo *random_info, 14809ed1f810381187775960350780d4d619c111dc4bcristy% const Quantum pixel,const NoiseType noise_type,const double attenuate) 14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o random_info: the random info. 14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o pixel: noise is relative to this pixel value. 14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o noise_type: the type of noise. 14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o attenuate: attenuate the noise. 14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 14938ea81224e9ff022e56eb2cddb12860a8b2e90411cristyMagickPrivate double GenerateDifferentialNoise(RandomInfo *random_info, 14949ed1f810381187775960350780d4d619c111dc4bcristy const Quantum pixel,const NoiseType noise_type,const double attenuate) 14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 14967118edf0993ccec017e96e2172e6ac672d3e24cdcristy#define SigmaUniform (attenuate*0.015625) 14977118edf0993ccec017e96e2172e6ac672d3e24cdcristy#define SigmaGaussian (attenuate*0.015625) 14987118edf0993ccec017e96e2172e6ac672d3e24cdcristy#define SigmaImpulse (attenuate*0.1) 14997118edf0993ccec017e96e2172e6ac672d3e24cdcristy#define SigmaLaplacian (attenuate*0.0390625) 15007118edf0993ccec017e96e2172e6ac672d3e24cdcristy#define SigmaMultiplicativeGaussian (attenuate*0.5) 15014ce9df6057fcca6de6a4bbf18958c85ad22b106dcristy#define SigmaPoisson (attenuate*12.5) 1502785eb590c771f467d6635fce646e366a6a3a2754cristy#define SigmaRandom (attenuate) 15037118edf0993ccec017e96e2172e6ac672d3e24cdcristy#define TauGaussian (attenuate*0.078125) 15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1505adb41caab5f958d39a3466968df0be65ef2b1045cristy double 15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy alpha, 15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy beta, 15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy noise, 15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy sigma; 15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy alpha=GetPseudoRandomValue(random_info); 15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy switch (noise_type) 15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case UniformNoise: 15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy default: 15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 15176bbabe6bce89c2e8051ea16a47efd0cb42c708e2cristy noise=(double) (pixel+QuantumRange*SigmaUniform*(alpha-0.5)); 15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case GaussianNoise: 15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1522adb41caab5f958d39a3466968df0be65ef2b1045cristy double 152362faa60a11bc656bbeb1b418a95de40815a4490ccristy gamma, 15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy tau; 15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1526adb41caab5f958d39a3466968df0be65ef2b1045cristy if (alpha == 0.0) 1527adb41caab5f958d39a3466968df0be65ef2b1045cristy alpha=1.0; 15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy beta=GetPseudoRandomValue(random_info); 152962faa60a11bc656bbeb1b418a95de40815a4490ccristy gamma=sqrt(-2.0*log(alpha)); 153055a91cddcdea3aa002893186a773e1704884a9dfcristy sigma=gamma*cos((double) (2.0*MagickPI*beta)); 153155a91cddcdea3aa002893186a773e1704884a9dfcristy tau=gamma*sin((double) (2.0*MagickPI*beta)); 15326bbabe6bce89c2e8051ea16a47efd0cb42c708e2cristy noise=(double) (pixel+sqrt((double) pixel)*SigmaGaussian*sigma+ 15336bbabe6bce89c2e8051ea16a47efd0cb42c708e2cristy QuantumRange*TauGaussian*tau); 15343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case ImpulseNoise: 15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (alpha < (SigmaImpulse/2.0)) 15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy noise=0.0; 154037c2407b40ceacf637731f133d9dbff27a39f669cristy else 154137c2407b40ceacf637731f133d9dbff27a39f669cristy if (alpha >= (1.0-(SigmaImpulse/2.0))) 154237c2407b40ceacf637731f133d9dbff27a39f669cristy noise=(double) QuantumRange; 154337c2407b40ceacf637731f133d9dbff27a39f669cristy else 154437c2407b40ceacf637731f133d9dbff27a39f669cristy noise=(double) pixel; 15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case LaplacianNoise: 15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (alpha <= 0.5) 15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 15517118edf0993ccec017e96e2172e6ac672d3e24cdcristy if (alpha <= MagickEpsilon) 15526bbabe6bce89c2e8051ea16a47efd0cb42c708e2cristy noise=(double) (pixel-QuantumRange); 15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 1554785eb590c771f467d6635fce646e366a6a3a2754cristy noise=(double) (pixel+QuantumRange*SigmaLaplacian*log(2.0*alpha)+ 1555785eb590c771f467d6635fce646e366a6a3a2754cristy 0.5); 15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy beta=1.0-alpha; 15597118edf0993ccec017e96e2172e6ac672d3e24cdcristy if (beta <= (0.5*MagickEpsilon)) 1560adb41caab5f958d39a3466968df0be65ef2b1045cristy noise=(double) (pixel+QuantumRange); 15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 15626bbabe6bce89c2e8051ea16a47efd0cb42c708e2cristy noise=(double) (pixel-QuantumRange*SigmaLaplacian*log(2.0*beta)+0.5); 15637118edf0993ccec017e96e2172e6ac672d3e24cdcristy break; 15647118edf0993ccec017e96e2172e6ac672d3e24cdcristy } 15657118edf0993ccec017e96e2172e6ac672d3e24cdcristy case MultiplicativeGaussianNoise: 15667118edf0993ccec017e96e2172e6ac672d3e24cdcristy { 15677118edf0993ccec017e96e2172e6ac672d3e24cdcristy sigma=1.0; 15687118edf0993ccec017e96e2172e6ac672d3e24cdcristy if (alpha > MagickEpsilon) 15697118edf0993ccec017e96e2172e6ac672d3e24cdcristy sigma=sqrt(-2.0*log(alpha)); 15707118edf0993ccec017e96e2172e6ac672d3e24cdcristy beta=GetPseudoRandomValue(random_info); 15716bbabe6bce89c2e8051ea16a47efd0cb42c708e2cristy noise=(double) (pixel+pixel*SigmaMultiplicativeGaussian*sigma* 15726bbabe6bce89c2e8051ea16a47efd0cb42c708e2cristy cos((double) (2.0*MagickPI*beta))/2.0); 15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case PoissonNoise: 15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1577adb41caab5f958d39a3466968df0be65ef2b1045cristy double 15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy poisson; 15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1580bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 15837118edf0993ccec017e96e2172e6ac672d3e24cdcristy poisson=exp(-SigmaPoisson*QuantumScale*pixel); 15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=0; alpha > poisson; i++) 15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy beta=GetPseudoRandomValue(random_info); 15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy alpha*=beta; 15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 15896bbabe6bce89c2e8051ea16a47efd0cb42c708e2cristy noise=(double) (QuantumRange*i/SigmaPoisson); 15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case RandomNoise: 15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1594785eb590c771f467d6635fce646e366a6a3a2754cristy noise=(double) (QuantumRange*SigmaRandom*alpha); 15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(noise); 15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% G e t O p t i m a l K e r n e l W i d t h % 16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 16103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% GetOptimalKernelWidth() computes the optimal kernel radius for a convolution 16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% filter. Start with the minimum value of 3 pixels and walk out until we drop 16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% below the threshold of one pixel numerical accuracy. 16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the GetOptimalKernelWidth method is: 16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1618bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy% size_t GetOptimalKernelWidth(const double radius, 16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% const double sigma) 16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 16232d7ffbbeca07eeb37beb7e8a246a4160aa9f2825cristy% o width: GetOptimalKernelWidth returns the optimal width of a 16242d7ffbbeca07eeb37beb7e8a246a4160aa9f2825cristy% convolution kernel. 16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o radius: the radius of the Gaussian, in pixels, not counting the center 16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% pixel. 16283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o sigma: the standard deviation of the Gaussian, in pixels. 16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 16328ea81224e9ff022e56eb2cddb12860a8b2e90411cristyMagickPrivate size_t GetOptimalKernelWidth1D(const double radius, 1633e96405a0f45f803fb9c26f75e7bdee252437febbcristy const double sigma) 16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 1635e96405a0f45f803fb9c26f75e7bdee252437febbcristy double 1636e96405a0f45f803fb9c26f75e7bdee252437febbcristy alpha, 1637e96405a0f45f803fb9c26f75e7bdee252437febbcristy beta, 1638e96405a0f45f803fb9c26f75e7bdee252437febbcristy gamma, 16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy normalize, 1640e96405a0f45f803fb9c26f75e7bdee252437febbcristy value; 16413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1642bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 164347e00508ba238041491b7e0daf628ae3f21ab91ecristy i; 164447e00508ba238041491b7e0daf628ae3f21ab91ecristy 1645bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 164647e00508ba238041491b7e0daf628ae3f21ab91ecristy width; 16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 16489d314ff2c17a77996c05413c2013880387e50f0ecristy ssize_t 16499d314ff2c17a77996c05413c2013880387e50f0ecristy j; 16509d314ff2c17a77996c05413c2013880387e50f0ecristy 16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 165247e00508ba238041491b7e0daf628ae3f21ab91ecristy if (radius > MagickEpsilon) 1653bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy return((size_t) (2.0*ceil(radius)+1.0)); 1654e96405a0f45f803fb9c26f75e7bdee252437febbcristy gamma=fabs(sigma); 1655e96405a0f45f803fb9c26f75e7bdee252437febbcristy if (gamma <= MagickEpsilon) 1656c106172cd6da00b6c8fd6a4c06efdd4aa32c7f06anthony return(3UL); 16573e3ec3afbb0782697f201cbe30a56794c10dc7efcristy alpha=PerceptibleReciprocal(2.0*gamma*gamma); 16583e3ec3afbb0782697f201cbe30a56794c10dc7efcristy beta=(double) PerceptibleReciprocal((double) MagickSQ2PI*gamma); 16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (width=5; ; ) 16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy normalize=0.0; 166235faaa73b04611ce5419c2bf48903d71ffea9869cristy j=(ssize_t) (width-1)/2; 166347e00508ba238041491b7e0daf628ae3f21ab91ecristy for (i=(-j); i <= j; i++) 1664e96405a0f45f803fb9c26f75e7bdee252437febbcristy normalize+=exp(-((double) (i*i))*alpha)*beta; 1665e96405a0f45f803fb9c26f75e7bdee252437febbcristy value=exp(-((double) (j*j))*alpha)*beta/normalize; 166620908dac8b2f15a9c0289728e57698bde5b74094cristy if ((value < QuantumScale) || (value < MagickEpsilon)) 16673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy width+=2; 16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1670bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy return((size_t) (width-2)); 16713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 16738ea81224e9ff022e56eb2cddb12860a8b2e90411cristyMagickPrivate size_t GetOptimalKernelWidth2D(const double radius, 1674e96405a0f45f803fb9c26f75e7bdee252437febbcristy const double sigma) 16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 167647e00508ba238041491b7e0daf628ae3f21ab91ecristy double 1677e96405a0f45f803fb9c26f75e7bdee252437febbcristy alpha, 1678e96405a0f45f803fb9c26f75e7bdee252437febbcristy beta, 1679e96405a0f45f803fb9c26f75e7bdee252437febbcristy gamma, 16803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy normalize, 1681e96405a0f45f803fb9c26f75e7bdee252437febbcristy value; 16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 16839d314ff2c17a77996c05413c2013880387e50f0ecristy size_t 16849d314ff2c17a77996c05413c2013880387e50f0ecristy width; 16859d314ff2c17a77996c05413c2013880387e50f0ecristy 1686bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy ssize_t 168747e00508ba238041491b7e0daf628ae3f21ab91ecristy j, 16883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy u, 16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy v; 16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 16913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 169247e00508ba238041491b7e0daf628ae3f21ab91ecristy if (radius > MagickEpsilon) 1693bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy return((size_t) (2.0*ceil(radius)+1.0)); 1694e96405a0f45f803fb9c26f75e7bdee252437febbcristy gamma=fabs(sigma); 1695e96405a0f45f803fb9c26f75e7bdee252437febbcristy if (gamma <= MagickEpsilon) 1696c106172cd6da00b6c8fd6a4c06efdd4aa32c7f06anthony return(3UL); 16973e3ec3afbb0782697f201cbe30a56794c10dc7efcristy alpha=PerceptibleReciprocal(2.0*gamma*gamma); 16983e3ec3afbb0782697f201cbe30a56794c10dc7efcristy beta=(double) PerceptibleReciprocal((double) Magick2PI*gamma*gamma); 16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (width=5; ; ) 17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy normalize=0.0; 170235faaa73b04611ce5419c2bf48903d71ffea9869cristy j=(ssize_t) (width-1)/2; 170347e00508ba238041491b7e0daf628ae3f21ab91ecristy for (v=(-j); v <= j; v++) 170447e00508ba238041491b7e0daf628ae3f21ab91ecristy for (u=(-j); u <= j; u++) 1705e96405a0f45f803fb9c26f75e7bdee252437febbcristy normalize+=exp(-((double) (u*u+v*v))*alpha)*beta; 1706e96405a0f45f803fb9c26f75e7bdee252437febbcristy value=exp(-((double) (j*j))*alpha)*beta/normalize; 170720908dac8b2f15a9c0289728e57698bde5b74094cristy if ((value < QuantumScale) || (value < MagickEpsilon)) 17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 17093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy width+=2; 17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1711bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy return((size_t) (width-2)); 17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 17148ea81224e9ff022e56eb2cddb12860a8b2e90411cristyMagickPrivate size_t GetOptimalKernelWidth(const double radius, 17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const double sigma) 17163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(GetOptimalKernelWidth1D(radius,sigma)); 17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 1719