]> 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 component of the
83 %      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     b,
93     c,
94     g,
95     h,
96     m,
97     r,
98     x;
99
100   /*
101     Convert HCL to RGB colorspace.
102   */
103   assert(red != (double *) NULL);
104   assert(green != (double *) NULL);
105   assert(blue != (double *) NULL);
106   h=6.0*hue;
107   c=chroma;
108   x=c*(1.0-fabs(fmod(h,2.0)-1.0));
109   r=0.0;
110   g=0.0;
111   b=0.0;
112   if ((0.0 <= h) && (h < 1.0))
113     {
114       r=c;
115       g=x;
116     }
117   else
118     if ((1.0 <= h) && (h < 2.0))
119       {
120         r=x;
121         g=c;
122       }
123     else
124       if ((2.0 <= h) && (h < 3.0))
125         {
126           g=c;
127           b=x;
128         }
129       else
130         if ((3.0 <= h) && (h < 4.0))
131           {
132             g=x;
133             b=c;
134           }
135         else
136           if ((4.0 <= h) && (h < 5.0))
137             {
138               r=x;
139               b=c;
140             }
141           else
142             if ((5.0 <= h) && (h < 6.0))
143               {
144                 r=c;
145                 b=x;
146               }
147   m=luma-(0.298839*r+0.586811*g+0.114350*b);
148   *red=QuantumRange*(r+m);
149   *green=QuantumRange*(g+m);
150   *blue=QuantumRange*(b+m);
151 }
152 \f
153 /*
154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
155 %                                                                             %
156 %                                                                             %
157 %                                                                             %
158 %   C o n v e r t H C L p T o R G B                                           %
159 %                                                                             %
160 %                                                                             %
161 %                                                                             %
162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
163 %
164 %  ConvertHCLpToRGB() transforms a (hue, chroma, luma) to a (red, green,
165 %  blue) triple.  Since HCL colorspace is wider than RGB, we instead choose a
166 %  saturation strategy to project it on the RGB cube.
167 %
168 %  The format of the ConvertHCLpToRGBImage method is:
169 %
170 %      void ConvertHCLpToRGB(const double hue,const double chroma,
171 %        const double luma,double *red,double *green,double *blue)
172 %
173 %  A description of each parameter follows:
174 %
175 %    o hue, chroma, luma: A double value representing a componenet of the
176 %      HCLp color space.
177 %
178 %    o red, green, blue: A pointer to a pixel component of type Quantum.
179 %
180 */
181 MagickPrivate void ConvertHCLpToRGB(const double hue,const double chroma,
182   const double luma,double *red,double *green,double *blue)
183 {
184   double
185     b,
186     c,
187     g,
188     h,
189     m,
190     r,
191     x,
192     z;
193
194   /*
195     Convert HCLp to RGB colorspace.
196   */
197   assert(red != (double *) NULL);
198   assert(green != (double *) NULL);
199   assert(blue != (double *) NULL);
200   h=6.0*hue;
201   c=chroma;
202   x=c*(1.0-fabs(fmod(h,2.0)-1.0));
203   r=0.0;
204   g=0.0;
205   b=0.0;
206   if ((0.0 <= h) && (h < 1.0))
207     {
208       r=c;
209       g=x;
210     }
211   else
212     if ((1.0 <= h) && (h < 2.0))
213       {
214         r=x;
215         g=c;
216       }
217     else
218       if ((2.0 <= h) && (h < 3.0))
219         {
220           g=c;
221           b=x;
222         }
223       else
224         if ((3.0 <= h) && (h < 4.0))
225           {
226             g=x;
227             b=c;
228           }
229         else
230           if ((4.0 <= h) && (h < 5.0))
231             {
232               r=x;
233               b=c;
234             }
235           else
236             if ((5.0 <= h) && (h < 6.0))
237               {
238                 r=c;
239                 b=x;
240               }
241   m=luma-(0.298839*r+0.586811*g+0.114350*b);
242   z=1.0;
243   if (m < 0.0)
244     {
245       z=luma/(luma-m);
246       m=0.0;
247     }
248   else
249     if (m+c > 1.0)
250       {
251         z=(1.0-luma)/(m+c-luma);
252         m=1.0-z*c;
253       }
254   *red=QuantumRange*(z*r+m);
255   *green=QuantumRange*(z*g+m);
256   *blue=QuantumRange*(z*b+m);
257 }
258 \f
259 /*
260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261 %                                                                             %
262 %                                                                             %
263 %                                                                             %
264 %   C o n v e r t H S B T o R G B                                             %
265 %                                                                             %
266 %                                                                             %
267 %                                                                             %
268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
269 %
270 %  ConvertHSBToRGB() transforms a (hue, saturation, brightness) to a (red,
271 %  green, blue) triple.
272 %
273 %  The format of the ConvertHSBToRGBImage method is:
274 %
275 %      void ConvertHSBToRGB(const double hue,const double saturation,
276 %        const double brightness,double *red,double *green,double *blue)
277 %
278 %  A description of each parameter follows:
279 %
280 %    o hue, saturation, brightness: A double value representing a
281 %      component of the HSB color space.
282 %
283 %    o red, green, blue: A pointer to a pixel component of type Quantum.
284 %
285 */
286 MagickPrivate void ConvertHSBToRGB(const double hue,const double saturation,
287   const double brightness,double *red,double *green,double *blue)
288 {
289   double
290     f,
291     h,
292     p,
293     q,
294     t;
295
296   /*
297     Convert HSB to RGB colorspace.
298   */
299   assert(red != (double *) NULL);
300   assert(green != (double *) NULL);
301   assert(blue != (double *) NULL);
302   if (saturation == 0.0)
303     {
304       *red=QuantumRange*brightness;
305       *green=(*red);
306       *blue=(*red);
307       return;
308     }
309   h=6.0*(hue-floor(hue));
310   f=h-floor((double) h);
311   p=brightness*(1.0-saturation);
312   q=brightness*(1.0-saturation*f);
313   t=brightness*(1.0-(saturation*(1.0-f)));
314   switch ((int) h)
315   {
316     case 0:
317     default:
318     {
319       *red=QuantumRange*brightness;
320       *green=QuantumRange*t;
321       *blue=QuantumRange*p;
322       break;
323     }
324     case 1:
325     {
326       *red=QuantumRange*q;
327       *green=QuantumRange*brightness;
328       *blue=QuantumRange*p;
329       break;
330     }
331     case 2:
332     {
333       *red=QuantumRange*p;
334       *green=QuantumRange*brightness;
335       *blue=QuantumRange*t;
336       break;
337     }
338     case 3:
339     {
340       *red=QuantumRange*p;
341       *green=QuantumRange*q;
342       *blue=QuantumRange*brightness;
343       break;
344     }
345     case 4:
346     {
347       *red=QuantumRange*t;
348       *green=QuantumRange*p;
349       *blue=QuantumRange*brightness;
350       break;
351     }
352     case 5:
353     {
354       *red=QuantumRange*brightness;
355       *green=QuantumRange*p;
356       *blue=QuantumRange*q;
357       break;
358     }
359   }
360 }
361 \f
362 /*
363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
364 %                                                                             %
365 %                                                                             %
366 %                                                                             %
367 %   C o n v e r t H S I T o R G B                                             %
368 %                                                                             %
369 %                                                                             %
370 %                                                                             %
371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
372 %
373 %  ConvertHSIToRGB() transforms a (hue, saturation, intensity) to a (red,
374 %  green, blue) triple.
375 %
376 %  The format of the ConvertHSIToRGBImage method is:
377 %
378 %      void ConvertHSIToRGB(const double hue,const double saturation,
379 %        const double intensity,double *red,double *green,double *blue)
380 %
381 %  A description of each parameter follows:
382 %
383 %    o hue, saturation, intensity: A double value representing a
384 %      component of the HSI color space.
385 %
386 %    o red, green, blue: A pointer to a pixel component of type Quantum.
387 %
388 */
389 MagickPrivate void ConvertHSIToRGB(const double hue,const double saturation,
390   const double intensity,double *red,double *green,double *blue)
391 {
392   double
393     h;
394
395   /*
396     Convert HSI to RGB colorspace.
397   */
398   assert(red != (double *) NULL);
399   assert(green != (double *) NULL);
400   assert(blue != (double *) NULL);
401   h=360.0*hue;
402   h-=360.0*floor(h/360.0);
403   if (h < 120.0)
404     {
405       *blue=intensity*(1.0-saturation);
406       *red=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
407         (MagickPI/180.0)));
408       *green=3.0*intensity-*red-*blue;
409     }
410   else
411     if (h < 240.0)
412       {
413         h-=120.0;
414         *red=intensity*(1.0-saturation);
415         *green=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
416           (MagickPI/180.0)));
417         *blue=3.0*intensity-*red-*green;
418       }
419     else
420       {
421         h-=240.0;
422         *green=intensity*(1.0-saturation);
423         *blue=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
424           (MagickPI/180.0)));
425         *red=3.0*intensity-*green-*blue;
426       }
427   *red*=QuantumRange;
428   *green*=QuantumRange;
429   *blue*=QuantumRange;
430 }
431 \f
432 /*
433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
434 %                                                                             %
435 %                                                                             %
436 %                                                                             %
437 %   C o n v e r t H S L T o R G B                                             %
438 %                                                                             %
439 %                                                                             %
440 %                                                                             %
441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
442 %
443 %  ConvertHSLToRGB() transforms a (hue, saturation, lightness) to a (red,
444 %  green, blue) triple.
445 %
446 %  The format of the ConvertHSLToRGBImage method is:
447 %
448 %      void ConvertHSLToRGB(const double hue,const double saturation,
449 %        const double lightness,double *red,double *green,double *blue)
450 %
451 %  A description of each parameter follows:
452 %
453 %    o hue, saturation, lightness: A double value representing a
454 %      component of the HSL color space.
455 %
456 %    o red, green, blue: A pointer to a pixel component of type Quantum.
457 %
458 */
459 MagickExport void ConvertHSLToRGB(const double hue,const double saturation,
460   const double lightness,double *red,double *green,double *blue)
461 {
462   double
463     c,
464     h,
465     min,
466     x;
467
468   /*
469     Convert HSL to RGB colorspace.
470   */
471   assert(red != (double *) NULL);
472   assert(green != (double *) NULL);
473   assert(blue != (double *) NULL);
474   h=hue*360.0;
475   if (lightness <= 0.5)
476     c=2.0*lightness*saturation;
477   else
478     c=(2.0-2.0*lightness)*saturation;
479   min=lightness-0.5*c;
480   h-=360.0*floor(h/360.0);
481   h/=60.0;
482   x=c*(1.0-fabs(h-2.0*floor(h/2.0)-1.0));
483   switch ((int) floor(h))
484   {
485     case 0:
486     {
487       *red=QuantumRange*(min+c);
488       *green=QuantumRange*(min+x);
489       *blue=QuantumRange*min;
490       break;
491     }
492     case 1:
493     {
494       *red=QuantumRange*(min+x);
495       *green=QuantumRange*(min+c);
496       *blue=QuantumRange*min;
497       break;
498     }
499     case 2:
500     {
501       *red=QuantumRange*min;
502       *green=QuantumRange*(min+c);
503       *blue=QuantumRange*(min+x);
504       break;
505     }
506     case 3:
507     {
508       *red=QuantumRange*min;
509       *green=QuantumRange*(min+x);
510       *blue=QuantumRange*(min+c);
511       break;
512     }
513     case 4:
514     {
515       *red=QuantumRange*(min+x);
516       *green=QuantumRange*min;
517       *blue=QuantumRange*(min+c);
518       break;
519     }
520     case 5:
521     {
522       *red=QuantumRange*(min+c);
523       *green=QuantumRange*min;
524       *blue=QuantumRange*(min+x);
525       break;
526     }
527     default:
528     {
529       *red=0.0;
530       *green=0.0;
531       *blue=0.0;
532     }
533   }
534 }
535 \f
536 /*
537 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
538 %                                                                             %
539 %                                                                             %
540 %                                                                             %
541 %   C o n v e r t H S V T o R G B                                             %
542 %                                                                             %
543 %                                                                             %
544 %                                                                             %
545 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
546 %
547 %  ConvertHSVToRGB() transforms a (hue, saturation, value) to a (red,
548 %  green, blue) triple.
549 %
550 %  The format of the ConvertHSVToRGBImage method is:
551 %
552 %      void ConvertHSVToRGB(const double hue,const double saturation,
553 %        const double value,double *red,double *green,double *blue)
554 %
555 %  A description of each parameter follows:
556 %
557 %    o hue, saturation, value: A double value representing a
558 %      component of the HSV color space.
559 %
560 %    o red, green, blue: A pointer to a pixel component of type Quantum.
561 %
562 */
563 MagickPrivate void ConvertHSVToRGB(const double hue,const double saturation,
564   const double value,double *red,double *green,double *blue)
565 {
566   double
567     c,
568     h,
569     min,
570     x;
571
572   /*
573     Convert HSV to RGB colorspace.
574   */
575   assert(red != (double *) NULL);
576   assert(green != (double *) NULL);
577   assert(blue != (double *) NULL);
578   h=hue*360.0;
579   c=value*saturation;
580   min=value-c;
581   h-=360.0*floor(h/360.0);
582   h/=60.0;
583   x=c*(1.0-fabs(h-2.0*floor(h/2.0)-1.0));
584   switch ((int) floor(h))
585   {
586     case 0:
587     {
588       *red=QuantumRange*(min+c);
589       *green=QuantumRange*(min+x);
590       *blue=QuantumRange*min;
591       break;
592     }
593     case 1:
594     {
595       *red=QuantumRange*(min+x);
596       *green=QuantumRange*(min+c);
597       *blue=QuantumRange*min;
598       break;
599     }
600     case 2:
601     {
602       *red=QuantumRange*min;
603       *green=QuantumRange*(min+c);
604       *blue=QuantumRange*(min+x);
605       break;
606     }
607     case 3:
608     {
609       *red=QuantumRange*min;
610       *green=QuantumRange*(min+x);
611       *blue=QuantumRange*(min+c);
612       break;
613     }
614     case 4:
615     {
616       *red=QuantumRange*(min+x);
617       *green=QuantumRange*min;
618       *blue=QuantumRange*(min+c);
619       break;
620     }
621     case 5:
622     {
623       *red=QuantumRange*(min+c);
624       *green=QuantumRange*min;
625       *blue=QuantumRange*(min+x);
626       break;
627     }
628     default:
629     {
630       *red=0.0;
631       *green=0.0;
632       *blue=0.0;
633     }
634   }
635 }
636 \f
637 /*
638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
639 %                                                                             %
640 %                                                                             %
641 %                                                                             %
642 %   C o n v e r t H W B T o R G B                                             %
643 %                                                                             %
644 %                                                                             %
645 %                                                                             %
646 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
647 %
648 %  ConvertHWBToRGB() transforms a (hue, whiteness, blackness) to a (red, green,
649 %  blue) triple.
650 %
651 %  The format of the ConvertHWBToRGBImage method is:
652 %
653 %      void ConvertHWBToRGB(const double hue,const double whiteness,
654 %        const double blackness,double *red,double *green,double *blue)
655 %
656 %  A description of each parameter follows:
657 %
658 %    o hue, whiteness, blackness: A double value representing a
659 %      component of the HWB color space.
660 %
661 %    o red, green, blue: A pointer to a pixel component of type Quantum.
662 %
663 */
664 MagickPrivate void ConvertHWBToRGB(const double hue,const double whiteness,
665   const double blackness,double *red,double *green,double *blue)
666 {
667   double
668     b,
669     f,
670     g,
671     n,
672     r,
673     v;
674
675   register ssize_t
676     i;
677
678   /*
679     Convert HWB to RGB colorspace.
680   */
681   assert(red != (double *) NULL);
682   assert(green != (double *) NULL);
683   assert(blue != (double *) NULL);
684   v=1.0-blackness;
685   if (hue == -1.0)
686     {
687       *red=QuantumRange*v;
688       *green=QuantumRange*v;
689       *blue=QuantumRange*v;
690       return;
691     }
692   i=(ssize_t) floor(6.0*hue);
693   f=6.0*hue-i;
694   if ((i & 0x01) != 0)
695     f=1.0-f;
696   n=whiteness+f*(v-whiteness);  /* linear interpolation */
697   switch (i)
698   {
699     default:
700     case 6:
701     case 0: r=v; g=n; b=whiteness; break;
702     case 1: r=n; g=v; b=whiteness; break;
703     case 2: r=whiteness; g=v; b=n; break;
704     case 3: r=whiteness; g=n; b=v; break;
705     case 4: r=n; g=whiteness; b=v; break;
706     case 5: r=v; g=whiteness; b=n; break;
707   }
708   *red=QuantumRange*r;
709   *green=QuantumRange*g;
710   *blue=QuantumRange*b;
711 }
712 \f
713 /*
714 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
715 %                                                                             %
716 %                                                                             %
717 %                                                                             %
718 %   C o n v e r t L C H a b T o R G B                                         %
719 %                                                                             %
720 %                                                                             %
721 %                                                                             %
722 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
723 %
724 %  ConvertLCHabToRGB() transforms a (luma, chroma, hue) to a (red, green,
725 %  blue) triple.
726 %
727 %  The format of the ConvertLCHabToRGBImage method is:
728 %
729 %      void ConvertLCHabToRGB(const double luma,const double chroma,
730 %        const double hue,double *red,double *green,double *blue)
731 %
732 %  A description of each parameter follows:
733 %
734 %    o luma, chroma, hue: A double value representing a component of the
735 %      LCHab color space.
736 %
737 %    o red, green, blue: A pointer to a pixel component of type Quantum.
738 %
739 */
740 MagickPrivate void ConvertLCHabToRGB(const double luma,const double chroma,
741   const double hue,double *red,double *green,double *blue)
742 {
743   double
744     a,
745     b,
746     C,
747     H,
748     L,
749     X,
750     Y,
751     Z;
752
753   /*
754     Convert LCHab to RGB colorspace.
755   */
756   assert(red != (double *) NULL);
757   assert(green != (double *) NULL);
758   assert(blue != (double *) NULL);
759   L=luma;
760   C=chroma;
761   H=hue;
762   a=C*cos(360.0*H*MagickPI/180.0);
763   b=C*sin(360.0*H*MagickPI/180.0);
764   ConvertLabToXYZ(((116.0*L)-16.0)/100.0,(500.0*a)/255.0+0.5,(200.0*b)/255.0+
765     0.5,&X,&Y,&Z);
766   ConvertXYZToRGB(X,Y,Z,red,green,blue);
767 }
768 \f
769 /*
770 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
771 %                                                                             %
772 %                                                                             %
773 %                                                                             %
774 %   C o n v e r t L C H u v T o R G B                                         %
775 %                                                                             %
776 %                                                                             %
777 %                                                                             %
778 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
779 %
780 %  ConvertLCHuvToRGB() transforms a (luma, chroma, hue) to a (red, green,
781 %  blue) triple.
782 %
783 %  The format of the ConvertLCHuvToRGBImage method is:
784 %
785 %      void ConvertLCHuvToRGB(const double luma,const double chroma,
786 %        const double hue,double *red,double *green,double *blue)
787 %
788 %  A description of each parameter follows:
789 %
790 %    o luma, chroma, hue: A double value representing a component of the
791 %      LCHuv color space.
792 %
793 %    o red, green, blue: A pointer to a pixel component of type Quantum.
794 %
795 */
796 MagickPrivate void ConvertLCHuvToRGB(const double luma,const double chroma,
797   const double hue,double *red,double *green,double *blue)
798 {
799   double
800     C,
801     H,
802     L,
803     u,
804     v,
805     X,
806     Y,
807     Z;
808
809   /*
810     Convert LCHuv to RGB colorspace.
811   */
812   assert(red != (double *) NULL);
813   assert(green != (double *) NULL);
814   assert(blue != (double *) NULL);
815   L=luma;
816   C=chroma;
817   H=hue;
818   u=C*cos(360.0*H*MagickPI/180.0);
819   v=C*sin(360.0*H*MagickPI/180.0);
820   ConvertLuvToXYZ(L,(u+1.34)/3.54,(v+1.4)/2.62,&X,&Y,&Z);
821   ConvertXYZToRGB(X,Y,Z,red,green,blue);
822 }
823 \f
824 /*
825 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
826 %                                                                             %
827 %                                                                             %
828 %                                                                             %
829 %   C o n v e r t R G B T o H C L                                             %
830 %                                                                             %
831 %                                                                             %
832 %                                                                             %
833 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
834 %
835 %  ConvertRGBToHCL() transforms a (red, green, blue) to a (hue, chroma,
836 %  luma) triple.
837 %
838 %  The format of the ConvertRGBToHCL method is:
839 %
840 %      void ConvertRGBToHCL(const double red,const double green,
841 %        const double blue,double *hue,double *chroma,double *luma)
842 %
843 %  A description of each parameter follows:
844 %
845 %    o red, green, blue: A Quantum value representing the red, green, and
846 %      blue component of a pixel.
847 %
848 %    o hue, chroma, luma: A pointer to a double value representing a
849 %      component of the HCL color space.
850 %
851 */
852
853 static inline double MagickMax(const double x,const double y)
854 {
855   if (x > y)
856     return(x);
857   return(y);
858 }
859
860 static inline double MagickMin(const double x,const double y)
861 {
862   if (x < y)
863     return(x);
864   return(y);
865 }
866
867 MagickPrivate void ConvertRGBToHCL(const double red,const double green,
868   const double blue,double *hue,double *chroma,double *luma)
869 {
870   double
871     b,
872     c,
873     g,
874     h,
875     max,
876     r;
877
878   /*
879     Convert RGB to HCL colorspace.
880   */
881   assert(hue != (double *) NULL);
882   assert(chroma != (double *) NULL);
883   assert(luma != (double *) NULL);
884   r=red;
885   g=green;
886   b=blue;
887   max=MagickMax(r,MagickMax(g,b));
888   c=max-(double) MagickMin(r,MagickMin(g,b));
889   h=0.0;
890   if (c == 0.0)
891     h=0.0;
892   else
893     if (red == max)
894       h=fmod((g-b)/c+6.0,6.0);
895     else
896       if (green == max)
897         h=((b-r)/c)+2.0;
898       else
899         if (blue == max)
900           h=((r-g)/c)+4.0;
901   *hue=(h/6.0);
902   *chroma=QuantumScale*c;
903   *luma=QuantumScale*(0.298839*r+0.586811*g+0.114350*b);
904 }
905 \f
906 /*
907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
908 %                                                                             %
909 %                                                                             %
910 %                                                                             %
911 %   C o n v e r t R G B T o H C L p                                           %
912 %                                                                             %
913 %                                                                             %
914 %                                                                             %
915 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
916 %
917 %  ConvertRGBToHCLp() transforms a (red, green, blue) to a (hue, chroma,
918 %  luma) triple.
919 %
920 %  The format of the ConvertRGBToHCLp method is:
921 %
922 %      void ConvertRGBToHCLp(const double red,const double green,
923 %        const double blue,double *hue,double *chroma,double *luma)
924 %
925 %  A description of each parameter follows:
926 %
927 %    o red, green, blue: A Quantum value representing the red, green, and
928 %      blue component of a pixel.
929 %
930 %    o hue, chroma, luma: A pointer to a double value representing a
931 %      component of the HCL color space.
932 %
933 */
934 MagickPrivate void ConvertRGBToHCLp(const double red,const double green,
935   const double blue,double *hue,double *chroma,double *luma)
936 {
937   double
938     b,
939     c,
940     g,
941     h,
942     max,
943     r;
944
945   /*
946     Convert RGB to HCL colorspace.
947   */
948   assert(hue != (double *) NULL);
949   assert(chroma != (double *) NULL);
950   assert(luma != (double *) NULL);
951   r=red;
952   g=green;
953   b=blue;
954   max=MagickMax(r,MagickMax(g,b));
955   c=max-(double) MagickMin(r,MagickMin(g,b));
956   h=0.0;
957   if (c == 0.0)
958     h=0.0;
959   else
960     if (red == max)
961       h=fmod((g-b)/c+6.0,6.0);
962     else
963       if (green == max)
964         h=((b-r)/c)+2.0;
965       else
966         if (blue == max)
967           h=((r-g)/c)+4.0;
968   *hue=(h/6.0);
969   *chroma=QuantumScale*c;
970   *luma=QuantumScale*(0.298839*r+0.586811*g+0.114350*b);
971 }
972 \f
973 /*
974 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
975 %                                                                             %
976 %                                                                             %
977 %                                                                             %
978 %   C o n v e r t R G B T o H S B                                             %
979 %                                                                             %
980 %                                                                             %
981 %                                                                             %
982 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
983 %
984 %  ConvertRGBToHSB() transforms a (red, green, blue) to a (hue, saturation,
985 %  brightness) triple.
986 %
987 %  The format of the ConvertRGBToHSB method is:
988 %
989 %      void ConvertRGBToHSB(const double red,const double green,
990 %        const double blue,double *hue,double *saturation,double *brightness)
991 %
992 %  A description of each parameter follows:
993 %
994 %    o red, green, blue: A Quantum value representing the red, green, and
995 %      blue component of a pixel..
996 %
997 %    o hue, saturation, brightness: A pointer to a double value representing a
998 %      component of the HSB color space.
999 %
1000 */
1001 MagickPrivate void ConvertRGBToHSB(const double red,const double green,
1002   const double blue,double *hue,double *saturation,double *brightness)
1003 {
1004   double
1005     b,
1006     delta,
1007     g,
1008     max,
1009     min,
1010     r;
1011
1012   /*
1013     Convert RGB to HSB colorspace.
1014   */
1015   assert(hue != (double *) NULL);
1016   assert(saturation != (double *) NULL);
1017   assert(brightness != (double *) NULL);
1018   *hue=0.0;
1019   *saturation=0.0;
1020   *brightness=0.0;
1021   r=red;
1022   g=green;
1023   b=blue;
1024   min=r < g ? r : g;
1025   if (b < min)
1026     min=b;
1027   max=r > g ? r : g;
1028   if (b > max)
1029     max=b;
1030   if (max == 0.0)
1031     return;
1032   delta=max-min;
1033   *saturation=delta/max;
1034   *brightness=QuantumScale*max;
1035   if (delta == 0.0)
1036     return;
1037   if (r == max)
1038     *hue=(g-b)/delta;
1039   else
1040     if (g == max)
1041       *hue=2.0+(b-r)/delta;
1042     else
1043       *hue=4.0+(r-g)/delta;
1044   *hue/=6.0;
1045   if (*hue < 0.0)
1046     *hue+=1.0;
1047 }
1048 \f
1049 /*
1050 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1051 %                                                                             %
1052 %                                                                             %
1053 %                                                                             %
1054 %   C o n v e r t R G B T o H S I                                             %
1055 %                                                                             %
1056 %                                                                             %
1057 %                                                                             %
1058 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1059 %
1060 %  ConvertRGBToHSI() transforms a (red, green, blue) to a (hue, saturation,
1061 %  intensity) triple.
1062 %
1063 %  The format of the ConvertRGBToHSI method is:
1064 %
1065 %      void ConvertRGBToHSI(const double red,const double green,
1066 %        const double blue,double *hue,double *saturation,double *intensity)
1067 %
1068 %  A description of each parameter follows:
1069 %
1070 %    o red, green, blue: A Quantum value representing the red, green, and
1071 %      blue component of a pixel..
1072 %
1073 %    o hue, saturation, intensity: A pointer to a double value representing a
1074 %      component of the HSI color space.
1075 %
1076 */
1077 MagickPrivate void ConvertRGBToHSI(const double red,const double green,
1078   const double blue,double *hue,double *saturation,double *intensity)
1079 {
1080   double
1081     alpha,
1082     beta;
1083
1084   /*
1085     Convert RGB to HSI colorspace.
1086   */
1087   assert(hue != (double *) NULL);
1088   assert(saturation != (double *) NULL);
1089   assert(intensity != (double *) NULL);
1090   *intensity=(QuantumScale*red+QuantumScale*green+QuantumScale*blue)/3.0;
1091   if (*intensity <= 0.0)
1092     {
1093       *hue=0.0;
1094       *saturation=0.0;
1095       return;
1096     }
1097   *saturation=1.0-MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
1098     QuantumScale*blue))/(*intensity);
1099   alpha=0.5*(2.0*QuantumScale*red-QuantumScale*green-QuantumScale*blue);
1100   beta=0.866025403784439*(QuantumScale*green-QuantumScale*blue);
1101   *hue=atan2(beta,alpha)*(180.0/MagickPI)/360.0;
1102   if (*hue < 0.0)
1103     *hue+=1.0;
1104 }
1105 \f
1106 /*
1107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1108 %                                                                             %
1109 %                                                                             %
1110 %                                                                             %
1111 %   C o n v e r t R G B T o H S L                                             %
1112 %                                                                             %
1113 %                                                                             %
1114 %                                                                             %
1115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1116 %
1117 %  ConvertRGBToHSL() transforms a (red, green, blue) to a (hue, saturation,
1118 %  lightness) triple.
1119 %
1120 %  The format of the ConvertRGBToHSL method is:
1121 %
1122 %      void ConvertRGBToHSL(const double red,const double green,
1123 %        const double blue,double *hue,double *saturation,double *lightness)
1124 %
1125 %  A description of each parameter follows:
1126 %
1127 %    o red, green, blue: A Quantum value representing the red, green, and
1128 %      blue component of a pixel..
1129 %
1130 %    o hue, saturation, lightness: A pointer to a double value representing a
1131 %      component of the HSL color space.
1132 %
1133 */
1134 MagickExport void ConvertRGBToHSL(const double red,const double green,
1135   const double blue,double *hue,double *saturation,double *lightness)
1136 {
1137   double
1138     c,
1139     max,
1140     min;
1141
1142   /*
1143     Convert RGB to HSL colorspace.
1144   */
1145   assert(hue != (double *) NULL);
1146   assert(saturation != (double *) NULL);
1147   assert(lightness != (double *) NULL);
1148   max=MagickMax(QuantumScale*red,MagickMax(QuantumScale*green,
1149     QuantumScale*blue));
1150   min=MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
1151     QuantumScale*blue));
1152   c=max-min;
1153   *lightness=(max+min)/2.0;
1154   if (c <= 0.0)
1155     {
1156       *hue=0.0;
1157       *saturation=0.0;
1158       return;
1159     }
1160   if (max == (QuantumScale*red))
1161     {
1162       *hue=(QuantumScale*green-QuantumScale*blue)/c;
1163       if ((QuantumScale*green) < (QuantumScale*blue))
1164         *hue+=6.0;
1165     }
1166   else
1167     if (max == (QuantumScale*green))
1168       *hue=2.0+(QuantumScale*blue-QuantumScale*red)/c;
1169     else
1170       *hue=4.0+(QuantumScale*red-QuantumScale*green)/c;
1171   *hue*=60.0/360.0;
1172   if (*lightness <= 0.5)
1173     *saturation=c/(2.0*(*lightness));
1174   else
1175     *saturation=c/(2.0-2.0*(*lightness));
1176 }
1177 \f
1178 /*
1179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1180 %                                                                             %
1181 %                                                                             %
1182 %                                                                             %
1183 %   C o n v e r t R G B T o H S V                                             %
1184 %                                                                             %
1185 %                                                                             %
1186 %                                                                             %
1187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1188 %
1189 %  ConvertRGBToHSV() transforms a (red, green, blue) to a (hue, saturation,
1190 %  value) triple.
1191 %
1192 %  The format of the ConvertRGBToHSV method is:
1193 %
1194 %      void ConvertRGBToHSV(const double red,const double green,
1195 %        const double blue,double *hue,double *saturation,double *value)
1196 %
1197 %  A description of each parameter follows:
1198 %
1199 %    o red, green, blue: A Quantum value representing the red, green, and
1200 %      blue component of a pixel..
1201 %
1202 %    o hue, saturation, value: A pointer to a double value representing a
1203 %      component of the HSV color space.
1204 %
1205 */
1206 MagickPrivate void ConvertRGBToHSV(const double red,const double green,
1207   const double blue,double *hue,double *saturation,double *value)
1208 {
1209   double
1210     c,
1211     max,
1212     min;
1213
1214   /*
1215     Convert RGB to HSV colorspace.
1216   */
1217   assert(hue != (double *) NULL);
1218   assert(saturation != (double *) NULL);
1219   assert(value != (double *) NULL);
1220   max=MagickMax(QuantumScale*red,MagickMax(QuantumScale*green,
1221     QuantumScale*blue));
1222   min=MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
1223     QuantumScale*blue));
1224   c=max-min;
1225   *value=max;
1226   if (c <= 0.0)
1227     {
1228       *hue=0.0;
1229       *saturation=0.0;
1230       return;
1231     }
1232   if (max == (QuantumScale*red))
1233     {
1234       *hue=(QuantumScale*green-QuantumScale*blue)/c;
1235       if ((QuantumScale*green) < (QuantumScale*blue))
1236         *hue+=6.0;
1237     }
1238   else
1239     if (max == (QuantumScale*green))
1240       *hue=2.0+(QuantumScale*blue-QuantumScale*red)/c;
1241     else
1242       *hue=4.0+(QuantumScale*red-QuantumScale*green)/c;
1243   *hue*=60.0/360.0;
1244   *saturation=c/max;
1245 }
1246 \f
1247 /*
1248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1249 %                                                                             %
1250 %                                                                             %
1251 %                                                                             %
1252 %   C o n v e r t R G B T o H W B                                             %
1253 %                                                                             %
1254 %                                                                             %
1255 %                                                                             %
1256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1257 %
1258 %  ConvertRGBToHWB() transforms a (red, green, blue) to a (hue, whiteness,
1259 %  blackness) triple.
1260 %
1261 %  The format of the ConvertRGBToHWB method is:
1262 %
1263 %      void ConvertRGBToHWB(const double red,const double green,
1264 %        const double blue,double *hue,double *whiteness,double *blackness)
1265 %
1266 %  A description of each parameter follows:
1267 %
1268 %    o red, green, blue: A Quantum value representing the red, green, and
1269 %      blue component of a pixel.
1270 %
1271 %    o hue, whiteness, blackness: A pointer to a double value representing a
1272 %      component of the HWB color space.
1273 %
1274 */
1275 MagickPrivate void ConvertRGBToHWB(const double red,const double green,
1276   const double blue,double *hue,double *whiteness,double *blackness)
1277 {
1278   double
1279     b,
1280     f,
1281     g,
1282     p,
1283     r,
1284     v,
1285     w;
1286
1287   /*
1288     Convert RGB to HWB colorspace.
1289   */
1290   assert(hue != (double *) NULL);
1291   assert(whiteness != (double *) NULL);
1292   assert(blackness != (double *) NULL);
1293   r=red;
1294   g=green;
1295   b=blue;
1296   w=MagickMin(r,MagickMin(g,b));
1297   v=MagickMax(r,MagickMax(g,b));
1298   *blackness=1.0-QuantumScale*v;
1299   *whiteness=QuantumScale*w;
1300   if (v == w)
1301     {
1302       *hue=(-1.0);
1303       return;
1304     }
1305   f=(r == w) ? g-b : ((g == w) ? b-r : r-g);
1306   p=(r == w) ? 3.0 : ((g == w) ? 5.0 : 1.0);
1307   *hue=(p-f/(v-1.0*w))/6.0;
1308 }
1309 \f
1310 /*
1311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1312 %                                                                             %
1313 %                                                                             %
1314 %                                                                             %
1315 %   C o n v e r t R G B T o L C H a b                                         %
1316 %                                                                             %
1317 %                                                                             %
1318 %                                                                             %
1319 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1320 %
1321 %  ConvertRGBToLCHab() transforms a (red, green, blue) to a (luma, chroma,
1322 %  hue) triple.
1323 %
1324 %  The format of the ConvertRGBToLCHab method is:
1325 %
1326 %      void ConvertRGBToLCHab(const double red,const double green,
1327 %        const double blue,double *luma,double *chroma,double *hue)
1328 %
1329 %  A description of each parameter follows:
1330 %
1331 %    o red, green, blue: A Quantum value representing the red, green, and
1332 %      blue component of a pixel.
1333 %
1334 %    o luma, chroma, hue: A pointer to a double value representing a
1335 %      component of the LCH color space.
1336 %
1337 */
1338 MagickPrivate void ConvertRGBToLCHab(const double red,const double green,
1339   const double blue,double *luma,double *chroma,double *hue)
1340 {
1341   double
1342     a,
1343     b,
1344     C,
1345     H,
1346     L,
1347     X,
1348     Y,
1349     Z;
1350
1351   /*
1352     Convert RGB to LCHab colorspace.
1353   */
1354   assert(luma != (double *) NULL);
1355   assert(chroma != (double *) NULL);
1356   assert(hue != (double *) NULL);
1357   ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
1358   ConvertXYZToLab(X,Y,Z,&L,&a,&b);
1359   C=hypot(255.0*(a-0.5)/500.0,255.0*(b-0.5)/200.0);
1360   H=180.0*atan2(255.0*(b-0.5)/200.0,255.0*(a-0.5)/500.0)/MagickPI/360.0;
1361   if (H < 0.0)
1362     H+=1.0;
1363   if (H >= 1.0)
1364     H-=1.0;
1365   *luma=(100.0*L+16.0)/116.0;
1366   *chroma=C;
1367   *hue=H;
1368 }
1369 \f
1370 /*
1371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1372 %                                                                             %
1373 %                                                                             %
1374 %                                                                             %
1375 %   C o n v e r t R G B T o L C H u v                                         %
1376 %                                                                             %
1377 %                                                                             %
1378 %                                                                             %
1379 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1380 %
1381 %  ConvertRGBToLCHuv() transforms a (red, green, blue) to a (luma, chroma,
1382 %  hue) triple.
1383 %
1384 %  The format of the ConvertRGBToLCHuv method is:
1385 %
1386 %      void ConvertRGBToLCHuv(const double red,const double green,
1387 %        const double blue,double *luma,double *chroma,double *hue)
1388 %
1389 %  A description of each parameter follows:
1390 %
1391 %    o red, green, blue: A Quantum value representing the red, green, and
1392 %      blue component of a pixel.
1393 %
1394 %    o luma, chroma, hue: A pointer to a double value representing a
1395 %      component of the LCHuv color space.
1396 %
1397 */
1398 MagickPrivate void ConvertRGBToLCHuv(const double red,const double green,
1399   const double blue,double *luma,double *chroma,double *hue)
1400 {
1401   double
1402     C,
1403     H,
1404     L,
1405     u,
1406     v,
1407     X,
1408     Y,
1409     Z;
1410
1411   /*
1412     Convert RGB to LCHuv colorspace.
1413   */
1414   assert(luma != (double *) NULL);
1415   assert(chroma != (double *) NULL);
1416   assert(hue != (double *) NULL);
1417   ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
1418   ConvertXYZToLuv(X,Y,Z,&L,&u,&v);
1419   C=hypot(3.54*u-1.34,2.62*v-1.4);
1420   H=180.0*atan2(2.62*v-1.4,3.54*u-1.34)/MagickPI/360.0;
1421   if (H < 0.0)
1422     H+=1.0;
1423   if (H >= 1.0)
1424     H-=1.0;
1425   *luma=L;
1426   *chroma=C;
1427   *hue=H;
1428 }
1429 \f
1430 /*
1431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1432 %                                                                             %
1433 %                                                                             %
1434 %                                                                             %
1435 %   E x p a n d A f f i n e                                                   %
1436 %                                                                             %
1437 %                                                                             %
1438 %                                                                             %
1439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1440 %
1441 %  ExpandAffine() computes the affine's expansion factor, i.e. the square root
1442 %  of the factor by which the affine transform affects area. In an affine
1443 %  transform composed of scaling, rotation, shearing, and translation, returns
1444 %  the amount of scaling.
1445 %
1446 %  The format of the ExpandAffine method is:
1447 %
1448 %      double ExpandAffine(const AffineMatrix *affine)
1449 %
1450 %  A description of each parameter follows:
1451 %
1452 %    o expansion: ExpandAffine returns the affine's expansion factor.
1453 %
1454 %    o affine: A pointer the affine transform of type AffineMatrix.
1455 %
1456 */
1457 MagickExport double ExpandAffine(const AffineMatrix *affine)
1458 {
1459   assert(affine != (const AffineMatrix *) NULL);
1460   return(sqrt(fabs(affine->sx*affine->sy-affine->rx*affine->ry)));
1461 }
1462 \f
1463 /*
1464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1465 %                                                                             %
1466 %                                                                             %
1467 %                                                                             %
1468 %   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                         %
1469 %                                                                             %
1470 %                                                                             %
1471 %                                                                             %
1472 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1473 %
1474 %  GenerateDifferentialNoise() generates differentual noise.
1475 %
1476 %  The format of the GenerateDifferentialNoise method is:
1477 %
1478 %      double GenerateDifferentialNoise(RandomInfo *random_info,
1479 %        const Quantum pixel,const NoiseType noise_type,const double attenuate)
1480 %
1481 %  A description of each parameter follows:
1482 %
1483 %    o random_info: the random info.
1484 %
1485 %    o pixel: noise is relative to this pixel value.
1486 %
1487 %    o noise_type: the type of noise.
1488 %
1489 %    o attenuate:  attenuate the noise.
1490 %
1491 */
1492 MagickPrivate double GenerateDifferentialNoise(RandomInfo *random_info,
1493   const Quantum pixel,const NoiseType noise_type,const double attenuate)
1494 {
1495 #define SigmaUniform  (attenuate*0.015625)
1496 #define SigmaGaussian  (attenuate*0.015625)
1497 #define SigmaImpulse  (attenuate*0.1)
1498 #define SigmaLaplacian (attenuate*0.0390625)
1499 #define SigmaMultiplicativeGaussian  (attenuate*0.5)
1500 #define SigmaPoisson  (attenuate*12.5)
1501 #define SigmaRandom  (attenuate)
1502 #define TauGaussian  (attenuate*0.078125)
1503
1504   double
1505     alpha,
1506     beta,
1507     noise,
1508     sigma;
1509
1510   alpha=GetPseudoRandomValue(random_info);
1511   switch (noise_type)
1512   {
1513     case UniformNoise:
1514     default:
1515     {
1516       noise=(double) (pixel+QuantumRange*SigmaUniform*(alpha-0.5));
1517       break;
1518     }
1519     case GaussianNoise:
1520     {
1521       double
1522         gamma,
1523         tau;
1524
1525       if (alpha == 0.0)
1526         alpha=1.0;
1527       beta=GetPseudoRandomValue(random_info);
1528       gamma=sqrt(-2.0*log(alpha));
1529       sigma=gamma*cos((double) (2.0*MagickPI*beta));
1530       tau=gamma*sin((double) (2.0*MagickPI*beta));
1531       noise=(double) (pixel+sqrt((double) pixel)*SigmaGaussian*sigma+
1532         QuantumRange*TauGaussian*tau);
1533       break;
1534     }
1535     case ImpulseNoise:
1536     {
1537       if (alpha < (SigmaImpulse/2.0))
1538         noise=0.0;
1539       else
1540         if (alpha >= (1.0-(SigmaImpulse/2.0)))
1541           noise=(double) QuantumRange;
1542         else
1543           noise=(double) pixel;
1544       break;
1545     }
1546     case LaplacianNoise:
1547     {
1548       if (alpha <= 0.5)
1549         {
1550           if (alpha <= MagickEpsilon)
1551             noise=(double) (pixel-QuantumRange);
1552           else
1553             noise=(double) (pixel+QuantumRange*SigmaLaplacian*log(2.0*alpha)+
1554               0.5);
1555           break;
1556         }
1557       beta=1.0-alpha;
1558       if (beta <= (0.5*MagickEpsilon))
1559         noise=(double) (pixel+QuantumRange);
1560       else
1561         noise=(double) (pixel-QuantumRange*SigmaLaplacian*log(2.0*beta)+0.5);
1562       break;
1563     }
1564     case MultiplicativeGaussianNoise:
1565     {
1566       sigma=1.0;
1567       if (alpha > MagickEpsilon)
1568         sigma=sqrt(-2.0*log(alpha));
1569       beta=GetPseudoRandomValue(random_info);
1570       noise=(double) (pixel+pixel*SigmaMultiplicativeGaussian*sigma*
1571         cos((double) (2.0*MagickPI*beta))/2.0);
1572       break;
1573     }
1574     case PoissonNoise:
1575     {
1576       double
1577         poisson;
1578
1579       register ssize_t
1580         i;
1581
1582       poisson=exp(-SigmaPoisson*QuantumScale*pixel);
1583       for (i=0; alpha > poisson; i++)
1584       {
1585         beta=GetPseudoRandomValue(random_info);
1586         alpha*=beta;
1587       }
1588       noise=(double) (QuantumRange*i/SigmaPoisson);
1589       break;
1590     }
1591     case RandomNoise:
1592     {
1593       noise=(double) (QuantumRange*SigmaRandom*alpha);
1594       break;
1595     }
1596   }
1597   return(noise);
1598 }
1599 \f
1600 /*
1601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1602 %                                                                             %
1603 %                                                                             %
1604 %                                                                             %
1605 %   G e t O p t i m a l K e r n e l W i d t h                                 %
1606 %                                                                             %
1607 %                                                                             %
1608 %                                                                             %
1609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1610 %
1611 %  GetOptimalKernelWidth() computes the optimal kernel radius for a convolution
1612 %  filter.  Start with the minimum value of 3 pixels and walk out until we drop
1613 %  below the threshold of one pixel numerical accuracy.
1614 %
1615 %  The format of the GetOptimalKernelWidth method is:
1616 %
1617 %      size_t GetOptimalKernelWidth(const double radius,
1618 %        const double sigma)
1619 %
1620 %  A description of each parameter follows:
1621 %
1622 %    o width: GetOptimalKernelWidth returns the optimal width of a
1623 %      convolution kernel.
1624 %
1625 %    o radius: the radius of the Gaussian, in pixels, not counting the center
1626 %      pixel.
1627 %
1628 %    o sigma: the standard deviation of the Gaussian, in pixels.
1629 %
1630 */
1631 MagickPrivate size_t GetOptimalKernelWidth1D(const double radius,
1632   const double sigma)
1633 {
1634   double
1635     alpha,
1636     beta,
1637     gamma,
1638     normalize,
1639     value;
1640
1641   register ssize_t
1642     i;
1643
1644   size_t
1645     width;
1646
1647   ssize_t
1648     j;
1649
1650   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1651   if (radius > MagickEpsilon)
1652     return((size_t) (2.0*ceil(radius)+1.0));
1653   gamma=fabs(sigma);
1654   if (gamma <= MagickEpsilon)
1655     return(3UL);
1656   alpha=PerceptibleReciprocal(2.0*gamma*gamma);
1657   beta=(double) PerceptibleReciprocal((double) MagickSQ2PI*gamma);
1658   for (width=5; ; )
1659   {
1660     normalize=0.0;
1661     j=(ssize_t) (width-1)/2;
1662     for (i=(-j); i <= j; i++)
1663       normalize+=exp(-((double) (i*i))*alpha)*beta;
1664     value=exp(-((double) (j*j))*alpha)*beta/normalize;
1665     if ((value < QuantumScale) || (value < MagickEpsilon))
1666       break;
1667     width+=2;
1668   }
1669   return((size_t) (width-2));
1670 }
1671
1672 MagickPrivate size_t GetOptimalKernelWidth2D(const double radius,
1673   const double sigma)
1674 {
1675   double
1676     alpha,
1677     beta,
1678     gamma,
1679     normalize,
1680     value;
1681
1682   size_t
1683     width;
1684
1685   ssize_t
1686     j,
1687     u,
1688     v;
1689
1690   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1691   if (radius > MagickEpsilon)
1692     return((size_t) (2.0*ceil(radius)+1.0));
1693   gamma=fabs(sigma);
1694   if (gamma <= MagickEpsilon)
1695     return(3UL);
1696   alpha=PerceptibleReciprocal(2.0*gamma*gamma);
1697   beta=(double) PerceptibleReciprocal((double) Magick2PI*gamma*gamma);
1698   for (width=5; ; )
1699   {
1700     normalize=0.0;
1701     j=(ssize_t) (width-1)/2;
1702     for (v=(-j); v <= j; v++)
1703       for (u=(-j); u <= j; u++)
1704         normalize+=exp(-((double) (u*u+v*v))*alpha)*beta;
1705     value=exp(-((double) (j*j))*alpha)*beta/normalize;
1706     if ((value < QuantumScale) || (value < MagickEpsilon))
1707       break;
1708     width+=2;
1709   }
1710   return((size_t) (width-2));
1711 }
1712
1713 MagickPrivate size_t  GetOptimalKernelWidth(const double radius,
1714   const double sigma)
1715 {
1716   return(GetOptimalKernelWidth1D(radius,sigma));
1717 }