2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Graphic Gems - Graphic Support Methods %
20 % Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 #include "MagickCore/studio.h"
44 #include "MagickCore/color-private.h"
45 #include "MagickCore/draw.h"
46 #include "MagickCore/gem.h"
47 #include "MagickCore/gem-private.h"
48 #include "MagickCore/image.h"
49 #include "MagickCore/image-private.h"
50 #include "MagickCore/log.h"
51 #include "MagickCore/memory_.h"
52 #include "MagickCore/pixel-accessor.h"
53 #include "MagickCore/pixel-private.h"
54 #include "MagickCore/quantum.h"
55 #include "MagickCore/quantum-private.h"
56 #include "MagickCore/random_.h"
57 #include "MagickCore/resize.h"
58 #include "MagickCore/transform.h"
59 #include "MagickCore/signature-private.h"
62 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66 % C o n v e r t H C L T o R G B %
70 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72 % ConvertHCLToRGB() transforms a (hue, chroma, luma) to a (red, green,
75 % The format of the ConvertHCLToRGBImage method is:
77 % void ConvertHCLToRGB(const double hue,const double chroma,
78 % const double luma,double *red,double *green,double *blue)
80 % A description of each parameter follows:
82 % o hue, chroma, luma: A double value representing a component of the
85 % o red, green, blue: A pointer to a pixel component of type Quantum.
88 MagickPrivate void ConvertHCLToRGB(const double hue,const double chroma,
89 const double luma,double *red,double *green,double *blue)
101 Convert HCL to RGB colorspace.
103 assert(red != (double *) NULL);
104 assert(green != (double *) NULL);
105 assert(blue != (double *) NULL);
108 x=c*(1.0-fabs(fmod(h,2.0)-1.0));
112 if ((0.0 <= h) && (h < 1.0))
118 if ((1.0 <= h) && (h < 2.0))
124 if ((2.0 <= h) && (h < 3.0))
130 if ((3.0 <= h) && (h < 4.0))
136 if ((4.0 <= h) && (h < 5.0))
142 if ((5.0 <= h) && (h < 6.0))
147 m=luma-(0.298839*r+0.586811*g+0.114350*b);
148 *red=QuantumRange*(r+m);
149 *green=QuantumRange*(g+m);
150 *blue=QuantumRange*(b+m);
154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
158 % C o n v e r t H C L p T o R G B %
162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164 % ConvertHCLpToRGB() transforms a (hue, chroma, luma) to a (red, green,
165 % blue) triple. Since HCL colorspace is wider than RGB, we instead choose a
166 % saturation strategy to project it on the RGB cube.
168 % The format of the ConvertHCLpToRGBImage method is:
170 % void ConvertHCLpToRGB(const double hue,const double chroma,
171 % const double luma,double *red,double *green,double *blue)
173 % A description of each parameter follows:
175 % o hue, chroma, luma: A double value representing a componenet of the
178 % o red, green, blue: A pointer to a pixel component of type Quantum.
181 MagickPrivate void ConvertHCLpToRGB(const double hue,const double chroma,
182 const double luma,double *red,double *green,double *blue)
195 Convert HCLp to RGB colorspace.
197 assert(red != (double *) NULL);
198 assert(green != (double *) NULL);
199 assert(blue != (double *) NULL);
202 x=c*(1.0-fabs(fmod(h,2.0)-1.0));
206 if ((0.0 <= h) && (h < 1.0))
212 if ((1.0 <= h) && (h < 2.0))
218 if ((2.0 <= h) && (h < 3.0))
224 if ((3.0 <= h) && (h < 4.0))
230 if ((4.0 <= h) && (h < 5.0))
236 if ((5.0 <= h) && (h < 6.0))
241 m=luma-(0.298839*r+0.586811*g+0.114350*b);
251 z=(1.0-luma)/(m+c-luma);
254 *red=QuantumRange*(z*r+m);
255 *green=QuantumRange*(z*g+m);
256 *blue=QuantumRange*(z*b+m);
260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
264 % C o n v e r t H S B T o R G B %
268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
270 % ConvertHSBToRGB() transforms a (hue, saturation, brightness) to a (red,
271 % green, blue) triple.
273 % The format of the ConvertHSBToRGBImage method is:
275 % void ConvertHSBToRGB(const double hue,const double saturation,
276 % const double brightness,double *red,double *green,double *blue)
278 % A description of each parameter follows:
280 % o hue, saturation, brightness: A double value representing a
281 % component of the HSB color space.
283 % o red, green, blue: A pointer to a pixel component of type Quantum.
286 MagickPrivate void ConvertHSBToRGB(const double hue,const double saturation,
287 const double brightness,double *red,double *green,double *blue)
297 Convert HSB to RGB colorspace.
299 assert(red != (double *) NULL);
300 assert(green != (double *) NULL);
301 assert(blue != (double *) NULL);
302 if (saturation == 0.0)
304 *red=QuantumRange*brightness;
309 h=6.0*(hue-floor(hue));
310 f=h-floor((double) h);
311 p=brightness*(1.0-saturation);
312 q=brightness*(1.0-saturation*f);
313 t=brightness*(1.0-(saturation*(1.0-f)));
319 *red=QuantumRange*brightness;
320 *green=QuantumRange*t;
321 *blue=QuantumRange*p;
327 *green=QuantumRange*brightness;
328 *blue=QuantumRange*p;
334 *green=QuantumRange*brightness;
335 *blue=QuantumRange*t;
341 *green=QuantumRange*q;
342 *blue=QuantumRange*brightness;
348 *green=QuantumRange*p;
349 *blue=QuantumRange*brightness;
354 *red=QuantumRange*brightness;
355 *green=QuantumRange*p;
356 *blue=QuantumRange*q;
363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
367 % C o n v e r t H S I T o R G B %
371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
373 % ConvertHSIToRGB() transforms a (hue, saturation, intensity) to a (red,
374 % green, blue) triple.
376 % The format of the ConvertHSIToRGBImage method is:
378 % void ConvertHSIToRGB(const double hue,const double saturation,
379 % const double intensity,double *red,double *green,double *blue)
381 % A description of each parameter follows:
383 % o hue, saturation, intensity: A double value representing a
384 % component of the HSI color space.
386 % o red, green, blue: A pointer to a pixel component of type Quantum.
389 MagickPrivate void ConvertHSIToRGB(const double hue,const double saturation,
390 const double intensity,double *red,double *green,double *blue)
399 Convert HSI to RGB colorspace.
401 assert(red != (double *) NULL);
402 assert(green != (double *) NULL);
403 assert(blue != (double *) NULL);
405 h-=360.0*floor(h/360.0);
408 b=intensity*(1.0-saturation);
409 r=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
417 r=intensity*(1.0-saturation);
418 g=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
425 g=intensity*(1.0-saturation);
426 b=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
431 *green=QuantumRange*g;
432 *blue=QuantumRange*b;
436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
440 % C o n v e r t H S L T o R G B %
444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
446 % ConvertHSLToRGB() transforms a (hue, saturation, lightness) to a (red,
447 % green, blue) triple.
449 % The format of the ConvertHSLToRGBImage method is:
451 % void ConvertHSLToRGB(const double hue,const double saturation,
452 % const double lightness,double *red,double *green,double *blue)
454 % A description of each parameter follows:
456 % o hue, saturation, lightness: A double value representing a
457 % component of the HSL color space.
459 % o red, green, blue: A pointer to a pixel component of type Quantum.
462 MagickExport void ConvertHSLToRGB(const double hue,const double saturation,
463 const double lightness,double *red,double *green,double *blue)
472 Convert HSL to RGB colorspace.
474 assert(red != (double *) NULL);
475 assert(green != (double *) NULL);
476 assert(blue != (double *) NULL);
478 if (lightness <= 0.5)
479 c=2.0*lightness*saturation;
481 c=(2.0-2.0*lightness)*saturation;
483 h-=360.0*floor(h/360.0);
485 x=c*(1.0-fabs(h-2.0*floor(h/2.0)-1.0));
486 switch ((int) floor(h))
490 *red=QuantumRange*(min+c);
491 *green=QuantumRange*(min+x);
492 *blue=QuantumRange*min;
497 *red=QuantumRange*(min+x);
498 *green=QuantumRange*(min+c);
499 *blue=QuantumRange*min;
504 *red=QuantumRange*min;
505 *green=QuantumRange*(min+c);
506 *blue=QuantumRange*(min+x);
511 *red=QuantumRange*min;
512 *green=QuantumRange*(min+x);
513 *blue=QuantumRange*(min+c);
518 *red=QuantumRange*(min+x);
519 *green=QuantumRange*min;
520 *blue=QuantumRange*(min+c);
525 *red=QuantumRange*(min+c);
526 *green=QuantumRange*min;
527 *blue=QuantumRange*(min+x);
540 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
544 % C o n v e r t H S V T o R G B %
548 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
550 % ConvertHSVToRGB() transforms a (hue, saturation, value) to a (red,
551 % green, blue) triple.
553 % The format of the ConvertHSVToRGBImage method is:
555 % void ConvertHSVToRGB(const double hue,const double saturation,
556 % const double value,double *red,double *green,double *blue)
558 % A description of each parameter follows:
560 % o hue, saturation, value: A double value representing a
561 % component of the HSV color space.
563 % o red, green, blue: A pointer to a pixel component of type Quantum.
566 MagickPrivate void ConvertHSVToRGB(const double hue,const double saturation,
567 const double value,double *red,double *green,double *blue)
576 Convert HSV to RGB colorspace.
578 assert(red != (double *) NULL);
579 assert(green != (double *) NULL);
580 assert(blue != (double *) NULL);
584 h-=360.0*floor(h/360.0);
586 x=c*(1.0-fabs(h-2.0*floor(h/2.0)-1.0));
587 switch ((int) floor(h))
591 *red=QuantumRange*(min+c);
592 *green=QuantumRange*(min+x);
593 *blue=QuantumRange*min;
598 *red=QuantumRange*(min+x);
599 *green=QuantumRange*(min+c);
600 *blue=QuantumRange*min;
605 *red=QuantumRange*min;
606 *green=QuantumRange*(min+c);
607 *blue=QuantumRange*(min+x);
612 *red=QuantumRange*min;
613 *green=QuantumRange*(min+x);
614 *blue=QuantumRange*(min+c);
619 *red=QuantumRange*(min+x);
620 *green=QuantumRange*min;
621 *blue=QuantumRange*(min+c);
626 *red=QuantumRange*(min+c);
627 *green=QuantumRange*min;
628 *blue=QuantumRange*(min+x);
641 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
645 % C o n v e r t H W B T o R G B %
649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
651 % ConvertHWBToRGB() transforms a (hue, whiteness, blackness) to a (red, green,
654 % The format of the ConvertHWBToRGBImage method is:
656 % void ConvertHWBToRGB(const double hue,const double whiteness,
657 % const double blackness,double *red,double *green,double *blue)
659 % A description of each parameter follows:
661 % o hue, whiteness, blackness: A double value representing a
662 % component of the HWB color space.
664 % o red, green, blue: A pointer to a pixel component of type Quantum.
667 MagickPrivate void ConvertHWBToRGB(const double hue,const double whiteness,
668 const double blackness,double *red,double *green,double *blue)
682 Convert HWB to RGB colorspace.
684 assert(red != (double *) NULL);
685 assert(green != (double *) NULL);
686 assert(blue != (double *) NULL);
691 *green=QuantumRange*v;
692 *blue=QuantumRange*v;
695 i=(ssize_t) floor(6.0*hue);
699 n=whiteness+f*(v-whiteness); /* linear interpolation */
704 case 0: r=v; g=n; b=whiteness; break;
705 case 1: r=n; g=v; b=whiteness; break;
706 case 2: r=whiteness; g=v; b=n; break;
707 case 3: r=whiteness; g=n; b=v; break;
708 case 4: r=n; g=whiteness; b=v; break;
709 case 5: r=v; g=whiteness; b=n; break;
712 *green=QuantumRange*g;
713 *blue=QuantumRange*b;
717 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
721 % C o n v e r t L C H a b T o R G B %
725 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
727 % ConvertLCHabToRGB() transforms a (luma, chroma, hue) to a (red, green,
730 % The format of the ConvertLCHabToRGBImage method is:
732 % void ConvertLCHabToRGB(const double luma,const double chroma,
733 % const double hue,double *red,double *green,double *blue)
735 % A description of each parameter follows:
737 % o luma, chroma, hue: A double value representing a component of the
740 % o red, green, blue: A pointer to a pixel component of type Quantum.
744 static inline void ConvertLCHabToXYZ(const double luma,const double chroma,
745 const double hue,double *X,double *Y,double *Z)
747 ConvertLabToXYZ(luma,chroma*cos(hue*MagickPI/180.0),chroma*
748 sin(hue*MagickPI/180.0),X,Y,Z);
751 MagickPrivate void ConvertLCHabToRGB(const double luma,const double chroma,
752 const double hue,double *red,double *green,double *blue)
760 Convert LCHab to RGB colorspace.
762 assert(red != (double *) NULL);
763 assert(green != (double *) NULL);
764 assert(blue != (double *) NULL);
765 ConvertLCHabToXYZ(100.0*luma,255.0*(chroma-0.5),360.0*hue,&X,&Y,&Z);
766 ConvertXYZToRGB(X,Y,Z,red,green,blue);
770 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
774 % C o n v e r t L C H u v T o R G B %
778 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
780 % ConvertLCHuvToRGB() transforms a (luma, chroma, hue) to a (red, green,
783 % The format of the ConvertLCHuvToRGBImage method is:
785 % void ConvertLCHuvToRGB(const double luma,const double chroma,
786 % const double hue,double *red,double *green,double *blue)
788 % A description of each parameter follows:
790 % o luma, chroma, hue: A double value representing a component of the
793 % o red, green, blue: A pointer to a pixel component of type Quantum.
797 static inline void ConvertLCHuvToXYZ(const double luma,const double chroma,
798 const double hue,double *X,double *Y,double *Z)
800 ConvertLuvToXYZ(luma,chroma*cos(hue*MagickPI/180.0),chroma*
801 sin(hue*MagickPI/180.0),X,Y,Z);
804 MagickPrivate void ConvertLCHuvToRGB(const double luma,const double chroma,
805 const double hue,double *red,double *green,double *blue)
813 Convert LCHuv to RGB colorspace.
815 assert(red != (double *) NULL);
816 assert(green != (double *) NULL);
817 assert(blue != (double *) NULL);
818 ConvertLCHuvToXYZ(100.0*luma,255.0*(chroma-0.5),360.0*hue,&X,&Y,&Z);
819 ConvertXYZToRGB(X,Y,Z,red,green,blue);
823 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
827 % C o n v e r t R G B T o H C L %
831 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
833 % ConvertRGBToHCL() transforms a (red, green, blue) to a (hue, chroma,
836 % The format of the ConvertRGBToHCL method is:
838 % void ConvertRGBToHCL(const double red,const double green,
839 % const double blue,double *hue,double *chroma,double *luma)
841 % A description of each parameter follows:
843 % o red, green, blue: A Quantum value representing the red, green, and
844 % blue component of a pixel.
846 % o hue, chroma, luma: A pointer to a double value representing a
847 % component of the HCL color space.
850 MagickPrivate void ConvertRGBToHCL(const double red,const double green,
851 const double blue,double *hue,double *chroma,double *luma)
862 Convert RGB to HCL colorspace.
864 assert(hue != (double *) NULL);
865 assert(chroma != (double *) NULL);
866 assert(luma != (double *) NULL);
870 max=MagickMax(r,MagickMax(g,b));
871 c=max-(double) MagickMin(r,MagickMin(g,b));
877 h=fmod((g-b)/c+6.0,6.0);
885 *chroma=QuantumScale*c;
886 *luma=QuantumScale*(0.298839*r+0.586811*g+0.114350*b);
890 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
894 % C o n v e r t R G B T o H C L p %
898 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
900 % ConvertRGBToHCLp() transforms a (red, green, blue) to a (hue, chroma,
903 % The format of the ConvertRGBToHCLp method is:
905 % void ConvertRGBToHCLp(const double red,const double green,
906 % const double blue,double *hue,double *chroma,double *luma)
908 % A description of each parameter follows:
910 % o red, green, blue: A Quantum value representing the red, green, and
911 % blue component of a pixel.
913 % o hue, chroma, luma: A pointer to a double value representing a
914 % component of the HCL color space.
917 MagickPrivate void ConvertRGBToHCLp(const double red,const double green,
918 const double blue,double *hue,double *chroma,double *luma)
929 Convert RGB to HCL colorspace.
931 assert(hue != (double *) NULL);
932 assert(chroma != (double *) NULL);
933 assert(luma != (double *) NULL);
937 max=MagickMax(r,MagickMax(g,b));
938 c=max-(double) MagickMin(r,MagickMin(g,b));
944 h=fmod((g-b)/c+6.0,6.0);
952 *chroma=QuantumScale*c;
953 *luma=QuantumScale*(0.298839*r+0.586811*g+0.114350*b);
957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
961 % C o n v e r t R G B T o H S B %
965 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
967 % ConvertRGBToHSB() transforms a (red, green, blue) to a (hue, saturation,
968 % brightness) triple.
970 % The format of the ConvertRGBToHSB method is:
972 % void ConvertRGBToHSB(const double red,const double green,
973 % const double blue,double *hue,double *saturation,double *brightness)
975 % A description of each parameter follows:
977 % o red, green, blue: A Quantum value representing the red, green, and
978 % blue component of a pixel..
980 % o hue, saturation, brightness: A pointer to a double value representing a
981 % component of the HSB color space.
984 MagickPrivate void ConvertRGBToHSB(const double red,const double green,
985 const double blue,double *hue,double *saturation,double *brightness)
996 Convert RGB to HSB colorspace.
998 assert(hue != (double *) NULL);
999 assert(saturation != (double *) NULL);
1000 assert(brightness != (double *) NULL);
1016 *saturation=delta/max;
1017 *brightness=QuantumScale*max;
1024 *hue=2.0+(b-r)/delta;
1026 *hue=4.0+(r-g)/delta;
1033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1037 % C o n v e r t R G B T o H S I %
1041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1043 % ConvertRGBToHSI() transforms a (red, green, blue) to a (hue, saturation,
1044 % intensity) triple.
1046 % The format of the ConvertRGBToHSI method is:
1048 % void ConvertRGBToHSI(const double red,const double green,
1049 % const double blue,double *hue,double *saturation,double *intensity)
1051 % A description of each parameter follows:
1053 % o red, green, blue: A Quantum value representing the red, green, and
1054 % blue component of a pixel..
1056 % o hue, saturation, intensity: A pointer to a double value representing a
1057 % component of the HSI color space.
1060 MagickPrivate void ConvertRGBToHSI(const double red,const double green,
1061 const double blue,double *hue,double *saturation,double *intensity)
1068 Convert RGB to HSI colorspace.
1070 assert(hue != (double *) NULL);
1071 assert(saturation != (double *) NULL);
1072 assert(intensity != (double *) NULL);
1073 *intensity=(QuantumScale*red+QuantumScale*green+QuantumScale*blue)/3.0;
1074 if (*intensity <= 0.0)
1080 *saturation=1.0-MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
1081 QuantumScale*blue))/(*intensity);
1082 alpha=0.5*(2.0*QuantumScale*red-QuantumScale*green-QuantumScale*blue);
1083 beta=0.8660254037844385*(QuantumScale*green-QuantumScale*blue);
1084 *hue=atan2(beta,alpha)*(180.0/MagickPI)/360.0;
1090 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1094 % C o n v e r t R G B T o H S L %
1098 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1100 % ConvertRGBToHSL() transforms a (red, green, blue) to a (hue, saturation,
1101 % lightness) triple.
1103 % The format of the ConvertRGBToHSL method is:
1105 % void ConvertRGBToHSL(const double red,const double green,
1106 % const double blue,double *hue,double *saturation,double *lightness)
1108 % A description of each parameter follows:
1110 % o red, green, blue: A Quantum value representing the red, green, and
1111 % blue component of a pixel..
1113 % o hue, saturation, lightness: A pointer to a double value representing a
1114 % component of the HSL color space.
1117 MagickExport void ConvertRGBToHSL(const double red,const double green,
1118 const double blue,double *hue,double *saturation,double *lightness)
1126 Convert RGB to HSL colorspace.
1128 assert(hue != (double *) NULL);
1129 assert(saturation != (double *) NULL);
1130 assert(lightness != (double *) NULL);
1131 max=MagickMax(QuantumScale*red,MagickMax(QuantumScale*green,
1132 QuantumScale*blue));
1133 min=MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
1134 QuantumScale*blue));
1136 *lightness=(max+min)/2.0;
1143 if (max == (QuantumScale*red))
1145 *hue=(QuantumScale*green-QuantumScale*blue)/c;
1146 if ((QuantumScale*green) < (QuantumScale*blue))
1150 if (max == (QuantumScale*green))
1151 *hue=2.0+(QuantumScale*blue-QuantumScale*red)/c;
1153 *hue=4.0+(QuantumScale*red-QuantumScale*green)/c;
1155 if (*lightness <= 0.5)
1156 *saturation=c/(2.0*(*lightness));
1158 *saturation=c/(2.0-2.0*(*lightness));
1162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1166 % C o n v e r t R G B T o H S V %
1170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1172 % ConvertRGBToHSV() transforms a (red, green, blue) to a (hue, saturation,
1175 % The format of the ConvertRGBToHSV method is:
1177 % void ConvertRGBToHSV(const double red,const double green,
1178 % const double blue,double *hue,double *saturation,double *value)
1180 % A description of each parameter follows:
1182 % o red, green, blue: A Quantum value representing the red, green, and
1183 % blue component of a pixel..
1185 % o hue, saturation, value: A pointer to a double value representing a
1186 % component of the HSV color space.
1189 MagickPrivate void ConvertRGBToHSV(const double red,const double green,
1190 const double blue,double *hue,double *saturation,double *value)
1198 Convert RGB to HSV colorspace.
1200 assert(hue != (double *) NULL);
1201 assert(saturation != (double *) NULL);
1202 assert(value != (double *) NULL);
1203 max=MagickMax(QuantumScale*red,MagickMax(QuantumScale*green,
1204 QuantumScale*blue));
1205 min=MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
1206 QuantumScale*blue));
1215 if (max == (QuantumScale*red))
1217 *hue=(QuantumScale*green-QuantumScale*blue)/c;
1218 if ((QuantumScale*green) < (QuantumScale*blue))
1222 if (max == (QuantumScale*green))
1223 *hue=2.0+(QuantumScale*blue-QuantumScale*red)/c;
1225 *hue=4.0+(QuantumScale*red-QuantumScale*green)/c;
1231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1235 % C o n v e r t R G B T o H W B %
1239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1241 % ConvertRGBToHWB() transforms a (red, green, blue) to a (hue, whiteness,
1242 % blackness) triple.
1244 % The format of the ConvertRGBToHWB method is:
1246 % void ConvertRGBToHWB(const double red,const double green,
1247 % const double blue,double *hue,double *whiteness,double *blackness)
1249 % A description of each parameter follows:
1251 % o red, green, blue: A Quantum value representing the red, green, and
1252 % blue component of a pixel.
1254 % o hue, whiteness, blackness: A pointer to a double value representing a
1255 % component of the HWB color space.
1258 MagickPrivate void ConvertRGBToHWB(const double red,const double green,
1259 const double blue,double *hue,double *whiteness,double *blackness)
1271 Convert RGB to HWB colorspace.
1273 assert(hue != (double *) NULL);
1274 assert(whiteness != (double *) NULL);
1275 assert(blackness != (double *) NULL);
1279 w=MagickMin(r,MagickMin(g,b));
1280 v=MagickMax(r,MagickMax(g,b));
1281 *blackness=1.0-QuantumScale*v;
1282 *whiteness=QuantumScale*w;
1288 f=(r == w) ? g-b : ((g == w) ? b-r : r-g);
1289 p=(r == w) ? 3.0 : ((g == w) ? 5.0 : 1.0);
1290 *hue=(p-f/(v-1.0*w))/6.0;
1294 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1298 % C o n v e r t R G B T o L C H a b %
1302 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1304 % ConvertRGBToLCHab() transforms a (red, green, blue) to a (luma, chroma,
1307 % The format of the ConvertRGBToLCHab method is:
1309 % void ConvertRGBToLCHab(const double red,const double green,
1310 % const double blue,double *luma,double *chroma,double *hue)
1312 % A description of each parameter follows:
1314 % o red, green, blue: A Quantum value representing the red, green, and
1315 % blue component of a pixel.
1317 % o luma, chroma, hue: A pointer to a double value representing a
1318 % component of the LCH color space.
1322 static inline void ConvertXYZToLCHab(const double X,const double Y,
1323 const double Z,double *luma,double *chroma,double *hue)
1329 ConvertXYZToLab(X,Y,Z,luma,&a,&b);
1330 *chroma=hypot(255.0*(a-0.5),255.0*(b-0.5))/255.0+0.5;
1331 *hue=180.0*atan2(255.0*(b-0.5),255.0*(a-0.5))/MagickPI/360.0;
1336 MagickPrivate void ConvertRGBToLCHab(const double red,const double green,
1337 const double blue,double *luma,double *chroma,double *hue)
1345 Convert RGB to LCHab colorspace.
1347 assert(luma != (double *) NULL);
1348 assert(chroma != (double *) NULL);
1349 assert(hue != (double *) NULL);
1350 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
1351 ConvertXYZToLCHab(X,Y,Z,luma,chroma,hue);
1355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1359 % C o n v e r t R G B T o L C H u v %
1363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1365 % ConvertRGBToLCHuv() transforms a (red, green, blue) to a (luma, chroma,
1368 % The format of the ConvertRGBToLCHuv method is:
1370 % void ConvertRGBToLCHuv(const double red,const double green,
1371 % const double blue,double *luma,double *chroma,double *hue)
1373 % A description of each parameter follows:
1375 % o red, green, blue: A Quantum value representing the red, green, and
1376 % blue component of a pixel.
1378 % o luma, chroma, hue: A pointer to a double value representing a
1379 % component of the LCHuv color space.
1383 static inline void ConvertXYZToLCHuv(const double X,const double Y,
1384 const double Z,double *luma,double *chroma,double *hue)
1390 ConvertXYZToLuv(X,Y,Z,luma,&u,&v);
1391 *chroma=hypot(354.0*u-134.0,262.0*v-140.0)/255.0+0.5;
1392 *hue=180.0*atan2(262.0*v-140.0,354.0*u-134.0)/MagickPI/360.0;
1397 MagickPrivate void ConvertRGBToLCHuv(const double red,const double green,
1398 const double blue,double *luma,double *chroma,double *hue)
1406 Convert RGB to LCHuv colorspace.
1408 assert(luma != (double *) NULL);
1409 assert(chroma != (double *) NULL);
1410 assert(hue != (double *) NULL);
1411 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
1412 ConvertXYZToLCHuv(X,Y,Z,luma,chroma,hue);
1416 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1420 % E x p a n d A f f i n e %
1424 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1426 % ExpandAffine() computes the affine's expansion factor, i.e. the square root
1427 % of the factor by which the affine transform affects area. In an affine
1428 % transform composed of scaling, rotation, shearing, and translation, returns
1429 % the amount of scaling.
1431 % The format of the ExpandAffine method is:
1433 % double ExpandAffine(const AffineMatrix *affine)
1435 % A description of each parameter follows:
1437 % o expansion: ExpandAffine returns the affine's expansion factor.
1439 % o affine: A pointer the affine transform of type AffineMatrix.
1442 MagickExport double ExpandAffine(const AffineMatrix *affine)
1444 assert(affine != (const AffineMatrix *) NULL);
1445 return(sqrt(fabs(affine->sx*affine->sy-affine->rx*affine->ry)));
1449 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1453 % 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 %
1457 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1459 % GenerateDifferentialNoise() generates differentual noise.
1461 % The format of the GenerateDifferentialNoise method is:
1463 % double GenerateDifferentialNoise(RandomInfo *random_info,
1464 % const Quantum pixel,const NoiseType noise_type,const double attenuate)
1466 % A description of each parameter follows:
1468 % o random_info: the random info.
1470 % o pixel: noise is relative to this pixel value.
1472 % o noise_type: the type of noise.
1474 % o attenuate: attenuate the noise.
1477 MagickPrivate double GenerateDifferentialNoise(RandomInfo *random_info,
1478 const Quantum pixel,const NoiseType noise_type,const double attenuate)
1480 #define SigmaUniform (attenuate*0.015625)
1481 #define SigmaGaussian (attenuate*0.015625)
1482 #define SigmaImpulse (attenuate*0.1)
1483 #define SigmaLaplacian (attenuate*0.0390625)
1484 #define SigmaMultiplicativeGaussian (attenuate*0.5)
1485 #define SigmaPoisson (attenuate*12.5)
1486 #define SigmaRandom (attenuate)
1487 #define TauGaussian (attenuate*0.078125)
1495 alpha=GetPseudoRandomValue(random_info);
1501 noise=(double) (pixel+QuantumRange*SigmaUniform*(alpha-0.5));
1512 beta=GetPseudoRandomValue(random_info);
1513 gamma=sqrt(-2.0*log(alpha));
1514 sigma=gamma*cos((double) (2.0*MagickPI*beta));
1515 tau=gamma*sin((double) (2.0*MagickPI*beta));
1516 noise=(double) (pixel+sqrt((double) pixel)*SigmaGaussian*sigma+
1517 QuantumRange*TauGaussian*tau);
1522 if (alpha < (SigmaImpulse/2.0))
1525 if (alpha >= (1.0-(SigmaImpulse/2.0)))
1526 noise=(double) QuantumRange;
1528 noise=(double) pixel;
1531 case LaplacianNoise:
1535 if (alpha <= MagickEpsilon)
1536 noise=(double) (pixel-QuantumRange);
1538 noise=(double) (pixel+QuantumRange*SigmaLaplacian*log(2.0*alpha)+
1543 if (beta <= (0.5*MagickEpsilon))
1544 noise=(double) (pixel+QuantumRange);
1546 noise=(double) (pixel-QuantumRange*SigmaLaplacian*log(2.0*beta)+0.5);
1549 case MultiplicativeGaussianNoise:
1552 if (alpha > MagickEpsilon)
1553 sigma=sqrt(-2.0*log(alpha));
1554 beta=GetPseudoRandomValue(random_info);
1555 noise=(double) (pixel+pixel*SigmaMultiplicativeGaussian*sigma*
1556 cos((double) (2.0*MagickPI*beta))/2.0);
1567 poisson=exp(-SigmaPoisson*QuantumScale*pixel);
1568 for (i=0; alpha > poisson; i++)
1570 beta=GetPseudoRandomValue(random_info);
1573 noise=(double) (QuantumRange*i/SigmaPoisson);
1578 noise=(double) (QuantumRange*SigmaRandom*alpha);
1586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1590 % G e t O p t i m a l K e r n e l W i d t h %
1594 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1596 % GetOptimalKernelWidth() computes the optimal kernel radius for a convolution
1597 % filter. Start with the minimum value of 3 pixels and walk out until we drop
1598 % below the threshold of one pixel numerical accuracy.
1600 % The format of the GetOptimalKernelWidth method is:
1602 % size_t GetOptimalKernelWidth(const double radius,
1603 % const double sigma)
1605 % A description of each parameter follows:
1607 % o width: GetOptimalKernelWidth returns the optimal width of a
1608 % convolution kernel.
1610 % o radius: the radius of the Gaussian, in pixels, not counting the center
1613 % o sigma: the standard deviation of the Gaussian, in pixels.
1616 MagickPrivate size_t GetOptimalKernelWidth1D(const double radius,
1635 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1636 if (radius > MagickEpsilon)
1637 return((size_t) (2.0*ceil(radius)+1.0));
1639 if (gamma <= MagickEpsilon)
1641 alpha=PerceptibleReciprocal(2.0*gamma*gamma);
1642 beta=(double) PerceptibleReciprocal((double) MagickSQ2PI*gamma);
1646 j=(ssize_t) (width-1)/2;
1647 for (i=(-j); i <= j; i++)
1648 normalize+=exp(-((double) (i*i))*alpha)*beta;
1649 value=exp(-((double) (j*j))*alpha)*beta/normalize;
1650 if ((value < QuantumScale) || (value < MagickEpsilon))
1654 return((size_t) (width-2));
1657 MagickPrivate size_t GetOptimalKernelWidth2D(const double radius,
1675 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1676 if (radius > MagickEpsilon)
1677 return((size_t) (2.0*ceil(radius)+1.0));
1679 if (gamma <= MagickEpsilon)
1681 alpha=PerceptibleReciprocal(2.0*gamma*gamma);
1682 beta=(double) PerceptibleReciprocal((double) Magick2PI*gamma*gamma);
1686 j=(ssize_t) (width-1)/2;
1687 for (v=(-j); v <= j; v++)
1688 for (u=(-j); u <= j; u++)
1689 normalize+=exp(-((double) (u*u+v*v))*alpha)*beta;
1690 value=exp(-((double) (j*j))*alpha)*beta/normalize;
1691 if ((value < QuantumScale) || (value < MagickEpsilon))
1695 return((size_t) (width-2));
1698 MagickPrivate size_t GetOptimalKernelWidth(const double radius,
1701 return(GetOptimalKernelWidth1D(radius,sigma));