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)
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.298839f*r+0.586811f*g+0.114350f*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 S B T o R G B %
162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164 % ConvertHSBToRGB() transforms a (hue, saturation, brightness) to a (red,
165 % green, blue) triple.
167 % The format of the ConvertHSBToRGBImage method is:
169 % void ConvertHSBToRGB(const double hue,const double saturation,
170 % const double brightness,double *red,double *green,double *blue)
172 % A description of each parameter follows:
174 % o hue, saturation, brightness: A double value representing a
175 % component of the HSB color space.
177 % o red, green, blue: A pointer to a pixel component of type Quantum.
180 MagickPrivate void ConvertHSBToRGB(const double hue,const double saturation,
181 const double brightness,double *red,double *green,double *blue)
191 Convert HSB to RGB colorspace.
193 assert(red != (double *) NULL);
194 assert(green != (double *) NULL);
195 assert(blue != (double *) NULL);
196 if (saturation == 0.0)
198 *red=QuantumRange*brightness;
203 h=6.0*(hue-floor(hue));
204 f=h-floor((double) h);
205 p=brightness*(1.0-saturation);
206 q=brightness*(1.0-saturation*f);
207 t=brightness*(1.0-(saturation*(1.0-f)));
213 *red=QuantumRange*brightness;
214 *green=QuantumRange*t;
215 *blue=QuantumRange*p;
221 *green=QuantumRange*brightness;
222 *blue=QuantumRange*p;
228 *green=QuantumRange*brightness;
229 *blue=QuantumRange*t;
235 *green=QuantumRange*q;
236 *blue=QuantumRange*brightness;
242 *green=QuantumRange*p;
243 *blue=QuantumRange*brightness;
248 *red=QuantumRange*brightness;
249 *green=QuantumRange*p;
250 *blue=QuantumRange*q;
257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261 % C o n v e r t H S L T o R G B %
265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
267 % ConvertHSLToRGB() transforms a (hue, saturation, lightness) to a (red,
268 % green, blue) triple.
270 % The format of the ConvertHSLToRGBImage method is:
272 % void ConvertHSLToRGB(const double hue,const double saturation,
273 % const double lightness,double *red,double *green,double *blue)
275 % A description of each parameter follows:
277 % o hue, saturation, lightness: A double value representing a
278 % component of the HSL color space.
280 % o red, green, blue: A pointer to a pixel component of type Quantum.
284 static inline double ConvertHueToRGB(double m1,double m2,double hue)
291 return(m1+6.0*(m2-m1)*hue);
295 return(m1+6.0*(m2-m1)*(2.0/3.0-hue));
299 MagickExport void ConvertHSLToRGB(const double hue,const double saturation,
300 const double lightness,double *red,double *green,double *blue)
310 Convert HSL to RGB colorspace.
312 assert(red != (double *) NULL);
313 assert(green != (double *) NULL);
314 assert(blue != (double *) NULL);
317 *red=QuantumRange*lightness;
323 m2=lightness*(saturation+1.0);
325 m2=(lightness+saturation)-(lightness*saturation);
327 r=ConvertHueToRGB(m1,m2,hue+1.0/3.0);
328 g=ConvertHueToRGB(m1,m2,hue);
329 b=ConvertHueToRGB(m1,m2,hue-1.0/3.0);
331 *green=QuantumRange*g;
332 *blue=QuantumRange*b;
336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
340 % C o n v e r t H W B T o R G B %
344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
346 % ConvertHWBToRGB() transforms a (hue, whiteness, blackness) to a (red, green,
349 % The format of the ConvertHWBToRGBImage method is:
351 % void ConvertHWBToRGB(const double hue,const double whiteness,
352 % const double blackness,double *red,double *green,double *blue)
354 % A description of each parameter follows:
356 % o hue, whiteness, blackness: A double value representing a
357 % component of the HWB color space.
359 % o red, green, blue: A pointer to a pixel component of type Quantum.
362 MagickPrivate void ConvertHWBToRGB(const double hue,const double whiteness,
363 const double blackness,double *red,double *green,double *blue)
377 Convert HWB to RGB colorspace.
379 assert(red != (double *) NULL);
380 assert(green != (double *) NULL);
381 assert(blue != (double *) NULL);
386 *green=QuantumRange*v;
387 *blue=QuantumRange*v;
390 i=(ssize_t) floor(6.0*hue);
394 n=whiteness+f*(v-whiteness); /* linear interpolation */
399 case 0: r=v; g=n; b=whiteness; break;
400 case 1: r=n; g=v; b=whiteness; break;
401 case 2: r=whiteness; g=v; b=n; break;
402 case 3: r=whiteness; g=n; b=v; break;
403 case 4: r=n; g=whiteness; b=v; break;
404 case 5: r=v; g=whiteness; b=n; break;
407 *green=QuantumRange*g;
408 *blue=QuantumRange*b;
412 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
416 % C o n v e r t L C H a b T o R G B %
420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
422 % ConvertLCHabToRGB() transforms a (luma, chroma, hue) to a (red, green,
425 % The format of the ConvertLCHabToRGBImage method is:
427 % void ConvertLCHabToRGB(const double luma,const double chroma,
428 % const double hue,double *red,double *green,double *blue)
430 % A description of each parameter follows:
432 % o luma, chroma, hue: A double value representing a component of the
435 % o red, green, blue: A pointer to a pixel component of type Quantum.
438 MagickPrivate void ConvertLCHabToRGB(const double luma,const double chroma,
439 const double hue,double *red,double *green,double *blue)
452 Convert LCHab to RGB colorspace.
454 assert(red != (double *) NULL);
455 assert(green != (double *) NULL);
456 assert(blue != (double *) NULL);
460 a=C*cos(360.0*H*MagickPI/180.0)+0.5;
461 b=C*sin(360.0*H*MagickPI/180.0)+0.5;
462 ConvertLabToXYZ(L,a,b,&X,&Y,&Z);
463 ConvertXYZToRGB(X,Y,Z,red,green,blue);
467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
471 % C o n v e r t L C H u v T o R G B %
475 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
477 % ConvertLCHuvToRGB() transforms a (luma, chroma, hue) to a (red, green,
480 % The format of the ConvertLCHuvToRGBImage method is:
482 % void ConvertLCHuvToRGB(const double luma,const double chroma,
483 % const double hue,double *red,double *green,double *blue)
485 % A description of each parameter follows:
487 % o luma, chroma, hue: A double value representing a component of the
490 % o red, green, blue: A pointer to a pixel component of type Quantum.
493 MagickPrivate void ConvertLCHuvToRGB(const double luma,const double chroma,
494 const double hue,double *red,double *green,double *blue)
507 Convert LCHuv to RGB colorspace.
509 assert(red != (double *) NULL);
510 assert(green != (double *) NULL);
511 assert(blue != (double *) NULL);
515 u=C*cos(360.0*H*MagickPI/180.0)+(134.0/354.0);
516 v=C*sin(360.0*H*MagickPI/180.0)+(140.0/262.0);
517 ConvertLuvToXYZ(L,u,v,&X,&Y,&Z);
518 ConvertXYZToRGB(X,Y,Z,red,green,blue);
522 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
526 % C o n v e r t R G B T o H C L %
530 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
532 % ConvertRGBToHCL() transforms a (red, green, blue) to a (hue, chroma,
535 % The format of the ConvertRGBToHCL method is:
537 % void ConvertRGBToHCL(const double red,const double green,
538 % const double blue,double *hue,double *chroma,double *luma)
540 % A description of each parameter follows:
542 % o red, green, blue: A Quantum value representing the red, green, and
543 % blue component of a pixel.
545 % o hue, chroma, luma: A pointer to a double value representing a
546 % component of the HCL color space.
550 static inline double MagickMax(const double x,const double y)
557 static inline double MagickMin(const double x,const double y)
564 MagickPrivate void ConvertRGBToHCL(const double red,const double green,
565 const double blue,double *hue,double *chroma,double *luma)
576 Convert RGB to HCL colorspace.
578 assert(hue != (double *) NULL);
579 assert(chroma != (double *) NULL);
580 assert(luma != (double *) NULL);
584 max=MagickMax(r,MagickMax(g,b));
585 c=max-(double) MagickMin(r,MagickMin(g,b));
591 h=fmod((g-b)/c+6.0,6.0);
599 *chroma=QuantumScale*c;
600 *luma=QuantumScale*(0.298839f*r+0.586811f*g+0.114350f*b);
604 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
608 % C o n v e r t R G B T o H S B %
612 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
614 % ConvertRGBToHSB() transforms a (red, green, blue) to a (hue, saturation,
615 % brightness) triple.
617 % The format of the ConvertRGBToHSB method is:
619 % void ConvertRGBToHSB(const double red,const double green,
620 % const double blue,double *hue,double *saturation,double *brightness)
622 % A description of each parameter follows:
624 % o red, green, blue: A Quantum value representing the red, green, and
625 % blue component of a pixel..
627 % o hue, saturation, brightness: A pointer to a double value representing a
628 % component of the HSB color space.
631 MagickPrivate void ConvertRGBToHSB(const double red,const double green,
632 const double blue,double *hue,double *saturation,double *brightness)
643 Convert RGB to HSB colorspace.
645 assert(hue != (double *) NULL);
646 assert(saturation != (double *) NULL);
647 assert(brightness != (double *) NULL);
663 *saturation=delta/max;
664 *brightness=QuantumScale*max;
671 *hue=2.0+(b-r)/delta;
673 *hue=4.0+(r-g)/delta;
680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
684 % C o n v e r t R G B T o H S L %
688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
690 % ConvertRGBToHSL() transforms a (red, green, blue) to a (hue, saturation,
693 % The format of the ConvertRGBToHSL method is:
695 % void ConvertRGBToHSL(const double red,const double green,
696 % const double blue,double *hue,double *saturation,double *lightness)
698 % A description of each parameter follows:
700 % o red, green, blue: A Quantum value representing the red, green, and
701 % blue component of a pixel..
703 % o hue, saturation, lightness: A pointer to a double value representing a
704 % component of the HSL color space.
707 MagickExport void ConvertRGBToHSL(const double red,const double green,
708 const double blue,double *hue,double *saturation,double *lightness)
719 Convert RGB to HSL colorspace.
721 assert(hue != (double *) NULL);
722 assert(saturation != (double *) NULL);
723 assert(lightness != (double *) NULL);
725 g=QuantumScale*green;
727 max=MagickMax(r,MagickMax(g,b));
728 min=MagickMin(r,MagickMin(g,b));
729 *lightness=(double) ((min+max)/2.0);
737 if (*lightness < 0.5)
738 *saturation=(double) (delta/(min+max));
740 *saturation=(double) (delta/(2.0-max-min));
742 *hue=((((max-b)/6.0)+(delta/2.0))-(((max-g)/6.0)+(delta/2.0)))/delta;
745 *hue=(1.0/3.0)+((((max-r)/6.0)+(delta/2.0))-(((max-b)/6.0)+(delta/2.0)))/
749 *hue=(2.0/3.0)+((((max-g)/6.0)+(delta/2.0))-(((max-r)/6.0)+
758 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
762 % C o n v e r t R G B T o H W B %
766 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
768 % ConvertRGBToHWB() transforms a (red, green, blue) to a (hue, whiteness,
771 % The format of the ConvertRGBToHWB method is:
773 % void ConvertRGBToHWB(const double red,const double green,
774 % const double blue,double *hue,double *whiteness,double *blackness)
776 % A description of each parameter follows:
778 % o red, green, blue: A Quantum value representing the red, green, and
779 % blue component of a pixel.
781 % o hue, whiteness, blackness: A pointer to a double value representing a
782 % component of the HWB color space.
785 MagickPrivate void ConvertRGBToHWB(const double red,const double green,
786 const double blue,double *hue,double *whiteness,double *blackness)
798 Convert RGB to HWB colorspace.
800 assert(hue != (double *) NULL);
801 assert(whiteness != (double *) NULL);
802 assert(blackness != (double *) NULL);
806 w=MagickMin(r,MagickMin(g,b));
807 v=MagickMax(r,MagickMax(g,b));
808 *blackness=1.0-QuantumScale*v;
809 *whiteness=QuantumScale*w;
815 f=(r == w) ? g-b : ((g == w) ? b-r : r-g);
816 p=(r == w) ? 3.0 : ((g == w) ? 5.0 : 1.0);
817 *hue=(p-f/(v-1.0*w))/6.0;
821 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
825 % C o n v e r t R G B a b T o L C H %
829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
831 % ConvertRGBToLCHab() transforms a (red, green, blue) to a (luma, chroma,
834 % The format of the ConvertRGBToLCHab method is:
836 % void ConvertRGBToLCHab(const double red,const double green,
837 % const double blue,double *luma,double *chroma,double *hue)
839 % A description of each parameter follows:
841 % o red, green, blue: A Quantum value representing the red, green, and
842 % blue component of a pixel.
844 % o luma, chroma, hue: A pointer to a double value representing a
845 % component of the LCH color space.
848 MagickPrivate void ConvertRGBToLCHab(const double red,const double green,
849 const double blue,double *luma,double *chroma,double *hue)
862 Convert RGB to LCHab colorspace.
864 assert(luma != (double *) NULL);
865 assert(chroma != (double *) NULL);
866 assert(hue != (double *) NULL);
867 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
868 ConvertXYZToLab(X,Y,Z,&L,&a,&b);
870 H=180.0*atan2(b,a)/MagickPI/360.0;
881 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
885 % C o n v e r t R G B u v T o L C H %
889 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
891 % ConvertRGBToLCHuv() transforms a (red, green, blue) to a (luma, chroma,
894 % The format of the ConvertRGBToLCHuv method is:
896 % void ConvertRGBToLCHuv(const double red,const double green,
897 % const double blue,double *luma,double *chroma,double *hue)
899 % A description of each parameter follows:
901 % o red, green, blue: A Quantum value representing the red, green, and
902 % blue component of a pixel.
904 % o luma, chroma, hue: A pointer to a double value representing a
905 % component of the LCHuv color space.
908 MagickPrivate void ConvertRGBToLCHuv(const double red,const double green,
909 const double blue,double *luma,double *chroma,double *hue)
922 Convert RGB to LCHuv colorspace.
924 assert(luma != (double *) NULL);
925 assert(chroma != (double *) NULL);
926 assert(hue != (double *) NULL);
927 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
928 ConvertXYZToLuv(X,Y,Z,&L,&u,&v);
930 H=180.0*atan2(v,u)/MagickPI/360.0;
941 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
945 % E x p a n d A f f i n e %
949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
951 % ExpandAffine() computes the affine's expansion factor, i.e. the square root
952 % of the factor by which the affine transform affects area. In an affine
953 % transform composed of scaling, rotation, shearing, and translation, returns
954 % the amount of scaling.
956 % The format of the ExpandAffine method is:
958 % double ExpandAffine(const AffineMatrix *affine)
960 % A description of each parameter follows:
962 % o expansion: Method ExpandAffine returns the affine's expansion factor.
964 % o affine: A pointer the affine transform of type AffineMatrix.
967 MagickExport double ExpandAffine(const AffineMatrix *affine)
969 assert(affine != (const AffineMatrix *) NULL);
970 return(sqrt(fabs(affine->sx*affine->sy-affine->rx*affine->ry)));
974 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
978 % 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 %
982 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
984 % GenerateDifferentialNoise() generates differentual noise.
986 % The format of the GenerateDifferentialNoise method is:
988 % double GenerateDifferentialNoise(RandomInfo *random_info,
989 % const Quantum pixel,const NoiseType noise_type,const double attenuate)
991 % A description of each parameter follows:
993 % o random_info: the random info.
995 % o pixel: noise is relative to this pixel value.
997 % o noise_type: the type of noise.
999 % o attenuate: attenuate the noise.
1002 MagickPrivate double GenerateDifferentialNoise(RandomInfo *random_info,
1003 const Quantum pixel,const NoiseType noise_type,const double attenuate)
1005 #define SigmaUniform (attenuate*0.015625)
1006 #define SigmaGaussian (attenuate*0.015625)
1007 #define SigmaImpulse (attenuate*0.1)
1008 #define SigmaLaplacian (attenuate*0.0390625)
1009 #define SigmaMultiplicativeGaussian (attenuate*0.5)
1010 #define SigmaPoisson (attenuate*12.5)
1011 #define SigmaRandom (attenuate)
1012 #define TauGaussian (attenuate*0.078125)
1020 alpha=GetPseudoRandomValue(random_info);
1026 noise=(double) (pixel+QuantumRange*SigmaUniform*(alpha-0.5));
1037 beta=GetPseudoRandomValue(random_info);
1038 gamma=sqrt(-2.0*log(alpha));
1039 sigma=gamma*cos((double) (2.0*MagickPI*beta));
1040 tau=gamma*sin((double) (2.0*MagickPI*beta));
1041 noise=(double) (pixel+sqrt((double) pixel)*SigmaGaussian*sigma+
1042 QuantumRange*TauGaussian*tau);
1047 if (alpha < (SigmaImpulse/2.0))
1050 if (alpha >= (1.0-(SigmaImpulse/2.0)))
1051 noise=(double) QuantumRange;
1053 noise=(double) pixel;
1056 case LaplacianNoise:
1060 if (alpha <= MagickEpsilon)
1061 noise=(double) (pixel-QuantumRange);
1063 noise=(double) (pixel+QuantumRange*SigmaLaplacian*log(2.0*alpha)+
1068 if (beta <= (0.5*MagickEpsilon))
1069 noise=(double) (pixel+QuantumRange);
1071 noise=(double) (pixel-QuantumRange*SigmaLaplacian*log(2.0*beta)+0.5);
1074 case MultiplicativeGaussianNoise:
1077 if (alpha > MagickEpsilon)
1078 sigma=sqrt(-2.0*log(alpha));
1079 beta=GetPseudoRandomValue(random_info);
1080 noise=(double) (pixel+pixel*SigmaMultiplicativeGaussian*sigma*
1081 cos((double) (2.0*MagickPI*beta))/2.0);
1092 poisson=exp(-SigmaPoisson*QuantumScale*pixel);
1093 for (i=0; alpha > poisson; i++)
1095 beta=GetPseudoRandomValue(random_info);
1098 noise=(double) (QuantumRange*i/SigmaPoisson);
1103 noise=(double) (QuantumRange*SigmaRandom*alpha);
1111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1115 % G e t O p t i m a l K e r n e l W i d t h %
1119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1121 % GetOptimalKernelWidth() computes the optimal kernel radius for a convolution
1122 % filter. Start with the minimum value of 3 pixels and walk out until we drop
1123 % below the threshold of one pixel numerical accuracy.
1125 % The format of the GetOptimalKernelWidth method is:
1127 % size_t GetOptimalKernelWidth(const double radius,
1128 % const double sigma)
1130 % A description of each parameter follows:
1132 % o width: Method GetOptimalKernelWidth returns the optimal width of
1133 % a convolution kernel.
1135 % o radius: the radius of the Gaussian, in pixels, not counting the center
1138 % o sigma: the standard deviation of the Gaussian, in pixels.
1141 MagickPrivate size_t GetOptimalKernelWidth1D(const double radius,
1160 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1161 if (radius > MagickEpsilon)
1162 return((size_t) (2.0*ceil(radius)+1.0));
1164 if (gamma <= MagickEpsilon)
1166 alpha=PerceptibleReciprocal(2.0*gamma*gamma);
1167 beta=(double) PerceptibleReciprocal((double) MagickSQ2PI*gamma);
1171 j=(ssize_t) (width-1)/2;
1172 for (i=(-j); i <= j; i++)
1173 normalize+=exp(-((double) (i*i))*alpha)*beta;
1174 value=exp(-((double) (j*j))*alpha)*beta/normalize;
1175 if ((value < QuantumScale) || (value < MagickEpsilon))
1179 return((size_t) (width-2));
1182 MagickPrivate size_t GetOptimalKernelWidth2D(const double radius,
1200 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1201 if (radius > MagickEpsilon)
1202 return((size_t) (2.0*ceil(radius)+1.0));
1204 if (gamma <= MagickEpsilon)
1206 alpha=PerceptibleReciprocal(2.0*gamma*gamma);
1207 beta=(double) PerceptibleReciprocal((double) Magick2PI*gamma*gamma);
1211 j=(ssize_t) (width-1)/2;
1212 for (v=(-j); v <= j; v++)
1213 for (u=(-j); u <= j; u++)
1214 normalize+=exp(-((double) (u*u+v*v))*alpha)*beta;
1215 value=exp(-((double) (j*j))*alpha)*beta/normalize;
1216 if ((value < QuantumScale) || (value < MagickEpsilon))
1220 return((size_t) (width-2));
1223 MagickPrivate size_t GetOptimalKernelWidth(const double radius,
1226 return(GetOptimalKernelWidth1D(radius,sigma));