root / ImageMagick / branches / ImageMagick-6.3.5 / magick / gem.c

Revision 7952, 22.9 kB (checked in by cristy, 14 months ago)
Line 
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3%                                                                             %
4%                                                                             %
5%                                                                             %
6%                              GGGG  EEEEE  M   M                             %
7%                             G      E      MM MM                             %
8%                             G GG   EEE    M M M                             %
9%                             G   G  E      M   M                             %
10%                              GGGG  EEEEE  M   M                             %
11%                                                                             %
12%                                                                             %
13%                    Graphic Gems - Graphic Support Methods                   %
14%                                                                             %
15%                               Software Design                               %
16%                                 John Cristy                                 %
17%                                 August 1996                                 %
18%                                                                             %
19%                                                                             %
20%  Copyright 1999-2007 ImageMagick Studio LLC, a non-profit organization      %
21%  dedicated to making software imaging solutions freely available.           %
22%                                                                             %
23%  You may not use this file except in compliance with the License.  You may  %
24%  obtain a copy of the License at                                            %
25%                                                                             %
26%    http://www.imagemagick.org/script/license.php                            %
27%                                                                             %
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.                                             %
33%                                                                             %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37%
38*/
39
40/*
41  Include declarations.
42*/
43#include "magick/studio.h"
44#include "magick/color-private.h"
45#include "magick/draw.h"
46#include "magick/gem.h"
47#include "magick/image.h"
48#include "magick/image-private.h"
49#include "magick/log.h"
50#include "magick/memory_.h"
51#include "magick/pixel-private.h"
52#include "magick/quantum.h"
53#include "magick/random_.h"
54#include "magick/resize.h"
55#include "magick/transform.h"
56#include "magick/signature.h"
57
58/*
59%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60%                                                                             %
61%                                                                             %
62%                                                                             %
63%   C o n v e r t H S B T o R G B                                             %
64%                                                                             %
65%                                                                             %
66%                                                                             %
67%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
68%
69%  ConvertHSBToRGB() transforms a (hue, saturation, brightness) to a (red,
70%  green, blue) triple.
71%
72%  The format of the ConvertHSBToRGBImage method is:
73%
74%      void ConvertHSBToRGB(const double hue,const double saturation,
75%        const double brightness,Quantum *red,Quantum *green,Quantum *blue)
76%
77%  A description of each parameter follows:
78%
79%    o hue, saturation, brightness: A double value representing a
80%      component of the HSB color space.
81%
82%    o red, green, blue: A pointer to a pixel component of type Quantum.
83%
84*/
85MagickExport void ConvertHSBToRGB(const double hue,const double saturation,
86  const double brightness,Quantum *red,Quantum *green,Quantum *blue)
87{
88  MagickRealType
89    f,
90    h,
91    p,
92    q,
93    t;
94
95  /*
96    Convert HSB to RGB colorspace.
97  */
98  assert(red != (Quantum *) NULL);
99  assert(green != (Quantum *) NULL);
100  assert(blue != (Quantum *) NULL);
101  if (saturation == 0.0)
102    {
103      *red=RoundToQuantum((MagickRealType) QuantumRange*brightness);
104      *green=(*red);
105      *blue=(*red);
106      return;
107    }
108  h=6.0*(hue-floor(hue));
109  f=h-floor((double) h);
110  p=brightness*(1.0-saturation);
111  q=brightness*(1.0-saturation*f);
112  t=brightness*(1.0-(saturation*(1.0-f)));
113  switch ((int) h)
114  {
115    case 0:
116    default:
117    {
118      *red=RoundToQuantum((MagickRealType) QuantumRange*brightness);
119      *green=RoundToQuantum((MagickRealType) QuantumRange*t);
120      *blue=RoundToQuantum((MagickRealType) QuantumRange*p);
121      break;
122    }
123    case 1:
124    {
125      *red=RoundToQuantum((MagickRealType) QuantumRange*q);
126      *green=RoundToQuantum((MagickRealType) QuantumRange*brightness);
127      *blue=RoundToQuantum((MagickRealType) QuantumRange*p);
128      break;
129    }
130    case 2:
131    {
132      *red=RoundToQuantum((MagickRealType) QuantumRange*p);
133      *green=RoundToQuantum((MagickRealType) QuantumRange*brightness);
134      *blue=RoundToQuantum((MagickRealType) QuantumRange*t);
135      break;
136    }
137    case 3:
138    {
139      *red=RoundToQuantum((MagickRealType) QuantumRange*p);
140      *green=RoundToQuantum((MagickRealType) QuantumRange*q);
141      *blue=RoundToQuantum((MagickRealType) QuantumRange*brightness);
142      break;
143    }
144    case 4:
145    {
146      *red=RoundToQuantum((MagickRealType) QuantumRange*t);
147      *green=RoundToQuantum((MagickRealType) QuantumRange*p);
148      *blue=RoundToQuantum((MagickRealType) QuantumRange*brightness);
149      break;
150    }
151    case 5:
152    {
153      *red=RoundToQuantum((MagickRealType) QuantumRange*brightness);
154      *green=RoundToQuantum((MagickRealType) QuantumRange*p);
155      *blue=RoundToQuantum((MagickRealType) QuantumRange*q);
156      break;
157    }
158  }
159}
160
161/*
162%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
163%                                                                             %
164%                                                                             %
165%                                                                             %
166%   C o n v e r t H S L T o R G B                                             %
167%                                                                             %
168%                                                                             %
169%                                                                             %
170%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
171%
172%  ConvertHSLToRGB() transforms a (hue, saturation, luminosity) to a (red,
173%  green, blue) triple.
174%
175%  The format of the ConvertHSLToRGBImage method is:
176%
177%      void ConvertHSLToRGB(const double hue,const double saturation,
178%        const double luminosity,Quantum *red,Quantum *green,Quantum *blue)
179%
180%  A description of each parameter follows:
181%
182%    o hue, saturation, luminosity: A double value representing a
183%      component of the HSL color space.
184%
185%    o red, green, blue: A pointer to a pixel component of type Quantum.
186%
187*/
188
189static inline MagickRealType ConvertHueToRGB(MagickRealType m1,
190  MagickRealType m2,MagickRealType hue)
191{
192  if (hue < 0.0)
193    hue+=1.0;
194  if (hue > 1.0)
195    hue-=1.0;
196  if ((6.0*hue) < 1.0)
197    return(m1+6.0*(m2-m1)*hue);
198  if ((2.0*hue) < 1.0)
199    return(m2);
200  if ((3.0*hue) < 2.0)
201    return(m1+6.0*(m2-m1)*(2.0/3.0-hue));
202  return(m1);
203}
204
205MagickExport void ConvertHSLToRGB(const double hue,const double saturation,
206  const double luminosity,Quantum *red,Quantum *green,Quantum *blue)
207{
208  MagickRealType
209    b,
210    g,
211    r,
212    m1,
213    m2;
214
215  /*
216    Convert HSL to RGB colorspace.
217  */
218  assert(red != (Quantum *) NULL);
219  assert(green != (Quantum *) NULL);
220  assert(blue != (Quantum *) NULL);
221  if (saturation == 0)
222    {
223      *red=RoundToQuantum((MagickRealType) QuantumRange*luminosity);
224      *green=(*red);
225      *blue=(*red);
226      return;
227    }
228  if (luminosity <= 0.5)
229    m2=luminosity*(saturation+1.0);
230  else
231    m2=(luminosity+saturation)-(luminosity*saturation);
232  m1=2.0*luminosity-m2;
233  r=ConvertHueToRGB(m1,m2,hue+1.0/3.0);
234  g=ConvertHueToRGB(m1,m2,hue);
235  b=ConvertHueToRGB(m1,m2,hue-1.0/3.0);
236  *red=RoundToQuantum((MagickRealType) QuantumRange*r);
237  *green=RoundToQuantum((MagickRealType) QuantumRange*g);
238  *blue=RoundToQuantum((MagickRealType) QuantumRange*b);
239}
240
241/*
242%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
243%                                                                             %
244%                                                                             %
245%                                                                             %
246%   C o n v e r t H W B T o R G B                                             %
247%                                                                             %
248%                                                                             %
249%                                                                             %
250%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
251%
252%  ConvertHWBToRGB() transforms a (hue, whiteness, blackness) to a (red, green,
253%  blue) triple.
254%
255%  The format of the ConvertHWBToRGBImage method is:
256%
257%      void ConvertHWBToRGB(const double hue,const double whiteness,
258%        const double blackness,Quantum *red,Quantum *green,Quantum *blue)
259%
260%  A description of each parameter follows:
261%
262%    o hue, whiteness, blackness: A double value representing a
263%      component of the HWB color space.
264%
265%    o red, green, blue: A pointer to a pixel component of type Quantum.
266%
267*/
268MagickExport void ConvertHWBToRGB(const double hue,const double whiteness,
269  const double blackness,Quantum *red,Quantum *green,Quantum *blue)
270{
271  MagickRealType
272    b,
273    f,
274    g,
275    n,
276    r,
277    v;
278
279  register long
280    i;
281
282  /*
283    Convert HWB to RGB colorspace.
284  */
285  assert(red != (Quantum *) NULL);
286  assert(green != (Quantum *) NULL);
287  assert(blue != (Quantum *) NULL);
288  v=1.0-blackness;
289  if (hue == 0.0)
290    {
291      *red=RoundToQuantum((MagickRealType) QuantumRange*v);
292      *green=RoundToQuantum((MagickRealType) QuantumRange*v);
293      *blue=RoundToQuantum((MagickRealType) QuantumRange*v);
294      return;
295    }
296  i=(long) floor(6.0*hue);
297  f=6.0*hue-i;
298  if ((i & 0x01) != 0)
299    f=1.0-f;
300  n=whiteness+f*(v-whiteness);  /* linear interpolation */
301  switch (i)
302  {
303    default:
304    case 6:
305    case 0: r=v; g=n; b=whiteness; break;
306    case 1: r=n; g=v; b=whiteness; break;
307    case 2: r=whiteness; g=v; b=n; break;
308    case 3: r=whiteness; g=n; b=v; break;
309    case 4: r=n; g=whiteness; b=v; break;
310    case 5: r=v; g=whiteness; b=n; break;
311  }
312  *red=RoundToQuantum((MagickRealType) QuantumRange*r);
313  *green=RoundToQuantum((MagickRealType) QuantumRange*g);
314  *blue=RoundToQuantum((MagickRealType) QuantumRange*b);
315}
316
317/*
318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
319%                                                                             %
320%                                                                             %
321%                                                                             %
322%   C o n v e r t R G B T o H S B                                             %
323%                                                                             %
324%                                                                             %
325%                                                                             %
326%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
327%
328%  ConvertRGBToHSB() transforms a (red, green, blue) to a (hue, saturation,
329%  brightness) triple.
330%
331%  The format of the ConvertRGBToHSB method is:
332%
333%      void ConvertRGBToHSB(const Quantum red,const Quantum green,
334%        const Quantum blue,double *hue,double *saturation,double *brightness)
335%
336%  A description of each parameter follows:
337%
338%    o red, green, blue: A Quantum value representing the red, green, and
339%      blue component of a pixel..
340%
341%    o hue, saturation, brightness: A pointer to a double value representing a
342%      component of the HSB color space.
343%
344*/
345MagickExport void ConvertRGBToHSB(const Quantum red,const Quantum green,
346  const Quantum blue,double *hue,double *saturation,double *brightness)
347{
348  MagickRealType
349    delta,
350    max,
351    min;
352
353  /*
354    Convert RGB to HSB colorspace.
355  */
356  assert(hue != (double *) NULL);
357  assert(saturation != (double *) NULL);
358  assert(brightness != (double *) NULL);
359  max=(MagickRealType) (red > green ? red : green);
360  if ((MagickRealType) blue > max)
361    max=(MagickRealType) blue;
362  min=(MagickRealType) (red < green ? red : green);
363  if ((MagickRealType) blue < min)
364    min=(MagickRealType) blue;
365  *hue=0.0;
366  *saturation=0.0;
367  *brightness=(double) (QuantumScale*max);
368  if (max == 0.0)
369    return;
370  *saturation=(double) (1.0-min/max);
371  delta=max-min;
372  if (delta == 0.0)
373    return;
374  if ((MagickRealType) red == max)
375    *hue=(double) ((green-(MagickRealType) blue)/delta);
376  else
377    if ((MagickRealType) green == max)
378      *hue=(double) (2.0+(blue-(MagickRealType) red)/delta);
379    else
380      *hue=(double) (4.0+(red-(MagickRealType) green)/delta);
381  *hue/=6.0;
382  if (*hue < 0.0)
383    *hue+=1.0;
384}
385
386/*
387%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
388%                                                                             %
389%                                                                             %
390%                                                                             %
391%   C o n v e r t R G B T o H S L                                             %
392%                                                                             %
393%                                                                             %
394%                                                                             %
395%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
396%
397%  ConvertRGBToHSL() transforms a (red, green, blue) to a (hue, saturation,
398%  luminosity) triple.
399%
400%  The format of the ConvertRGBToHSL method is:
401%
402%      void ConvertRGBToHSL(const Quantum red,const Quantum green,
403%        const Quantum blue,double *hue,double *saturation,double *luminosity)
404%
405%  A description of each parameter follows:
406%
407%    o red, green, blue: A Quantum value representing the red, green, and
408%      blue component of a pixel..
409%
410%    o hue, saturation, luminosity: A pointer to a double value representing a
411%      component of the HSL color space.
412%
413*/
414
415static inline double MagickMax(const double x,const double y)
416{
417  if (x > y)
418    return(x);
419  return(y);
420}
421
422static inline double MagickMin(const double x,const double y)
423{
424  if (x < y)
425    return(x);
426  return(y);
427}
428
429MagickExport void ConvertRGBToHSL(const Quantum red,const Quantum green,
430  const Quantum blue,double *hue,double *saturation,double *luminosity)
431{
432  MagickRealType
433    b,
434    delta,
435    g,
436    max,
437    min,
438    r;
439
440  /*
441    Convert RGB to HSL colorspace.
442  */
443  assert(hue != (double *) NULL);
444  assert(saturation != (double *) NULL);
445  assert(luminosity != (double *) NULL);
446  r=QuantumScale*red;
447  g=QuantumScale*green;
448  b=QuantumScale*blue;
449  max=MagickMax(r,MagickMax(g,b));
450  min=MagickMin(r,MagickMin(g,b));
451  *luminosity=(double) ((min+max)/2.0);
452  delta=max-min;
453  if (delta == 0.0)
454    {
455      *hue=0.0;
456      *saturation=0.0;
457      return;
458    }
459  if (*luminosity < 0.5)
460    *saturation=(double) (delta/(min+max));
461  else
462    *saturation=(double) (delta/(2.0-max-min));
463  if (r == max)
464    *hue=((((max-b)/6.0)+(delta/2.0))-(((max-g)/6.0)+(delta/2.0)))/delta;
465  else
466    if (g == max)
467      *hue=(1.0/3.0)+((((max-r)/6.0)+(delta/2.0))-(((max-b)/6.0)+(delta/2.0)))/
468        delta;
469    else
470      if (b == max)
471        *hue=(2.0/3.0)+((((max-g)/6.0)+(delta/2.0))-(((max-r)/6.0)+
472          (delta/2.0)))/delta;
473  if (*hue < 0.0)
474    *hue+=1.0;
475  if (*hue > 1.0)
476    *hue-=1.0;
477}
478
479/*
480%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
481%                                                                             %
482%                                                                             %
483%                                                                             %
484%   C o n v e r t R G B T o H W B                                             %
485%                                                                             %
486%                                                                             %
487%                                                                             %
488%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
489%
490%  ConvertRGBToHWB() transforms a (red, green, blue) to a (hue, whiteness,
491%  blackness) triple.
492%
493%  The format of the ConvertRGBToHWB method is:
494%
495%      void ConvertRGBToHWB(const Quantum red,const Quantum green,
496%        const Quantum blue,double *hue,double *whiteness,double *blackness)
497%
498%  A description of each parameter follows:
499%
500%    o red, green, blue: A Quantum value representing the red, green, and
501%      blue component of a pixel.
502%
503%    o hue, whiteness, blackness: A pointer to a double value representing a
504%      component of the HWB color space.
505%
506*/
507MagickExport void ConvertRGBToHWB(const Quantum red,const Quantum green,
508  const Quantum blue,double *hue,double *whiteness,double *blackness)
509{
510  MagickRealType
511    f,
512    v,
513    w;
514
515  register long
516    i;
517
518  /*
519    Convert RGB to HWB colorspace.
520  */
521  assert(hue != (double *) NULL);
522  assert(whiteness != (double *) NULL);
523  assert(blackness != (double *) NULL);
524  w=(MagickRealType) MagickMin((double) red,MagickMin((double) green,(double)
525    blue));
526  v=(MagickRealType) MagickMax((double) red,MagickMax((double) green,(double)
527    blue));
528  *blackness=1.0-QuantumScale*v;
529  *whiteness=QuantumScale*w;
530  if (v == w)
531    {
532      *hue=0.0;
533      return;
534    }
535  f=((MagickRealType) red == w) ? green-(MagickRealType) blue :
536    (((MagickRealType) green == w) ? blue-(MagickRealType) red : red-
537    (MagickRealType) green);
538  i=((MagickRealType) red == w) ? 3 : (((MagickRealType) green == w) ? 5 : 1);
539  *hue=((double) i-f/(v-1.0*w))/6.0;
540}
541
542/*
543%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
544%                                                                             %
545%                                                                             %
546%                                                                             %
547%   E x p a n d A f f i n e                                                   %
548%                                                                             %
549%                                                                             %
550%                                                                             %
551%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
552%
553%  ExpandAffine() computes the affine's expansion factor, i.e. the square root
554%  of the factor by which the affine transform affects area. In an affine
555%  transform composed of scaling, rotation, shearing, and translation, returns
556%  the amount of scaling.
557%
558%  The format of the ExpandAffine method is:
559%
560%      double ExpandAffine(const AffineMatrix *affine)
561%
562%  A description of each parameter follows:
563%
564%    o expansion: Method ExpandAffine returns the affine's expansion factor.
565%
566%    o affine: A pointer the the affine transform of type AffineMatrix.
567%
568*/
569MagickExport double ExpandAffine(const AffineMatrix *affine)
570{
571  assert(affine != (const AffineMatrix *) NULL);
572  return(sqrt(fabs(affine->sx*affine->sy-affine->rx*affine->ry)));
573}
574
575/*
576%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
577%                                                                             %
578%                                                                             %
579%                                                                             %
580%   G e t O p t i m a l K e r n e l W i d t h                                 %
581%                                                                             %
582%                                                                             %
583%                                                                             %
584%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
585%
586%  GetOptimalKernelWidth() computes the optimal kernel radius for a convolution
587%  filter.  Start with the minimum value of 3 pixels and walk out until we drop
588%  below the threshold of one pixel numerical accuracy.
589%
590%  The format of the GetOptimalKernelWidth method is:
591%
592%      unsigned long GetOptimalKernelWidth(const double radius,
593%        const double sigma)
594%
595%  A description of each parameter follows:
596%
597%    o width: Method GetOptimalKernelWidth returns the optimal width of
598%      a convolution kernel.
599%
600%    o radius: The radius of the Gaussian, in pixels, not counting the center
601%      pixel.
602%
603%    o sigma: The standard deviation of the Gaussian, in pixels.
604%
605*/
606MagickExport unsigned long GetOptimalKernelWidth1D(const double radius,
607  const double sigma)
608{
609  long
610    width;
611
612  MagickRealType
613    normalize,
614    value;
615
616  register long
617    u;
618
619  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
620  if (radius > 0.0)
621    return((unsigned long) (2.0*ceil(radius)+1.0));
622  if (fabs(sigma) <= MagickEpsilon)
623    return(1);
624  for (width=5; ;)
625  {
626    normalize=0.0;
627    for (u=(-width/2); u <= (width/2); u++)
628      normalize+=exp(-((double) u*u)/(2.0*sigma*sigma))/(MagickSQ2PI*sigma);
629    u=width/2;
630    value=exp(-((double) u*u)/(2.0*sigma*sigma))/(MagickSQ2PI*sigma)/normalize;
631    if ((long) (QuantumRange*value) <= 0L)
632      break;
633    width+=2;
634  }
635  return((unsigned long) (width-2));
636}
637
638MagickExport unsigned long GetOptimalKernelWidth2D(const double radius,
639  const double sigma)
640{
641
642  long
643    width;
644
645  MagickRealType
646    alpha,
647    normalize,
648    value;
649
650  register long
651    u,
652    v;
653
654  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
655  if (radius > 0.0)
656    return((unsigned long) (2.0*ceil(radius)+1.0));
657  if (fabs(sigma) <= MagickEpsilon)
658    return(1);
659  for (width=5; ;)
660  {
661    normalize=0.0;
662    for (v=(-width/2); v <= (width/2); v++)
663    {
664      for (u=(-width/2); u <= (width/2); u++)
665      {
666        alpha=exp(-((double) u*u+v*v)/(2.0*sigma*sigma));
667        normalize+=alpha/(2.0*MagickPI*sigma*sigma);
668      }
669    }
670    v=width/2;
671    value=exp(-((double) v*v)/(2.0*sigma*sigma))/(MagickSQ2PI*sigma)/normalize;
672    if ((long) (QuantumRange*value) <= 0L)
673      break;
674    width+=2;
675  }
676  return((unsigned long) (width-2));
677}
678
679MagickExport unsigned long  GetOptimalKernelWidth(const double radius,
680  const double sigma)
681{
682  return(GetOptimalKernelWidth1D(radius,sigma));
683}
Note: See TracBrowser for help on using the browser.