2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Graphic Gems - Graphic Support Methods %
20 % Copyright 1999-2013 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
83 % component of the HCL color space.
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)
102 Convert HCL to RGB colorspace.
104 assert(red != (double *) NULL);
105 assert(green != (double *) NULL);
106 assert(blue != (double *) NULL);
110 u=C*cos(360.0*H*MagickPI/180.0)+134.0/354.0;
111 v=C*sin(360.0*H*MagickPI/180.0)+140.0/262.0;
112 ConvertLuvToXYZ(L,u,v,&X,&Y,&Z);
113 ConvertXYZToRGB(X,Y,Z,red,green,blue);
117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121 % C o n v e r t H S B T o R G B %
125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127 % ConvertHSBToRGB() transforms a (hue, saturation, brightness) to a (red,
128 % green, blue) triple.
130 % The format of the ConvertHSBToRGBImage method is:
132 % void ConvertHSBToRGB(const double hue,const double saturation,
133 % const double brightness,double *red,double *green,double *blue)
135 % A description of each parameter follows:
137 % o hue, saturation, brightness: A double value representing a
138 % component of the HSB color space.
140 % o red, green, blue: A pointer to a pixel component of type Quantum.
143 MagickPrivate void ConvertHSBToRGB(const double hue,const double saturation,
144 const double brightness,double *red,double *green,double *blue)
154 Convert HSB to RGB colorspace.
156 assert(red != (double *) NULL);
157 assert(green != (double *) NULL);
158 assert(blue != (double *) NULL);
159 if (saturation == 0.0)
161 *red=QuantumRange*brightness;
166 h=6.0*(hue-floor(hue));
167 f=h-floor((double) h);
168 p=brightness*(1.0-saturation);
169 q=brightness*(1.0-saturation*f);
170 t=brightness*(1.0-(saturation*(1.0-f)));
176 *red=QuantumRange*brightness;
177 *green=QuantumRange*t;
178 *blue=QuantumRange*p;
184 *green=QuantumRange*brightness;
185 *blue=QuantumRange*p;
191 *green=QuantumRange*brightness;
192 *blue=QuantumRange*t;
198 *green=QuantumRange*q;
199 *blue=QuantumRange*brightness;
205 *green=QuantumRange*p;
206 *blue=QuantumRange*brightness;
211 *red=QuantumRange*brightness;
212 *green=QuantumRange*p;
213 *blue=QuantumRange*q;
220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
224 % C o n v e r t H S L T o R G B %
228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
230 % ConvertHSLToRGB() transforms a (hue, saturation, lightness) to a (red,
231 % green, blue) triple.
233 % The format of the ConvertHSLToRGBImage method is:
235 % void ConvertHSLToRGB(const double hue,const double saturation,
236 % const double lightness,double *red,double *green,double *blue)
238 % A description of each parameter follows:
240 % o hue, saturation, lightness: A double value representing a
241 % component of the HSL color space.
243 % o red, green, blue: A pointer to a pixel component of type Quantum.
247 static inline double ConvertHueToRGB(double m1,double m2,double hue)
254 return(m1+6.0*(m2-m1)*hue);
258 return(m1+6.0*(m2-m1)*(2.0/3.0-hue));
262 MagickExport void ConvertHSLToRGB(const double hue,const double saturation,
263 const double lightness,double *red,double *green,double *blue)
273 Convert HSL to RGB colorspace.
275 assert(red != (double *) NULL);
276 assert(green != (double *) NULL);
277 assert(blue != (double *) NULL);
280 *red=QuantumRange*lightness;
286 m2=lightness*(saturation+1.0);
288 m2=(lightness+saturation)-(lightness*saturation);
290 r=ConvertHueToRGB(m1,m2,hue+1.0/3.0);
291 g=ConvertHueToRGB(m1,m2,hue);
292 b=ConvertHueToRGB(m1,m2,hue-1.0/3.0);
294 *green=QuantumRange*g;
295 *blue=QuantumRange*b;
299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
303 % C o n v e r t H W B T o R G B %
307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
309 % ConvertHWBToRGB() transforms a (hue, whiteness, blackness) to a (red, green,
312 % The format of the ConvertHWBToRGBImage method is:
314 % void ConvertHWBToRGB(const double hue,const double whiteness,
315 % const double blackness,double *red,double *green,double *blue)
317 % A description of each parameter follows:
319 % o hue, whiteness, blackness: A double value representing a
320 % component of the HWB color space.
322 % o red, green, blue: A pointer to a pixel component of type Quantum.
325 MagickPrivate void ConvertHWBToRGB(const double hue,const double whiteness,
326 const double blackness,double *red,double *green,double *blue)
340 Convert HWB to RGB colorspace.
342 assert(red != (double *) NULL);
343 assert(green != (double *) NULL);
344 assert(blue != (double *) NULL);
349 *green=QuantumRange*v;
350 *blue=QuantumRange*v;
353 i=(ssize_t) floor(6.0*hue);
357 n=whiteness+f*(v-whiteness); /* linear interpolation */
362 case 0: r=v; g=n; b=whiteness; break;
363 case 1: r=n; g=v; b=whiteness; break;
364 case 2: r=whiteness; g=v; b=n; break;
365 case 3: r=whiteness; g=n; b=v; break;
366 case 4: r=n; g=whiteness; b=v; break;
367 case 5: r=v; g=whiteness; b=n; break;
370 *green=QuantumRange*g;
371 *blue=QuantumRange*b;
375 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
379 % C o n v e r t L C H a b T o R G B %
383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
385 % ConvertLCHabToRGB() transforms a (luma, chroma, hue) to a (red, green,
388 % The format of the ConvertLCHabToRGBImage method is:
390 % void ConvertLCHabToRGB(const double luma,const double chroma,
391 % const double hue,double *red,double *green,double *blue)
393 % A description of each parameter follows:
395 % o luma, chroma, hue: A double value representing a component of the
398 % o red, green, blue: A pointer to a pixel component of type Quantum.
401 MagickPrivate void ConvertLCHabToRGB(const double luma,const double chroma,
402 const double hue,double *red,double *green,double *blue)
415 Convert LCHab to RGB colorspace.
417 assert(red != (double *) NULL);
418 assert(green != (double *) NULL);
419 assert(blue != (double *) NULL);
423 a=C*cos(360.0*H*MagickPI/180.0)+0.5;
424 b=C*sin(360.0*H*MagickPI/180.0)+0.5;
425 ConvertLabToXYZ(L,a,b,&X,&Y,&Z);
426 ConvertXYZToRGB(X,Y,Z,red,green,blue);
430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
434 % C o n v e r t L C H u v T o R G B %
438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
440 % ConvertLCHuvToRGB() transforms a (luma, chroma, hue) to a (red, green,
443 % The format of the ConvertLCHuvToRGBImage method is:
445 % void ConvertLCHuvToRGB(const double luma,const double chroma,
446 % const double hue,double *red,double *green,double *blue)
448 % A description of each parameter follows:
450 % o luma, chroma, hue: A double value representing a component of the
453 % o red, green, blue: A pointer to a pixel component of type Quantum.
456 MagickPrivate void ConvertLCHuvToRGB(const double luma,const double chroma,
457 const double hue,double *red,double *green,double *blue)
470 Convert LCHuv to RGB colorspace.
472 assert(red != (double *) NULL);
473 assert(green != (double *) NULL);
474 assert(blue != (double *) NULL);
478 u=C*cos(360.0*H*MagickPI/180.0)+134.0/354.0;
479 v=C*sin(360.0*H*MagickPI/180.0)+140.0/262.0;
480 ConvertLuvToXYZ(L,u,v,&X,&Y,&Z);
481 ConvertXYZToRGB(X,Y,Z,red,green,blue);
485 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
489 % C o n v e r t R G B T o H C L %
493 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
495 % ConvertRGBToHCL() transforms a (red, green, blue) to a (hue, chroma,
498 % The format of the ConvertRGBToHCL method is:
500 % void ConvertRGBToHCL(const double red,const double green,
501 % const double blue,double *hue,double *chroma,double *luma)
503 % A description of each parameter follows:
505 % o red, green, blue: A Quantum value representing the red, green, and
506 % blue component of a pixel.
508 % o hue, chroma, luma: A pointer to a double value representing a
509 % component of the HCL color space.
512 MagickPrivate void ConvertRGBToHCL(const double red,const double green,
513 const double blue,double *hue,double *chroma,double *luma)
526 Convert RGB to HCL colorspace.
528 assert(luma != (double *) NULL);
529 assert(chroma != (double *) NULL);
530 assert(hue != (double *) NULL);
531 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
532 ConvertXYZToLuv(X,Y,Z,&L,&u,&v);
533 C=hypot(u-134.0/354.0,v-140.0/262.0);
534 H=180.0*atan2(v-140.0/262.0,u-134.0/354.0)/MagickPI/360.0;
545 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
549 % C o n v e r t R G B T o H S B %
553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
555 % ConvertRGBToHSB() transforms a (red, green, blue) to a (hue, saturation,
556 % brightness) triple.
558 % The format of the ConvertRGBToHSB method is:
560 % void ConvertRGBToHSB(const double red,const double green,
561 % const double blue,double *hue,double *saturation,double *brightness)
563 % A description of each parameter follows:
565 % o red, green, blue: A Quantum value representing the red, green, and
566 % blue component of a pixel..
568 % o hue, saturation, brightness: A pointer to a double value representing a
569 % component of the HSB color space.
572 MagickPrivate void ConvertRGBToHSB(const double red,const double green,
573 const double blue,double *hue,double *saturation,double *brightness)
584 Convert RGB to HSB colorspace.
586 assert(hue != (double *) NULL);
587 assert(saturation != (double *) NULL);
588 assert(brightness != (double *) NULL);
604 *saturation=delta/max;
605 *brightness=QuantumScale*max;
612 *hue=2.0+(b-r)/delta;
614 *hue=4.0+(r-g)/delta;
621 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
625 % C o n v e r t R G B T o H S L %
629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
631 % ConvertRGBToHSL() transforms a (red, green, blue) to a (hue, saturation,
634 % The format of the ConvertRGBToHSL method is:
636 % void ConvertRGBToHSL(const double red,const double green,
637 % const double blue,double *hue,double *saturation,double *lightness)
639 % A description of each parameter follows:
641 % o red, green, blue: A Quantum value representing the red, green, and
642 % blue component of a pixel..
644 % o hue, saturation, lightness: A pointer to a double value representing a
645 % component of the HSL color space.
649 static inline double MagickMax(const double x,const double y)
656 static inline double MagickMin(const double x,const double y)
663 MagickExport void ConvertRGBToHSL(const double red,const double green,
664 const double blue,double *hue,double *saturation,double *lightness)
675 Convert RGB to HSL colorspace.
677 assert(hue != (double *) NULL);
678 assert(saturation != (double *) NULL);
679 assert(lightness != (double *) NULL);
681 g=QuantumScale*green;
683 max=MagickMax(r,MagickMax(g,b));
684 min=MagickMin(r,MagickMin(g,b));
685 *lightness=(double) ((min+max)/2.0);
693 if (*lightness < 0.5)
694 *saturation=(double) (delta/(min+max));
696 *saturation=(double) (delta/(2.0-max-min));
698 *hue=((((max-b)/6.0)+(delta/2.0))-(((max-g)/6.0)+(delta/2.0)))/delta;
701 *hue=(1.0/3.0)+((((max-r)/6.0)+(delta/2.0))-(((max-b)/6.0)+(delta/2.0)))/
705 *hue=(2.0/3.0)+((((max-g)/6.0)+(delta/2.0))-(((max-r)/6.0)+
714 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
718 % C o n v e r t R G B T o H W B %
722 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
724 % ConvertRGBToHWB() transforms a (red, green, blue) to a (hue, whiteness,
727 % The format of the ConvertRGBToHWB method is:
729 % void ConvertRGBToHWB(const double red,const double green,
730 % const double blue,double *hue,double *whiteness,double *blackness)
732 % A description of each parameter follows:
734 % o red, green, blue: A Quantum value representing the red, green, and
735 % blue component of a pixel.
737 % o hue, whiteness, blackness: A pointer to a double value representing a
738 % component of the HWB color space.
741 MagickPrivate void ConvertRGBToHWB(const double red,const double green,
742 const double blue,double *hue,double *whiteness,double *blackness)
754 Convert RGB to HWB colorspace.
756 assert(hue != (double *) NULL);
757 assert(whiteness != (double *) NULL);
758 assert(blackness != (double *) NULL);
762 w=MagickMin(r,MagickMin(g,b));
763 v=MagickMax(r,MagickMax(g,b));
764 *blackness=1.0-QuantumScale*v;
765 *whiteness=QuantumScale*w;
771 f=(r == w) ? g-b : ((g == w) ? b-r : r-g);
772 p=(r == w) ? 3.0 : ((g == w) ? 5.0 : 1.0);
773 *hue=(p-f/(v-1.0*w))/6.0;
777 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
781 % C o n v e r t R G B a b T o L C H %
785 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
787 % ConvertRGBToLCHab() transforms a (red, green, blue) to a (luma, chroma,
790 % The format of the ConvertRGBToLCHab method is:
792 % void ConvertRGBToLCHab(const double red,const double green,
793 % const double blue,double *luma,double *chroma,double *hue)
795 % A description of each parameter follows:
797 % o red, green, blue: A Quantum value representing the red, green, and
798 % blue component of a pixel.
800 % o luma, chroma, hue: A pointer to a double value representing a
801 % component of the LCH color space.
804 MagickPrivate void ConvertRGBToLCHab(const double red,const double green,
805 const double blue,double *luma,double *chroma,double *hue)
818 Convert RGB to LCHab colorspace.
820 assert(luma != (double *) NULL);
821 assert(chroma != (double *) NULL);
822 assert(hue != (double *) NULL);
823 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
824 ConvertXYZToLab(X,Y,Z,&L,&a,&b);
825 C=hypot(a-0.5,b-0.5);
826 H=180.0*atan2(b-0.5,a-0.5)/MagickPI/360.0;
837 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
841 % C o n v e r t R G B u v T o L C H %
845 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
847 % ConvertRGBToLCHuv() transforms a (red, green, blue) to a (luma, chroma,
850 % The format of the ConvertRGBToLCHuv method is:
852 % void ConvertRGBToLCHuv(const double red,const double green,
853 % const double blue,double *luma,double *chroma,double *hue)
855 % A description of each parameter follows:
857 % o red, green, blue: A Quantum value representing the red, green, and
858 % blue component of a pixel.
860 % o luma, chroma, hue: A pointer to a double value representing a
861 % component of the LCHuv color space.
864 MagickPrivate void ConvertRGBToLCHuv(const double red,const double green,
865 const double blue,double *luma,double *chroma,double *hue)
878 Convert RGB to LCHuv colorspace.
880 assert(luma != (double *) NULL);
881 assert(chroma != (double *) NULL);
882 assert(hue != (double *) NULL);
883 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
884 ConvertXYZToLuv(X,Y,Z,&L,&u,&v);
885 C=hypot(u-134.0/354.0,v-140.0/262.0);
886 H=180.0*atan2(v-140.0/262.0,u-134.0/354.0)/MagickPI/360.0;
897 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
901 % E x p a n d A f f i n e %
905 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
907 % ExpandAffine() computes the affine's expansion factor, i.e. the square root
908 % of the factor by which the affine transform affects area. In an affine
909 % transform composed of scaling, rotation, shearing, and translation, returns
910 % the amount of scaling.
912 % The format of the ExpandAffine method is:
914 % double ExpandAffine(const AffineMatrix *affine)
916 % A description of each parameter follows:
918 % o expansion: Method ExpandAffine returns the affine's expansion factor.
920 % o affine: A pointer the affine transform of type AffineMatrix.
923 MagickExport double ExpandAffine(const AffineMatrix *affine)
925 assert(affine != (const AffineMatrix *) NULL);
926 return(sqrt(fabs(affine->sx*affine->sy-affine->rx*affine->ry)));
930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
934 % 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 %
938 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
940 % GenerateDifferentialNoise() generates differentual noise.
942 % The format of the GenerateDifferentialNoise method is:
944 % double GenerateDifferentialNoise(RandomInfo *random_info,
945 % const Quantum pixel,const NoiseType noise_type,const double attenuate)
947 % A description of each parameter follows:
949 % o random_info: the random info.
951 % o pixel: noise is relative to this pixel value.
953 % o noise_type: the type of noise.
955 % o attenuate: attenuate the noise.
958 MagickPrivate double GenerateDifferentialNoise(RandomInfo *random_info,
959 const Quantum pixel,const NoiseType noise_type,const double attenuate)
961 #define SigmaUniform (attenuate*0.015625)
962 #define SigmaGaussian (attenuate*0.015625)
963 #define SigmaImpulse (attenuate*0.1)
964 #define SigmaLaplacian (attenuate*0.0390625)
965 #define SigmaMultiplicativeGaussian (attenuate*0.5)
966 #define SigmaPoisson (attenuate*12.5)
967 #define SigmaRandom (attenuate)
968 #define TauGaussian (attenuate*0.078125)
976 alpha=GetPseudoRandomValue(random_info);
982 noise=(double) (pixel+QuantumRange*SigmaUniform*(alpha-0.5));
993 beta=GetPseudoRandomValue(random_info);
994 gamma=sqrt(-2.0*log(alpha));
995 sigma=gamma*cos((double) (2.0*MagickPI*beta));
996 tau=gamma*sin((double) (2.0*MagickPI*beta));
997 noise=(double) (pixel+sqrt((double) pixel)*SigmaGaussian*sigma+
998 QuantumRange*TauGaussian*tau);
1003 if (alpha < (SigmaImpulse/2.0))
1006 if (alpha >= (1.0-(SigmaImpulse/2.0)))
1007 noise=(double) QuantumRange;
1009 noise=(double) pixel;
1012 case LaplacianNoise:
1016 if (alpha <= MagickEpsilon)
1017 noise=(double) (pixel-QuantumRange);
1019 noise=(double) (pixel+QuantumRange*SigmaLaplacian*log(2.0*alpha)+
1024 if (beta <= (0.5*MagickEpsilon))
1025 noise=(double) (pixel+QuantumRange);
1027 noise=(double) (pixel-QuantumRange*SigmaLaplacian*log(2.0*beta)+0.5);
1030 case MultiplicativeGaussianNoise:
1033 if (alpha > MagickEpsilon)
1034 sigma=sqrt(-2.0*log(alpha));
1035 beta=GetPseudoRandomValue(random_info);
1036 noise=(double) (pixel+pixel*SigmaMultiplicativeGaussian*sigma*
1037 cos((double) (2.0*MagickPI*beta))/2.0);
1048 poisson=exp(-SigmaPoisson*QuantumScale*pixel);
1049 for (i=0; alpha > poisson; i++)
1051 beta=GetPseudoRandomValue(random_info);
1054 noise=(double) (QuantumRange*i/SigmaPoisson);
1059 noise=(double) (QuantumRange*SigmaRandom*alpha);
1067 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1071 % G e t O p t i m a l K e r n e l W i d t h %
1075 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1077 % GetOptimalKernelWidth() computes the optimal kernel radius for a convolution
1078 % filter. Start with the minimum value of 3 pixels and walk out until we drop
1079 % below the threshold of one pixel numerical accuracy.
1081 % The format of the GetOptimalKernelWidth method is:
1083 % size_t GetOptimalKernelWidth(const double radius,
1084 % const double sigma)
1086 % A description of each parameter follows:
1088 % o width: Method GetOptimalKernelWidth returns the optimal width of
1089 % a convolution kernel.
1091 % o radius: the radius of the Gaussian, in pixels, not counting the center
1094 % o sigma: the standard deviation of the Gaussian, in pixels.
1097 MagickPrivate size_t GetOptimalKernelWidth1D(const double radius,
1116 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1117 if (radius > MagickEpsilon)
1118 return((size_t) (2.0*ceil(radius)+1.0));
1120 if (gamma <= MagickEpsilon)
1122 alpha=PerceptibleReciprocal(2.0*gamma*gamma);
1123 beta=(double) PerceptibleReciprocal((double) MagickSQ2PI*gamma);
1127 j=(ssize_t) (width-1)/2;
1128 for (i=(-j); i <= j; i++)
1129 normalize+=exp(-((double) (i*i))*alpha)*beta;
1130 value=exp(-((double) (j*j))*alpha)*beta/normalize;
1131 if ((value < QuantumScale) || (value < MagickEpsilon))
1135 return((size_t) (width-2));
1138 MagickPrivate size_t GetOptimalKernelWidth2D(const double radius,
1156 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1157 if (radius > MagickEpsilon)
1158 return((size_t) (2.0*ceil(radius)+1.0));
1160 if (gamma <= MagickEpsilon)
1162 alpha=PerceptibleReciprocal(2.0*gamma*gamma);
1163 beta=(double) PerceptibleReciprocal((double) Magick2PI*gamma*gamma);
1167 j=(ssize_t) (width-1)/2;
1168 for (v=(-j); v <= j; v++)
1169 for (u=(-j); u <= j; u++)
1170 normalize+=exp(-((double) (u*u+v*v))*alpha)*beta;
1171 value=exp(-((double) (j*j))*alpha)*beta/normalize;
1172 if ((value < QuantumScale) || (value < MagickEpsilon))
1176 return((size_t) (width-2));
1179 MagickPrivate size_t GetOptimalKernelWidth(const double radius,
1182 return(GetOptimalKernelWidth1D(radius,sigma));