]> granicus.if.org Git - imagemagick/blob - MagickCore/gem.c
(no commit message)
[imagemagick] / MagickCore / gem.c
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-2013 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 \f
40 /*
41   Include declarations.
42 */
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"
60 \f
61 /*
62 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63 %                                                                             %
64 %                                                                             %
65 %                                                                             %
66 %   C o n v e r t H C L T o R G B                                             %
67 %                                                                             %
68 %                                                                             %
69 %                                                                             %
70 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
71 %
72 %  ConvertHCLToRGB() transforms a (hue, chroma, luma) to a (red, green,
73 %  blue) triple.
74 %
75 %  The format of the ConvertHCLToRGBImage method is:
76 %
77 %      void ConvertHCLToRGB(const double hue,const double chroma,
78 %        const double luma,double *red,double *green,double *blue)
79 %
80 %  A description of each parameter follows:
81 %
82 %    o hue, chroma, luma: A double value representing a
83 %      component of the HCL color space.
84 %
85 %    o red, green, blue: A pointer to a pixel component of type Quantum.
86 %
87 */
88 MagickPrivate void ConvertHCLToRGB(const double hue,const double chroma,
89   const double luma,double *red,double *green,double *blue)
90 {
91   double
92     C,
93     H,
94     L,
95     u,
96     v,
97     X,
98     Y,
99     Z;
100
101   /*
102     Convert HCL to RGB colorspace.
103   */
104   assert(red != (double *) NULL);
105   assert(green != (double *) NULL);
106   assert(blue != (double *) NULL);
107   L=luma;
108   C=chroma;
109   H=hue;
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);
114 }
115 \f
116 /*
117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
118 %                                                                             %
119 %                                                                             %
120 %                                                                             %
121 %   C o n v e r t H S B T o R G B                                             %
122 %                                                                             %
123 %                                                                             %
124 %                                                                             %
125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126 %
127 %  ConvertHSBToRGB() transforms a (hue, saturation, brightness) to a (red,
128 %  green, blue) triple.
129 %
130 %  The format of the ConvertHSBToRGBImage method is:
131 %
132 %      void ConvertHSBToRGB(const double hue,const double saturation,
133 %        const double brightness,double *red,double *green,double *blue)
134 %
135 %  A description of each parameter follows:
136 %
137 %    o hue, saturation, brightness: A double value representing a
138 %      component of the HSB color space.
139 %
140 %    o red, green, blue: A pointer to a pixel component of type Quantum.
141 %
142 */
143 MagickPrivate void ConvertHSBToRGB(const double hue,const double saturation,
144   const double brightness,double *red,double *green,double *blue)
145 {
146   double
147     f,
148     h,
149     p,
150     q,
151     t;
152
153   /*
154     Convert HSB to RGB colorspace.
155   */
156   assert(red != (double *) NULL);
157   assert(green != (double *) NULL);
158   assert(blue != (double *) NULL);
159   if (saturation == 0.0)
160     {
161       *red=QuantumRange*brightness;
162       *green=(*red);
163       *blue=(*red);
164       return;
165     }
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)));
171   switch ((int) h)
172   {
173     case 0:
174     default:
175     {
176       *red=QuantumRange*brightness;
177       *green=QuantumRange*t;
178       *blue=QuantumRange*p;
179       break;
180     }
181     case 1:
182     {
183       *red=QuantumRange*q;
184       *green=QuantumRange*brightness;
185       *blue=QuantumRange*p;
186       break;
187     }
188     case 2:
189     {
190       *red=QuantumRange*p;
191       *green=QuantumRange*brightness;
192       *blue=QuantumRange*t;
193       break;
194     }
195     case 3:
196     {
197       *red=QuantumRange*p;
198       *green=QuantumRange*q;
199       *blue=QuantumRange*brightness;
200       break;
201     }
202     case 4:
203     {
204       *red=QuantumRange*t;
205       *green=QuantumRange*p;
206       *blue=QuantumRange*brightness;
207       break;
208     }
209     case 5:
210     {
211       *red=QuantumRange*brightness;
212       *green=QuantumRange*p;
213       *blue=QuantumRange*q;
214       break;
215     }
216   }
217 }
218 \f
219 /*
220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221 %                                                                             %
222 %                                                                             %
223 %                                                                             %
224 %   C o n v e r t H S L T o R G B                                             %
225 %                                                                             %
226 %                                                                             %
227 %                                                                             %
228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
229 %
230 %  ConvertHSLToRGB() transforms a (hue, saturation, lightness) to a (red,
231 %  green, blue) triple.
232 %
233 %  The format of the ConvertHSLToRGBImage method is:
234 %
235 %      void ConvertHSLToRGB(const double hue,const double saturation,
236 %        const double lightness,double *red,double *green,double *blue)
237 %
238 %  A description of each parameter follows:
239 %
240 %    o hue, saturation, lightness: A double value representing a
241 %      component of the HSL color space.
242 %
243 %    o red, green, blue: A pointer to a pixel component of type Quantum.
244 %
245 */
246
247 static inline double ConvertHueToRGB(double m1,double m2,double hue)
248 {
249   if (hue < 0.0)
250     hue+=1.0;
251   if (hue >= 1.0)
252     hue-=1.0;
253   if ((6.0*hue) < 1.0)
254     return(m1+6.0*(m2-m1)*hue);
255   if ((2.0*hue) < 1.0)
256     return(m2);
257   if ((3.0*hue) < 2.0)
258     return(m1+6.0*(m2-m1)*(2.0/3.0-hue));
259   return(m1);
260 }
261
262 MagickExport void ConvertHSLToRGB(const double hue,const double saturation,
263   const double lightness,double *red,double *green,double *blue)
264 {
265   double
266     b,
267     g,
268     r,
269     m1,
270     m2;
271
272   /*
273     Convert HSL to RGB colorspace.
274   */
275   assert(red != (double *) NULL);
276   assert(green != (double *) NULL);
277   assert(blue != (double *) NULL);
278   if (saturation == 0)
279     {
280       *red=QuantumRange*lightness;
281       *green=(*red);
282       *blue=(*red);
283       return;
284     }
285   if (lightness < 0.5)
286     m2=lightness*(saturation+1.0);
287   else
288     m2=(lightness+saturation)-(lightness*saturation);
289   m1=2.0*lightness-m2;
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);
293   *red=QuantumRange*r;
294   *green=QuantumRange*g;
295   *blue=QuantumRange*b;
296 }
297 \f
298 /*
299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
300 %                                                                             %
301 %                                                                             %
302 %                                                                             %
303 %   C o n v e r t H W B T o R G B                                             %
304 %                                                                             %
305 %                                                                             %
306 %                                                                             %
307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
308 %
309 %  ConvertHWBToRGB() transforms a (hue, whiteness, blackness) to a (red, green,
310 %  blue) triple.
311 %
312 %  The format of the ConvertHWBToRGBImage method is:
313 %
314 %      void ConvertHWBToRGB(const double hue,const double whiteness,
315 %        const double blackness,double *red,double *green,double *blue)
316 %
317 %  A description of each parameter follows:
318 %
319 %    o hue, whiteness, blackness: A double value representing a
320 %      component of the HWB color space.
321 %
322 %    o red, green, blue: A pointer to a pixel component of type Quantum.
323 %
324 */
325 MagickPrivate void ConvertHWBToRGB(const double hue,const double whiteness,
326   const double blackness,double *red,double *green,double *blue)
327 {
328   double
329     b,
330     f,
331     g,
332     n,
333     r,
334     v;
335
336   register ssize_t
337     i;
338
339   /*
340     Convert HWB to RGB colorspace.
341   */
342   assert(red != (double *) NULL);
343   assert(green != (double *) NULL);
344   assert(blue != (double *) NULL);
345   v=1.0-blackness;
346   if (hue == -1.0)
347     {
348       *red=QuantumRange*v;
349       *green=QuantumRange*v;
350       *blue=QuantumRange*v;
351       return;
352     }
353   i=(ssize_t) floor(6.0*hue);
354   f=6.0*hue-i;
355   if ((i & 0x01) != 0)
356     f=1.0-f;
357   n=whiteness+f*(v-whiteness);  /* linear interpolation */
358   switch (i)
359   {
360     default:
361     case 6:
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;
368   }
369   *red=QuantumRange*r;
370   *green=QuantumRange*g;
371   *blue=QuantumRange*b;
372 }
373 \f
374 /*
375 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
376 %                                                                             %
377 %                                                                             %
378 %                                                                             %
379 %   C o n v e r t L C H a b T o R G B                                         %
380 %                                                                             %
381 %                                                                             %
382 %                                                                             %
383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
384 %
385 %  ConvertLCHabToRGB() transforms a (luma, chroma, hue) to a (red, green,
386 %  blue) triple.
387 %
388 %  The format of the ConvertLCHabToRGBImage method is:
389 %
390 %      void ConvertLCHabToRGB(const double luma,const double chroma,
391 %        const double hue,double *red,double *green,double *blue)
392 %
393 %  A description of each parameter follows:
394 %
395 %    o luma, chroma, hue: A double value representing a component of the
396 %      LCHab color space.
397 %
398 %    o red, green, blue: A pointer to a pixel component of type Quantum.
399 %
400 */
401 MagickPrivate void ConvertLCHabToRGB(const double luma,const double chroma,
402   const double hue,double *red,double *green,double *blue)
403 {
404   double
405     a,
406     b,
407     C,
408     H,
409     L,
410     X,
411     Y,
412     Z;
413
414   /*
415     Convert LCHab to RGB colorspace.
416   */
417   assert(red != (double *) NULL);
418   assert(green != (double *) NULL);
419   assert(blue != (double *) NULL);
420   L=luma;
421   C=chroma;
422   H=hue;
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);
427 }
428 \f
429 /*
430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
431 %                                                                             %
432 %                                                                             %
433 %                                                                             %
434 %   C o n v e r t L C H u v T o R G B                                         %
435 %                                                                             %
436 %                                                                             %
437 %                                                                             %
438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
439 %
440 %  ConvertLCHuvToRGB() transforms a (luma, chroma, hue) to a (red, green,
441 %  blue) triple.
442 %
443 %  The format of the ConvertLCHuvToRGBImage method is:
444 %
445 %      void ConvertLCHuvToRGB(const double luma,const double chroma,
446 %        const double hue,double *red,double *green,double *blue)
447 %
448 %  A description of each parameter follows:
449 %
450 %    o luma, chroma, hue: A double value representing a component of the
451 %      LCHuv color space.
452 %
453 %    o red, green, blue: A pointer to a pixel component of type Quantum.
454 %
455 */
456 MagickPrivate void ConvertLCHuvToRGB(const double luma,const double chroma,
457   const double hue,double *red,double *green,double *blue)
458 {
459   double
460     C,
461     H,
462     L,
463     u,
464     v,
465     X,
466     Y,
467     Z;
468
469   /*
470     Convert LCHuv to RGB colorspace.
471   */
472   assert(red != (double *) NULL);
473   assert(green != (double *) NULL);
474   assert(blue != (double *) NULL);
475   L=luma;
476   C=chroma;
477   H=hue;
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);
482 }
483 \f
484 /*
485 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
486 %                                                                             %
487 %                                                                             %
488 %                                                                             %
489 %   C o n v e r t R G B T o H C L                                             %
490 %                                                                             %
491 %                                                                             %
492 %                                                                             %
493 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
494 %
495 %  ConvertRGBToHCL() transforms a (red, green, blue) to a (hue, chroma,
496 %  luma) triple.
497 %
498 %  The format of the ConvertRGBToHCL method is:
499 %
500 %      void ConvertRGBToHCL(const double red,const double green,
501 %        const double blue,double *hue,double *chroma,double *luma)
502 %
503 %  A description of each parameter follows:
504 %
505 %    o red, green, blue: A Quantum value representing the red, green, and
506 %      blue component of a pixel.
507 %
508 %    o hue, chroma, luma: A pointer to a double value representing a
509 %      component of the HCL color space.
510 %
511 */
512 MagickPrivate void ConvertRGBToHCL(const double red,const double green,
513   const double blue,double *hue,double *chroma,double *luma)
514 {
515   double
516     C,
517     H,
518     L,
519     u,
520     v,
521     X,
522     Y,
523     Z;
524
525   /*
526     Convert RGB to HCL colorspace.
527   */
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;
535   if (H < 0.0)
536     H+=1.0;
537   if (H >= 1.0)
538     H-=1.0;
539   *luma=L;
540   *chroma=C;
541   *hue=H;
542 }
543 \f
544 /*
545 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
546 %                                                                             %
547 %                                                                             %
548 %                                                                             %
549 %   C o n v e r t R G B T o H S B                                             %
550 %                                                                             %
551 %                                                                             %
552 %                                                                             %
553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
554 %
555 %  ConvertRGBToHSB() transforms a (red, green, blue) to a (hue, saturation,
556 %  brightness) triple.
557 %
558 %  The format of the ConvertRGBToHSB method is:
559 %
560 %      void ConvertRGBToHSB(const double red,const double green,
561 %        const double blue,double *hue,double *saturation,double *brightness)
562 %
563 %  A description of each parameter follows:
564 %
565 %    o red, green, blue: A Quantum value representing the red, green, and
566 %      blue component of a pixel..
567 %
568 %    o hue, saturation, brightness: A pointer to a double value representing a
569 %      component of the HSB color space.
570 %
571 */
572 MagickPrivate void ConvertRGBToHSB(const double red,const double green,
573   const double blue,double *hue,double *saturation,double *brightness)
574 {
575   double
576     b,
577     delta,
578     g,
579     max,
580     min,
581     r;
582
583   /*
584     Convert RGB to HSB colorspace.
585   */
586   assert(hue != (double *) NULL);
587   assert(saturation != (double *) NULL);
588   assert(brightness != (double *) NULL);
589   *hue=0.0;
590   *saturation=0.0;
591   *brightness=0.0;
592   r=red;
593   g=green;
594   b=blue;
595   min=r < g ? r : g;
596   if (b < min)
597     min=b;
598   max=r > g ? r : g;
599   if (b > max)
600     max=b;
601   if (max == 0.0)
602     return;
603   delta=max-min;
604   *saturation=delta/max;
605   *brightness=QuantumScale*max;
606   if (delta == 0.0)
607     return;
608   if (r == max)
609     *hue=(g-b)/delta;
610   else
611     if (g == max)
612       *hue=2.0+(b-r)/delta;
613     else
614       *hue=4.0+(r-g)/delta;
615   *hue/=6.0;
616   if (*hue < 0.0)
617     *hue+=1.0;
618 }
619 \f
620 /*
621 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
622 %                                                                             %
623 %                                                                             %
624 %                                                                             %
625 %   C o n v e r t R G B T o H S L                                             %
626 %                                                                             %
627 %                                                                             %
628 %                                                                             %
629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
630 %
631 %  ConvertRGBToHSL() transforms a (red, green, blue) to a (hue, saturation,
632 %  lightness) triple.
633 %
634 %  The format of the ConvertRGBToHSL method is:
635 %
636 %      void ConvertRGBToHSL(const double red,const double green,
637 %        const double blue,double *hue,double *saturation,double *lightness)
638 %
639 %  A description of each parameter follows:
640 %
641 %    o red, green, blue: A Quantum value representing the red, green, and
642 %      blue component of a pixel..
643 %
644 %    o hue, saturation, lightness: A pointer to a double value representing a
645 %      component of the HSL color space.
646 %
647 */
648
649 static inline double MagickMax(const double x,const double y)
650 {
651   if (x > y)
652     return(x);
653   return(y);
654 }
655
656 static inline double MagickMin(const double x,const double y)
657 {
658   if (x < y)
659     return(x);
660   return(y);
661 }
662
663 MagickExport void ConvertRGBToHSL(const double red,const double green,
664   const double blue,double *hue,double *saturation,double *lightness)
665 {
666   double
667     b,
668     delta,
669     g,
670     max,
671     min,
672     r;
673
674   /*
675     Convert RGB to HSL colorspace.
676   */
677   assert(hue != (double *) NULL);
678   assert(saturation != (double *) NULL);
679   assert(lightness != (double *) NULL);
680   r=QuantumScale*red;
681   g=QuantumScale*green;
682   b=QuantumScale*blue;
683   max=MagickMax(r,MagickMax(g,b));
684   min=MagickMin(r,MagickMin(g,b));
685   *lightness=(double) ((min+max)/2.0);
686   delta=max-min;
687   if (delta == 0.0)
688     {
689       *hue=0.0;
690       *saturation=0.0;
691       return;
692     }
693   if (*lightness < 0.5)
694     *saturation=(double) (delta/(min+max));
695   else
696     *saturation=(double) (delta/(2.0-max-min));
697   if (r == max)
698     *hue=((((max-b)/6.0)+(delta/2.0))-(((max-g)/6.0)+(delta/2.0)))/delta;
699   else
700     if (g == max)
701       *hue=(1.0/3.0)+((((max-r)/6.0)+(delta/2.0))-(((max-b)/6.0)+(delta/2.0)))/
702         delta;
703     else
704       if (b == max)
705         *hue=(2.0/3.0)+((((max-g)/6.0)+(delta/2.0))-(((max-r)/6.0)+
706           (delta/2.0)))/delta;
707   if (*hue < 0.0)
708     *hue+=1.0;
709   if (*hue >= 1.0)
710     *hue-=1.0;
711 }
712 \f
713 /*
714 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
715 %                                                                             %
716 %                                                                             %
717 %                                                                             %
718 %   C o n v e r t R G B T o H W B                                             %
719 %                                                                             %
720 %                                                                             %
721 %                                                                             %
722 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
723 %
724 %  ConvertRGBToHWB() transforms a (red, green, blue) to a (hue, whiteness,
725 %  blackness) triple.
726 %
727 %  The format of the ConvertRGBToHWB method is:
728 %
729 %      void ConvertRGBToHWB(const double red,const double green,
730 %        const double blue,double *hue,double *whiteness,double *blackness)
731 %
732 %  A description of each parameter follows:
733 %
734 %    o red, green, blue: A Quantum value representing the red, green, and
735 %      blue component of a pixel.
736 %
737 %    o hue, whiteness, blackness: A pointer to a double value representing a
738 %      component of the HWB color space.
739 %
740 */
741 MagickPrivate void ConvertRGBToHWB(const double red,const double green,
742   const double blue,double *hue,double *whiteness,double *blackness)
743 {
744   double
745     b,
746     f,
747     g,
748     p,
749     r,
750     v,
751     w;
752
753   /*
754     Convert RGB to HWB colorspace.
755   */
756   assert(hue != (double *) NULL);
757   assert(whiteness != (double *) NULL);
758   assert(blackness != (double *) NULL);
759   r=red;
760   g=green;
761   b=blue;
762   w=MagickMin(r,MagickMin(g,b));
763   v=MagickMax(r,MagickMax(g,b));
764   *blackness=1.0-QuantumScale*v;
765   *whiteness=QuantumScale*w;
766   if (v == w)
767     {
768       *hue=(-1.0);
769       return;
770     }
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;
774 }
775 \f
776 /*
777 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
778 %                                                                             %
779 %                                                                             %
780 %                                                                             %
781 %   C o n v e r t R G B a b T o L C H                                         %
782 %                                                                             %
783 %                                                                             %
784 %                                                                             %
785 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
786 %
787 %  ConvertRGBToLCHab() transforms a (red, green, blue) to a (luma, chroma,
788 %  hue) triple.
789 %
790 %  The format of the ConvertRGBToLCHab method is:
791 %
792 %      void ConvertRGBToLCHab(const double red,const double green,
793 %        const double blue,double *luma,double *chroma,double *hue)
794 %
795 %  A description of each parameter follows:
796 %
797 %    o red, green, blue: A Quantum value representing the red, green, and
798 %      blue component of a pixel.
799 %
800 %    o luma, chroma, hue: A pointer to a double value representing a
801 %      component of the LCH color space.
802 %
803 */
804 MagickPrivate void ConvertRGBToLCHab(const double red,const double green,
805   const double blue,double *luma,double *chroma,double *hue)
806 {
807   double
808     a,
809     b,
810     C,
811     H,
812     L,
813     X,
814     Y,
815     Z;
816
817   /*
818     Convert RGB to LCHab colorspace.
819   */
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;
827   if (H < 0.0)
828     H+=1.0;
829   if (H >= 1.0)
830     H-=1.0;
831   *luma=L;
832   *chroma=C;
833   *hue=H;
834 }
835 \f
836 /*
837 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
838 %                                                                             %
839 %                                                                             %
840 %                                                                             %
841 %   C o n v e r t R G B u v T o L C H                                         %
842 %                                                                             %
843 %                                                                             %
844 %                                                                             %
845 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
846 %
847 %  ConvertRGBToLCHuv() transforms a (red, green, blue) to a (luma, chroma,
848 %  hue) triple.
849 %
850 %  The format of the ConvertRGBToLCHuv method is:
851 %
852 %      void ConvertRGBToLCHuv(const double red,const double green,
853 %        const double blue,double *luma,double *chroma,double *hue)
854 %
855 %  A description of each parameter follows:
856 %
857 %    o red, green, blue: A Quantum value representing the red, green, and
858 %      blue component of a pixel.
859 %
860 %    o luma, chroma, hue: A pointer to a double value representing a
861 %      component of the LCHuv color space.
862 %
863 */
864 MagickPrivate void ConvertRGBToLCHuv(const double red,const double green,
865   const double blue,double *luma,double *chroma,double *hue)
866 {
867   double
868     C,
869     H,
870     L,
871     u,
872     v,
873     X,
874     Y,
875     Z;
876
877   /*
878     Convert RGB to LCHuv colorspace.
879   */
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;
887   if (H < 0.0)
888     H+=1.0;
889   if (H >= 1.0)
890     H-=1.0;
891   *luma=L;
892   *chroma=C;
893   *hue=H;
894 }
895 \f
896 /*
897 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
898 %                                                                             %
899 %                                                                             %
900 %                                                                             %
901 %   E x p a n d A f f i n e                                                   %
902 %                                                                             %
903 %                                                                             %
904 %                                                                             %
905 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
906 %
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.
911 %
912 %  The format of the ExpandAffine method is:
913 %
914 %      double ExpandAffine(const AffineMatrix *affine)
915 %
916 %  A description of each parameter follows:
917 %
918 %    o expansion: Method ExpandAffine returns the affine's expansion factor.
919 %
920 %    o affine: A pointer the affine transform of type AffineMatrix.
921 %
922 */
923 MagickExport double ExpandAffine(const AffineMatrix *affine)
924 {
925   assert(affine != (const AffineMatrix *) NULL);
926   return(sqrt(fabs(affine->sx*affine->sy-affine->rx*affine->ry)));
927 }
928 \f
929 /*
930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
931 %                                                                             %
932 %                                                                             %
933 %                                                                             %
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                         %
935 %                                                                             %
936 %                                                                             %
937 %                                                                             %
938 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
939 %
940 %  GenerateDifferentialNoise() generates differentual noise.
941 %
942 %  The format of the GenerateDifferentialNoise method is:
943 %
944 %      double GenerateDifferentialNoise(RandomInfo *random_info,
945 %        const Quantum pixel,const NoiseType noise_type,const double attenuate)
946 %
947 %  A description of each parameter follows:
948 %
949 %    o random_info: the random info.
950 %
951 %    o pixel: noise is relative to this pixel value.
952 %
953 %    o noise_type: the type of noise.
954 %
955 %    o attenuate:  attenuate the noise.
956 %
957 */
958 MagickPrivate double GenerateDifferentialNoise(RandomInfo *random_info,
959   const Quantum pixel,const NoiseType noise_type,const double attenuate)
960 {
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)
969
970   double
971     alpha,
972     beta,
973     noise,
974     sigma;
975
976   alpha=GetPseudoRandomValue(random_info);
977   switch (noise_type)
978   {
979     case UniformNoise:
980     default:
981     {
982       noise=(double) (pixel+QuantumRange*SigmaUniform*(alpha-0.5));
983       break;
984     }
985     case GaussianNoise:
986     {
987       double
988         gamma,
989         tau;
990
991       if (alpha == 0.0)
992         alpha=1.0;
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);
999       break;
1000     }
1001     case ImpulseNoise:
1002     {
1003       if (alpha < (SigmaImpulse/2.0))
1004         noise=0.0;
1005       else
1006         if (alpha >= (1.0-(SigmaImpulse/2.0)))
1007           noise=(double) QuantumRange;
1008         else
1009           noise=(double) pixel;
1010       break;
1011     }
1012     case LaplacianNoise:
1013     {
1014       if (alpha <= 0.5)
1015         {
1016           if (alpha <= MagickEpsilon)
1017             noise=(double) (pixel-QuantumRange);
1018           else
1019             noise=(double) (pixel+QuantumRange*SigmaLaplacian*log(2.0*alpha)+
1020               0.5);
1021           break;
1022         }
1023       beta=1.0-alpha;
1024       if (beta <= (0.5*MagickEpsilon))
1025         noise=(double) (pixel+QuantumRange);
1026       else
1027         noise=(double) (pixel-QuantumRange*SigmaLaplacian*log(2.0*beta)+0.5);
1028       break;
1029     }
1030     case MultiplicativeGaussianNoise:
1031     {
1032       sigma=1.0;
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);
1038       break;
1039     }
1040     case PoissonNoise:
1041     {
1042       double
1043         poisson;
1044
1045       register ssize_t
1046         i;
1047
1048       poisson=exp(-SigmaPoisson*QuantumScale*pixel);
1049       for (i=0; alpha > poisson; i++)
1050       {
1051         beta=GetPseudoRandomValue(random_info);
1052         alpha*=beta;
1053       }
1054       noise=(double) (QuantumRange*i/SigmaPoisson);
1055       break;
1056     }
1057     case RandomNoise:
1058     {
1059       noise=(double) (QuantumRange*SigmaRandom*alpha);
1060       break;
1061     }
1062   }
1063   return(noise);
1064 }
1065 \f
1066 /*
1067 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1068 %                                                                             %
1069 %                                                                             %
1070 %                                                                             %
1071 %   G e t O p t i m a l K e r n e l W i d t h                                 %
1072 %                                                                             %
1073 %                                                                             %
1074 %                                                                             %
1075 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1076 %
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.
1080 %
1081 %  The format of the GetOptimalKernelWidth method is:
1082 %
1083 %      size_t GetOptimalKernelWidth(const double radius,
1084 %        const double sigma)
1085 %
1086 %  A description of each parameter follows:
1087 %
1088 %    o width: Method GetOptimalKernelWidth returns the optimal width of
1089 %      a convolution kernel.
1090 %
1091 %    o radius: the radius of the Gaussian, in pixels, not counting the center
1092 %      pixel.
1093 %
1094 %    o sigma: the standard deviation of the Gaussian, in pixels.
1095 %
1096 */
1097 MagickPrivate size_t GetOptimalKernelWidth1D(const double radius,
1098   const double sigma)
1099 {
1100   double
1101     alpha,
1102     beta,
1103     gamma,
1104     normalize,
1105     value;
1106
1107   register ssize_t
1108     i;
1109
1110   size_t
1111     width;
1112
1113   ssize_t
1114     j;
1115
1116   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1117   if (radius > MagickEpsilon)
1118     return((size_t) (2.0*ceil(radius)+1.0));
1119   gamma=fabs(sigma);
1120   if (gamma <= MagickEpsilon)
1121     return(3UL);
1122   alpha=PerceptibleReciprocal(2.0*gamma*gamma);
1123   beta=(double) PerceptibleReciprocal((double) MagickSQ2PI*gamma);
1124   for (width=5; ; )
1125   {
1126     normalize=0.0;
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))
1132       break;
1133     width+=2;
1134   }
1135   return((size_t) (width-2));
1136 }
1137
1138 MagickPrivate size_t GetOptimalKernelWidth2D(const double radius,
1139   const double sigma)
1140 {
1141   double
1142     alpha,
1143     beta,
1144     gamma,
1145     normalize,
1146     value;
1147
1148   size_t
1149     width;
1150
1151   ssize_t
1152     j,
1153     u,
1154     v;
1155
1156   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1157   if (radius > MagickEpsilon)
1158     return((size_t) (2.0*ceil(radius)+1.0));
1159   gamma=fabs(sigma);
1160   if (gamma <= MagickEpsilon)
1161     return(3UL);
1162   alpha=PerceptibleReciprocal(2.0*gamma*gamma);
1163   beta=(double) PerceptibleReciprocal((double) Magick2PI*gamma*gamma);
1164   for (width=5; ; )
1165   {
1166     normalize=0.0;
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))
1173       break;
1174     width+=2;
1175   }
1176   return((size_t) (width-2));
1177 }
1178
1179 MagickPrivate size_t  GetOptimalKernelWidth(const double radius,
1180   const double sigma)
1181 {
1182   return(GetOptimalKernelWidth1D(radius,sigma));
1183 }