18#ifndef MAGICKCORE_COLORSPACE_PRIVATE_H
19#define MAGICKCORE_COLORSPACE_PRIVATE_H
21#include "MagickCore/image.h"
22#include "MagickCore/image-private.h"
23#include "MagickCore/pixel.h"
24#include "MagickCore/pixel-accessor.h"
26#define IlluminantX 0.95047
27#define IlluminantY 1.0
28#define IlluminantZ 1.08883
29#define CIEEpsilon (216.0/24389.0)
30#define CIEK (24389.0/27.0)
33 illuminant_tristimulus[] =
35 { 1.09850, 1.00000, 0.35585 },
36 { 0.99072, 1.00000, 0.85223 },
37 { 0.98074, 1.00000, 1.18232 },
38 { 0.96422, 1.00000, 0.82521 },
39 { 0.95682, 1.00000, 0.92149 },
40 { 0.95047, 1.00000, 1.08883 },
41 { 0.94972, 1.00000, 1.22638 },
42 { 1.00000, 1.00000, 1.00000 },
43 { 0.99186, 1.00000, 0.67393 },
44 { 0.95041, 1.00000, 1.08747 },
45 { 1.00962, 1.00000, 0.64350 }
48#if defined(__cplusplus) || defined(c_plusplus)
53static inline void ConvertAdobe98ToXYZ(
const double red,
const double green,
54 const double blue,
double *X,
double *Y,
double *Z)
64 r=QuantumScale*DecodePixelGamma((
double) QuantumRange*red);
65 g=QuantumScale*DecodePixelGamma((
double) QuantumRange*green);
66 b=QuantumScale*DecodePixelGamma((
double) QuantumRange*blue);
67 *X=0.57666904291013050*r+0.18555823790654630*g+0.18822864623499470*b;
68 *Y=0.29734497525053605*r+0.62736356625546610*g+0.07529145849399788*b;
69 *Z=0.02703136138641234*r+0.07068885253582723*g+0.99133753683763880*b;
72static inline void ConvertXYZToRGB(
const double X,
const double Y,
const double Z,
73 double *red,
double *green,
double *blue)
81 r=(3.240969941904521*X)+(-1.537383177570093*Y)+(-0.498610760293*Z);
82 g=(-0.96924363628087*X)+(1.87596750150772*Y)+(0.041555057407175*Z);
83 b=(0.055630079696993*X)+(-0.20397695888897*Y)+(1.056971514242878*Z);
84 min=MagickMin(r,MagickMin(g,b));
91 *red=EncodePixelGamma((
double) QuantumRange*r);
92 *green=EncodePixelGamma((
double) QuantumRange*g);
93 *blue=EncodePixelGamma((
double) QuantumRange*b);
96static inline void ConvertAdobe98ToRGB(
const double r,
const double g,
97 const double b,
double *red,
double *green,
double *blue)
104 ConvertAdobe98ToXYZ(r,g,b,&X,&Y,&Z);
105 ConvertXYZToRGB(X,Y,Z,red,green,blue);
108static inline void ConvertCAT02LMSToXYZ(
const double L,
const double M,
109 const double S,
double *X,
double *Y,
double *Z)
114 *X=1.096123820835514*L-0.278869000218287*M+0.182745179382773*S;
115 *Y=0.454369041975359*L+0.473533154307412*M+0.072097803717229*S;
116 *Z=(-0.009627608738429)*L-0.005698031216113*M+1.015325639954543*S;
119static inline void ConvertCAT02LMSToRGB(
const double L,
const double M,
120 const double S,
double *R,
double *G,
double *B)
127 ConvertCAT02LMSToXYZ(L,M,S,&X,&Y,&Z);
128 ConvertXYZToRGB(X,Y,Z,R,G,B);
131static inline void ConvertCMYKToRGB(
PixelInfo *pixel)
133 pixel->red=(((double) QuantumRange-(QuantumScale*pixel->red*
134 ((double) QuantumRange-pixel->black)+pixel->black)));
135 pixel->green=(((double) QuantumRange-(QuantumScale*pixel->green*
136 ((double) QuantumRange-pixel->black)+pixel->black)));
137 pixel->blue=(((double) QuantumRange-(QuantumScale*pixel->blue*
138 ((double) QuantumRange-pixel->black)+pixel->black)));
141static inline void ConvertCMYToRGB(
const double cyan,
const double magenta,
142 const double yellow,
double *red,
double *green,
double *blue)
144 *red=(double) QuantumRange*(1.0-cyan);
145 *green=(double) QuantumRange*(1.0-magenta);
146 *blue=(double) QuantumRange*(1.0-yellow);
149static inline void ConvertHCLToRGB(
const double hue,
const double chroma,
150 const double luma,
double *red,
double *green,
double *blue)
164 assert(red != (
double *) NULL);
165 assert(green != (
double *) NULL);
166 assert(blue != (
double *) NULL);
169 x=c*(1.0-fabs(fmod(h,2.0)-1.0));
173 if ((0.0 <= h) && (h < 1.0))
179 if ((1.0 <= h) && (h < 2.0))
185 if ((2.0 <= h) && (h < 3.0))
191 if ((3.0 <= h) && (h < 4.0))
197 if ((4.0 <= h) && (h < 5.0))
203 if ((5.0 <= h) && (h < 6.0))
208 m=luma-(0.298839*r+0.586811*g+0.114350*b);
209 *red=(double) QuantumRange*(r+m);
210 *green=(double) QuantumRange*(g+m);
211 *blue=(double) QuantumRange*(b+m);
214static inline void ConvertHCLpToRGB(
const double hue,
const double chroma,
215 const double luma,
double *red,
double *green,
double *blue)
230 assert(red != (
double *) NULL);
231 assert(green != (
double *) NULL);
232 assert(blue != (
double *) NULL);
235 x=c*(1.0-fabs(fmod(h,2.0)-1.0));
239 if ((0.0 <= h) && (h < 1.0))
245 if ((1.0 <= h) && (h < 2.0))
251 if ((2.0 <= h) && (h < 3.0))
257 if ((3.0 <= h) && (h < 4.0))
263 if ((4.0 <= h) && (h < 5.0))
269 if ((5.0 <= h) && (h < 6.0))
274 m=luma-(0.298839*r+0.586811*g+0.114350*b);
284 z=(1.0-luma)/(m+c-luma);
287 *red=(double) QuantumRange*(z*r+m);
288 *green=(double) QuantumRange*(z*g+m);
289 *blue=(double) QuantumRange*(z*b+m);
292static inline void ConvertHSBToRGB(
const double hue,
const double saturation,
293 const double brightness,
double *red,
double *green,
double *blue)
305 assert(red != (
double *) NULL);
306 assert(green != (
double *) NULL);
307 assert(blue != (
double *) NULL);
308 if (fabs(saturation) < MagickEpsilon)
310 *red=(double) QuantumRange*brightness;
315 h=6.0*(hue-floor(hue));
316 f=h-floor((
double) h);
317 p=brightness*(1.0-saturation);
318 q=brightness*(1.0-saturation*f);
319 t=brightness*(1.0-(saturation*(1.0-f)));
325 *red=(double) QuantumRange*brightness;
326 *green=(double) QuantumRange*t;
327 *blue=(double) QuantumRange*p;
332 *red=(double) QuantumRange*q;
333 *green=(double) QuantumRange*brightness;
334 *blue=(double) QuantumRange*p;
339 *red=(double) QuantumRange*p;
340 *green=(double) QuantumRange*brightness;
341 *blue=(double) QuantumRange*t;
346 *red=(double) QuantumRange*p;
347 *green=(double) QuantumRange*q;
348 *blue=(double) QuantumRange*brightness;
353 *red=(double) QuantumRange*t;
354 *green=(double) QuantumRange*p;
355 *blue=(double) QuantumRange*brightness;
360 *red=(double) QuantumRange*brightness;
361 *green=(double) QuantumRange*p;
362 *blue=(double) QuantumRange*q;
368static inline void ConvertHSIToRGB(
const double hue,
const double saturation,
369 const double intensity,
double *red,
double *green,
double *blue)
380 assert(red != (
double *) NULL);
381 assert(green != (
double *) NULL);
382 assert(blue != (
double *) NULL);
384 h-=360.0*floor(h/360.0);
387 b=intensity*(1.0-saturation);
388 r=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
396 r=intensity*(1.0-saturation);
397 g=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
404 g=intensity*(1.0-saturation);
405 b=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
409 *red=(double) QuantumRange*r;
410 *green=(double) QuantumRange*g;
411 *blue=(double) QuantumRange*b;
414static inline void ConvertHSVToRGB(
const double hue,
const double saturation,
415 const double value,
double *red,
double *green,
double *blue)
426 assert(red != (
double *) NULL);
427 assert(green != (
double *) NULL);
428 assert(blue != (
double *) NULL);
432 h-=360.0*floor(h/360.0);
434 x=c*(1.0-fabs(h-2.0*floor(h/2.0)-1.0));
435 switch ((
int) floor(h))
440 *red=(double) QuantumRange*(min+c);
441 *green=(double) QuantumRange*(min+x);
442 *blue=(double) QuantumRange*min;
447 *red=(double) QuantumRange*(min+x);
448 *green=(double) QuantumRange*(min+c);
449 *blue=(double) QuantumRange*min;
454 *red=(double) QuantumRange*min;
455 *green=(double) QuantumRange*(min+c);
456 *blue=(double) QuantumRange*(min+x);
461 *red=(double) QuantumRange*min;
462 *green=(double) QuantumRange*(min+x);
463 *blue=(double) QuantumRange*(min+c);
468 *red=(double) QuantumRange*(min+x);
469 *green=(double) QuantumRange*min;
470 *blue=(double) QuantumRange*(min+c);
475 *red=(double) QuantumRange*(min+c);
476 *green=(double) QuantumRange*min;
477 *blue=(double) QuantumRange*(min+x);
483static inline void ConvertHWBToRGB(
const double hue,
const double whiteness,
484 const double blackness,
double *red,
double *green,
double *blue)
500 assert(red != (
double *) NULL);
501 assert(green != (
double *) NULL);
502 assert(blue != (
double *) NULL);
504 if (fabs(hue-(-1.0)) < MagickEpsilon)
506 *red=(double) QuantumRange*v;
507 *green=(double) QuantumRange*v;
508 *blue=(double) QuantumRange*v;
511 i=CastDoubleToLong(floor(6.0*hue));
515 n=whiteness+f*(v-whiteness);
519 default: r=v; g=n; b=whiteness;
break;
520 case 1: r=n; g=v; b=whiteness;
break;
521 case 2: r=whiteness; g=v; b=n;
break;
522 case 3: r=whiteness; g=n; b=v;
break;
523 case 4: r=n; g=whiteness; b=v;
break;
524 case 5: r=v; g=whiteness; b=n;
break;
526 *red=(double) QuantumRange*r;
527 *green=(double) QuantumRange*g;
528 *blue=(double) QuantumRange*b;
531static inline void ConvertLabToXYZ(
const double L,
const double a,
const double b,
532 const IlluminantType illuminant,
double *X,
double *Y,
double *Z)
542 if ((x*x*x) > CIEEpsilon)
545 x=(116.0*x-16.0)/CIEK;
546 if (L > (CIEK*CIEEpsilon))
550 if ((z*z*z) > CIEEpsilon)
553 z=(116.0*z-16.0)/CIEK;
554 *X=illuminant_tristimulus[illuminant].x*x;
555 *Y=illuminant_tristimulus[illuminant].y*y;
556 *Z=illuminant_tristimulus[illuminant].z*z;
559static inline void ConvertLabToRGB(
const double L,
const double a,
560 const double b,
const IlluminantType illuminant,
double *red,
double *green,
568 ConvertLabToXYZ(100.0*L,255.0*(a-0.5),255.0*(b-0.5),illuminant,&X,&Y,&Z);
569 ConvertXYZToRGB(X,Y,Z,red,green,blue);
572static inline void ConvertLCHabToXYZ(
const double luma,
const double chroma,
573 const double hue,
const IlluminantType illuminant,
double *X,
double *Y,
576 ConvertLabToXYZ(luma,chroma*cos(DegreesToRadians(hue)),chroma*
577 sin(DegreesToRadians(hue)),illuminant,X,Y,Z);
580static inline void ConvertLCHabToRGB(
const double luma,
const double chroma,
581 const double hue,
const IlluminantType illuminant,
double *red,
double *green,
592 assert(red != (
double *) NULL);
593 assert(green != (
double *) NULL);
594 assert(blue != (
double *) NULL);
595 ConvertLCHabToXYZ(100.0*luma,255.0*(chroma-0.5),360.0*hue,illuminant,
597 ConvertXYZToRGB(X,Y,Z,red,green,blue);
600static inline void ConvertLuvToXYZ(
const double L,
const double u,
const double v,
601 const IlluminantType illuminant,
double *X,
double *Y,
double *Z)
606 if (L > (CIEK*CIEEpsilon))
607 *Y=(double) pow((L+16.0)/116.0,3.0);
610 gamma=PerceptibleReciprocal((((52.0*L*PerceptibleReciprocal(u+13.0*L*
611 (4.0*illuminant_tristimulus[illuminant].x/
612 (illuminant_tristimulus[illuminant].x+15.0*
613 illuminant_tristimulus[illuminant].y+3.0*
614 illuminant_tristimulus[illuminant].z))))-1.0)/3.0)-(-1.0/3.0));
615 *X=gamma*((*Y*((39.0*L*PerceptibleReciprocal(v+13.0*L*(9.0*
616 illuminant_tristimulus[illuminant].y/
617 (illuminant_tristimulus[illuminant].x+15.0*
618 illuminant_tristimulus[illuminant].y+3.0*
619 illuminant_tristimulus[illuminant].z))))-5.0))+5.0*(*Y));
620 *Z=(*X*(((52.0*L*PerceptibleReciprocal(u+13.0*L*(4.0*
621 illuminant_tristimulus[illuminant].x/
622 (illuminant_tristimulus[illuminant].x+15.0*
623 illuminant_tristimulus[illuminant].y+3.0*
624 illuminant_tristimulus[illuminant].z))))-1.0)/3.0))-5.0*(*Y);
627static inline void ConvertLCHuvToXYZ(
const double luma,
const double chroma,
628 const double hue,
const IlluminantType illuminant,
double *X,
double *Y,
631 ConvertLuvToXYZ(luma,chroma*cos(DegreesToRadians(hue)),chroma*
632 sin(DegreesToRadians(hue)),illuminant,X,Y,Z);
635static inline void ConvertLCHuvToRGB(
const double luma,
const double chroma,
636 const double hue,
const IlluminantType illuminant,
double *red,
double *green,
647 assert(red != (
double *) NULL);
648 assert(green != (
double *) NULL);
649 assert(blue != (
double *) NULL);
650 ConvertLCHuvToXYZ(100.0*luma,255.0*(chroma-0.5),360.0*hue,illuminant,
652 ConvertXYZToRGB(X,Y,Z,red,green,blue);
655static inline void ConvertLMSToXYZ(
const double L,
const double M,
const double S,
656 double *X,
double *Y,
double *Z)
658 *X=1.096123820835514*L-0.278869000218287*M+0.182745179382773*S;
659 *Y=0.454369041975359*L+0.473533154307412*M+0.072097803717229*S;
660 *Z=(-0.009627608738429)*L-0.005698031216113*M+1.015325639954543*S;
663static inline void ConvertLMSToRGB(
const double L,
const double M,
664 const double S,
double *red,
double *green,
double *blue)
671 ConvertLMSToXYZ(L,M,S,&X,&Y,&Z);
672 ConvertXYZToRGB(X,Y,Z,red,green,blue);
675static inline void ConvertDisplayP3ToXYZ(
const double red,
const double green,
676 const double blue,
double *X,
double *Y,
double *Z)
686 r=QuantumScale*DecodePixelGamma((
double) QuantumRange*red);
687 g=QuantumScale*DecodePixelGamma((
double) QuantumRange*green);
688 b=QuantumScale*DecodePixelGamma((
double) QuantumRange*blue);
689 *X=0.4865709486482162*r+0.26566769316909306*g+0.1982172852343625*b;
690 *Y=0.2289745640697488*r+0.69173852183650640*g+0.0792869140937450*b;
691 *Z=0.0000000000000000*r+0.04511338185890264*g+1.0439443689009760*b;
694static inline void ConvertDisplayP3ToRGB(
const double r,
const double g,
695 const double b,
double *red,
double *green,
double *blue)
702 ConvertDisplayP3ToXYZ(r,g,b,&X,&Y,&Z);
703 ConvertXYZToRGB(X,Y,Z,red,green,blue);
706static inline void ConvertLuvToRGB(
const double L,
const double u,
707 const double v,
const IlluminantType illuminant,
double *red,
double *green,
715 ConvertLuvToXYZ(100.0*L,354.0*u-134.0,262.0*v-140.0,illuminant,&X,&Y,&Z);
716 ConvertXYZToRGB(X,Y,Z,red,green,blue);
719static inline void ConvertProPhotoToXYZ(
const double red,
const double green,
720 const double blue,
double *X,
double *Y,
double *Z)
730 r=QuantumScale*DecodePixelGamma((
double) QuantumRange*red);
731 g=QuantumScale*DecodePixelGamma((
double) QuantumRange*green);
732 b=QuantumScale*DecodePixelGamma((
double) QuantumRange*blue);
733 *X=0.4865709486482162*r+0.26566769316909306*g+0.1982172852343625*b;
734 *X=0.7977604896723027*r+0.13518583717574031*g+0.03134934958152480000*b;
735 *Y=0.2880711282292934*r+0.71184321781010140*g+0.00008565396060525902*b;
736 *Z=0.0000000000000000*r+0.00000000000000000*g+0.82510460251046010000*b;
739static inline void ConvertProPhotoToRGB(
const double r,
const double g,
740 const double b,
double *red,
double *green,
double *blue)
747 ConvertProPhotoToXYZ(r,g,b,&X,&Y,&Z);
748 ConvertXYZToRGB(X,Y,Z,red,green,blue);
751static inline void ConvertXYZToCAT02LMS(
const double X,
const double Y,
752 const double Z,
double *L,
double *M,
double *S)
754 *L=0.7328*X+0.4296*Y-0.1624*Z;
755 *M=(-0.7036)*X+1.6975*Y+0.0061*Z;
756 *S=0.0030*X+0.0136*Y+0.9834*Z;
759static inline void ConvertRGBToXYZ(
const double red,
const double green,
760 const double blue,
double *X,
double *Y,
double *Z)
770 r=QuantumScale*DecodePixelGamma(red);
771 g=QuantumScale*DecodePixelGamma(green);
772 b=QuantumScale*DecodePixelGamma(blue);
773 *X=(0.4123955889674142161*r)+(0.3575834307637148171*g)+
774 (0.1804926473817015735*b);
775 *Y=(0.2125862307855955516*r)+(0.7151703037034108499*g)+
776 (0.07220049864333622685*b);
777 *Z=(0.01929721549174694484*r)+(0.1191838645808485318*g)+
778 (0.9504971251315797660*b);
781static inline void ConvertRGBToCAT02LMS(
const double R,
const double G,
782 const double B,
double *L,
double *M,
double *S)
789 ConvertRGBToXYZ(R,G,B,&X,&Y,&Z);
790 ConvertXYZToCAT02LMS(X,Y,Z,L,M,S);
793static inline void ConvertRGBToCMY(
const double red,
const double green,
794 const double blue,
double *cyan,
double *magenta,
double *yellow)
796 *cyan=QuantumScale*((double) QuantumRange-red);
797 *magenta=QuantumScale*((double) QuantumRange-green);
798 *yellow=QuantumScale*((double) QuantumRange-blue);
801static inline void ConvertRGBToHCL(
const double red,
const double green,
802 const double blue,
double *hue,
double *chroma,
double *luma)
812 assert(hue != (
double *) NULL);
813 assert(chroma != (
double *) NULL);
814 assert(luma != (
double *) NULL);
815 max=MagickMax(red,MagickMax(green,blue));
816 c=max-(double) MagickMin(red,MagickMin(green,blue));
818 if (fabs(c) < MagickEpsilon)
821 if (fabs(red-max) < MagickEpsilon)
822 h=fmod((green-blue)/c+6.0,6.0);
824 if (fabs(green-max) < MagickEpsilon)
825 h=((blue-red)/c)+2.0;
827 if (fabs(blue-max) < MagickEpsilon)
828 h=((red-green)/c)+4.0;
830 *chroma=QuantumScale*c;
831 *luma=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
834static inline void ConvertRGBToHCLp(
const double red,
const double green,
835 const double blue,
double *hue,
double *chroma,
double *luma)
845 assert(hue != (
double *) NULL);
846 assert(chroma != (
double *) NULL);
847 assert(luma != (
double *) NULL);
848 max=MagickMax(red,MagickMax(green,blue));
849 c=max-MagickMin(red,MagickMin(green,blue));
851 if (fabs(c) < MagickEpsilon)
854 if (fabs(red-max) < MagickEpsilon)
855 h=fmod((green-blue)/c+6.0,6.0);
857 if (fabs(green-max) < MagickEpsilon)
858 h=((blue-red)/c)+2.0;
860 if (fabs(blue-max) < MagickEpsilon)
861 h=((red-green)/c)+4.0;
863 *chroma=QuantumScale*c;
864 *luma=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
867static inline void ConvertRGBToHSB(
const double red,
const double green,
868 const double blue,
double *hue,
double *saturation,
double *brightness)
878 assert(hue != (
double *) NULL);
879 assert(saturation != (
double *) NULL);
880 assert(brightness != (
double *) NULL);
884 min=red < green ? red : green;
887 max=red > green ? red : green;
890 if (fabs(max) < MagickEpsilon)
893 *saturation=delta/max;
894 *brightness=QuantumScale*max;
895 if (fabs(delta) < MagickEpsilon)
897 if (fabs(red-max) < MagickEpsilon)
898 *hue=(green-blue)/delta;
900 if (fabs(green-max) < MagickEpsilon)
901 *hue=2.0+(blue-red)/delta;
903 *hue=4.0+(red-green)/delta;
909static inline void ConvertRGBToHSI(
const double red,
const double green,
910 const double blue,
double *hue,
double *saturation,
double *intensity)
919 assert(hue != (
double *) NULL);
920 assert(saturation != (
double *) NULL);
921 assert(intensity != (
double *) NULL);
922 *intensity=(QuantumScale*red+QuantumScale*green+QuantumScale*blue)/3.0;
923 if (*intensity <= 0.0)
929 *saturation=1.0-MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
930 QuantumScale*blue))/(*intensity);
931 alpha=0.5*(2.0*QuantumScale*red-QuantumScale*green-QuantumScale*blue);
932 beta=0.8660254037844385*(QuantumScale*green-QuantumScale*blue);
933 *hue=atan2(beta,alpha)*(180.0/MagickPI)/360.0;
938static inline void ConvertXYZToAdobe98(
const double X,
const double Y,
939 const double Z,
double *red,
double *green,
double *blue)
946 r=2.041587903810746500*X-0.56500697427885960*Y-0.34473135077832956*Z;
947 g=(-0.969243636280879500)*X+1.87596750150772020*Y+0.04155505740717557*Z;
948 b=0.013444280632031142*X-0.11836239223101838*Y+1.01517499439120540*Z;
949 *red=QuantumScale*EncodePixelGamma((
double) QuantumRange*r);
950 *green=QuantumScale*EncodePixelGamma((
double) QuantumRange*g);
951 *blue=QuantumScale*EncodePixelGamma((
double) QuantumRange*b);
954static inline void ConvertRGBToAdobe98(
const double red,
const double green,
955 const double blue,
double *r,
double *g,
double *b)
962 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
963 ConvertXYZToAdobe98(X,Y,Z,r,g,b);
966static inline void ConvertXYZToDisplayP3(
const double X,
const double Y,
967 const double Z,
double *red,
double *green,
double *blue)
974 r=2.49349691194142500*X-0.93138361791912390*Y-0.402710784450716840*Z;
975 g=(-0.82948896956157470)*X+1.76266406031834630*Y+0.023624685841943577*Z;
976 b=0.03584583024378447*X-0.07617238926804182*Y+0.956884524007687200*Z;
977 *red=QuantumScale*EncodePixelGamma((
double) QuantumRange*r);
978 *green=QuantumScale*EncodePixelGamma((
double) QuantumRange*g);
979 *blue=QuantumScale*EncodePixelGamma((
double) QuantumRange*b);
982static inline void ConvertRGBToDisplayP3(
const double red,
const double green,
983 const double blue,
double *r,
double *g,
double *b)
990 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
991 ConvertXYZToDisplayP3(X,Y,Z,r,g,b);
994static inline void ConvertRGBToHSV(
const double red,
const double green,
995 const double blue,
double *hue,
double *saturation,
double *value)
1005 assert(hue != (
double *) NULL);
1006 assert(saturation != (
double *) NULL);
1007 assert(value != (
double *) NULL);
1008 max=MagickMax(QuantumScale*red,MagickMax(QuantumScale*green,
1009 QuantumScale*blue));
1010 min=MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
1011 QuantumScale*blue));
1020 if (fabs(max-QuantumScale*red) < MagickEpsilon)
1022 *hue=(QuantumScale*green-QuantumScale*blue)/c;
1023 if ((QuantumScale*green) < (QuantumScale*blue))
1027 if (fabs(max-QuantumScale*green) < MagickEpsilon)
1028 *hue=2.0+(QuantumScale*blue-QuantumScale*red)/c;
1030 *hue=4.0+(QuantumScale*red-QuantumScale*green)/c;
1032 *saturation=c*PerceptibleReciprocal(max);
1035static inline void ConvertRGBToHWB(
const double red,
const double green,
1036 const double blue,
double *hue,
double *whiteness,
double *blackness)
1047 assert(hue != (
double *) NULL);
1048 assert(whiteness != (
double *) NULL);
1049 assert(blackness != (
double *) NULL);
1050 w=MagickMin(red,MagickMin(green,blue));
1051 v=MagickMax(red,MagickMax(green,blue));
1052 *blackness=1.0-QuantumScale*v;
1053 *whiteness=QuantumScale*w;
1054 if (fabs(v-w) < MagickEpsilon)
1059 f=(fabs(red-w) < MagickEpsilon) ? green-blue :
1060 ((fabs(green-w) < MagickEpsilon) ? blue-red : red-green);
1061 p=(fabs(red-w) < MagickEpsilon) ? 3.0 :
1062 ((fabs(green-w) < MagickEpsilon) ? 5.0 : 1.0);
1063 *hue=(p-f/(v-1.0*w))/6.0;
1066static inline void ConvertXYZToLab(
const double X,
const double Y,
const double Z,
1067 const IlluminantType illuminant,
double *L,
double *a,
double *b)
1074 if ((X/illuminant_tristimulus[illuminant].x) > CIEEpsilon)
1075 x=pow(X/illuminant_tristimulus[illuminant].x,1.0/3.0);
1077 x=(CIEK*X/illuminant_tristimulus[illuminant].x+16.0)/116.0;
1078 if ((Y/illuminant_tristimulus[illuminant].y) > CIEEpsilon)
1079 y=pow(Y/illuminant_tristimulus[illuminant].y,1.0/3.0);
1081 y=(CIEK*Y/illuminant_tristimulus[illuminant].y+16.0)/116.0;
1082 if ((Z/illuminant_tristimulus[illuminant].z) > CIEEpsilon)
1083 z=pow(Z/illuminant_tristimulus[illuminant].z,1.0/3.0);
1085 z=(CIEK*Z/illuminant_tristimulus[illuminant].z+16.0)/116.0;
1086 *L=((116.0*y)-16.0)/100.0;
1087 *a=(500.0*(x-y))/255.0+0.5;
1088 *b=(200.0*(y-z))/255.0+0.5;
1091static inline void ConvertRGBToLab(
const double red,
const double green,
1092 const double blue,
const IlluminantType illuminant,
double *L,
double *a,
1100 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
1101 ConvertXYZToLab(X,Y,Z,illuminant,L,a,b);
1104static inline void ConvertXYZToLCHab(
const double X,
const double Y,
1105 const double Z,
const IlluminantType illuminant,
double *luma,
double *chroma,
1112 ConvertXYZToLab(X,Y,Z,illuminant,luma,&a,&b);
1113 *chroma=hypot(a-0.5,b-0.5)/1.0+0.5;
1114 *hue=180.0*atan2(b-0.5,a-0.5)/MagickPI/360.0;
1119static inline void ConvertRGBToLCHab(
const double red,
const double green,
1120 const double blue,
const IlluminantType illuminant,
double *luma,
double *chroma,
1131 assert(luma != (
double *) NULL);
1132 assert(chroma != (
double *) NULL);
1133 assert(hue != (
double *) NULL);
1134 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
1135 ConvertXYZToLCHab(X,Y,Z,illuminant,luma,chroma,hue);
1138static inline void ConvertXYZToLuv(
const double X,
const double Y,
const double Z,
1139 const IlluminantType illuminant,
double *L,
double *u,
double *v)
1144 if ((Y/illuminant_tristimulus[illuminant].y) > CIEEpsilon)
1145 *L=(double) (116.0*pow(Y/illuminant_tristimulus[illuminant].y,
1148 *L=CIEK*(Y/illuminant_tristimulus[illuminant].y);
1149 alpha=PerceptibleReciprocal(X+15.0*Y+3.0*Z);
1150 *u=13.0*(*L)*((4.0*alpha*X)-(4.0*illuminant_tristimulus[illuminant].x/
1151 (illuminant_tristimulus[illuminant].x+15.0*
1152 illuminant_tristimulus[illuminant].y+3.0*
1153 illuminant_tristimulus[illuminant].z)));
1154 *v=13.0*(*L)*((9.0*alpha*Y)-(9.0*illuminant_tristimulus[illuminant].y/
1155 (illuminant_tristimulus[illuminant].x+15.0*
1156 illuminant_tristimulus[illuminant].y+3.0*
1157 illuminant_tristimulus[illuminant].z)));
1159 *u=(*u+134.0)/354.0;
1160 *v=(*v+140.0)/262.0;
1163static inline void ConvertXYZToLCHuv(
const double X,
const double Y,
1164 const double Z,
const IlluminantType illuminant,
double *luma,
double *chroma,
1171 ConvertXYZToLuv(X,Y,Z,illuminant,luma,&u,&v);
1172 *chroma=hypot(354.0*u-134.0,262.0*v-140.0)/255.0+0.5;
1173 *hue=180.0*atan2(262.0*v-140.0,354.0*u-134.0)/MagickPI/360.0;
1178static inline void ConvertRGBToLCHuv(
const double red,
const double green,
1179 const double blue,
const IlluminantType illuminant,
double *luma,
double *chroma,
1190 assert(luma != (
double *) NULL);
1191 assert(chroma != (
double *) NULL);
1192 assert(hue != (
double *) NULL);
1193 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
1194 ConvertXYZToLCHuv(X,Y,Z,illuminant,luma,chroma,hue);
1197static inline void ConvertXYZToProPhoto(
const double X,
const double Y,
1198 const double Z,
double *red,
double *green,
double *blue)
1205 r=1.3457989731028281*X-0.25558010007997534*Y-0.05110628506753401*Z;
1206 g=(-0.5446224939028347)*X+1.50823274131327810*Y+0.02053603239147973*Z;
1207 b=0.0000000000000000*X+0.0000000000000000*Y+1.21196754563894540*Z;
1208 *red=QuantumScale*EncodePixelGamma((
double) QuantumRange*r);
1209 *green=QuantumScale*EncodePixelGamma((
double) QuantumRange*g);
1210 *blue=QuantumScale*EncodePixelGamma((
double) QuantumRange*b);
1213static inline void ConvertRGBToProPhoto(
const double red,
const double green,
1214 const double blue,
double *r,
double *g,
double *b)
1221 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
1222 ConvertXYZToProPhoto(X,Y,Z,r,g,b);
1225static inline void ConvertXYZToLMS(
const double x,
const double y,
1226 const double z,
double *L,
double *M,
double *S)
1228 *L=0.7328*x+0.4296*y-0.1624*z;
1229 *M=(-0.7036*x+1.6975*y+0.0061*z);
1230 *S=0.0030*x+0.0136*y+0.9834*z;
1233static inline void ConvertRGBToLMS(
const double red,
const double green,
1234 const double blue,
double *L,
double *M,
double *S)
1241 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
1242 ConvertXYZToLMS(X,Y,Z,L,M,S);
1245static inline void ConvertRGBToLuv(
const double red,
const double green,
1246 const double blue,
const IlluminantType illuminant,
double *L,
double *u,
1254 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
1255 ConvertXYZToLuv(X,Y,Z,illuminant,L,u,v);
1258static inline void ConvertRGBToxyY(
const double red,
const double green,
1259 const double blue,
double *low_x,
double *low_y,
double *cap_Y)
1267 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
1268 gamma=PerceptibleReciprocal(X+Y+Z);
1274static inline void ConvertXYZToJzazbz(
const double X,
const double Y,
1275 const double Z,
const double white_luminance,
double *Jz,
double *az,
double *bz)
1277#define Jzazbz_b (1.15)
1278#define Jzazbz_g (0.66)
1279#define Jzazbz_c1 (3424.0/4096.0)
1280#define Jzazbz_c2 (2413.0/128.0)
1281#define Jzazbz_c3 (2392.0/128.0)
1282#define Jzazbz_n (2610.0/16384.0)
1283#define Jzazbz_p (1.7*2523.0/32.0)
1284#define Jzazbz_d (-0.56)
1285#define Jzazbz_d0 (1.6295499532821566e-11)
1286#define Jzazbz_LX (0.41478972)
1287#define Jzazbz_LY (0.579999)
1288#define Jzazbz_LZ (0.0146480)
1289#define Jzazbz_MX (-0.2015100)
1290#define Jzazbz_MY (1.120649)
1291#define Jzazbz_MZ (0.0531008)
1292#define Jzazbz_SX (-0.0166008)
1293#define Jzazbz_SY (0.264800)
1294#define Jzazbz_SZ (0.6684799)
1295#define Jzazbz_aL (3.52400)
1296#define Jzazbz_aM (-4.066708)
1297#define Jzazbz_aS (0.542708)
1298#define Jzazbz_bL (0.199076)
1299#define Jzazbz_bM (1.096799)
1300#define Jzazbz_bS (-1.295875)
1327 WLr=PerceptibleReciprocal(white_luminance);
1328 Xp=Z+Jzazbz_b*(X-Z);
1329 Yp=X+Jzazbz_g*(Y-X);
1339 gL=pow(L*WLr,Jzazbz_n);
1340 gM=pow(M*WLr,Jzazbz_n);
1341 gS=pow(S*WLr,Jzazbz_n);
1342 nL=Jzazbz_c1+Jzazbz_c2*gL;
1343 nM=Jzazbz_c1+Jzazbz_c2*gM;
1344 nS=Jzazbz_c1+Jzazbz_c2*gS;
1345 dL=1.0+Jzazbz_c3*gL;
1346 dM=1.0+Jzazbz_c3*gM;
1347 dS=1.0+Jzazbz_c3*gS;
1348 Lp=pow(nL/dL,Jzazbz_p);
1349 Mp=pow(nM/dM,Jzazbz_p);
1350 Sp=pow(nS/dS,Jzazbz_p);
1353 J=(JdI+Iz)/(JdI+1.0)-Jzazbz_d0;
1360 *Jz=IsNaN(J) != 0 ? 0.0 : J;
1361 *az=IsNaN(a) != 0 ? 0.5 : a;
1362 *bz=IsNaN(b) != 0 ? 0.5 : b;
1365static inline void ConvertRGBToJzazbz(
const double red,
const double green,
1366 const double blue,
const double white_luminance,
double *Jz,
double *az,
1374 ConvertRGBToXYZ(red,blue,green,&X,&Y,&Z);
1375 ConvertXYZToJzazbz(X,Y,Z,white_luminance,Jz,az,bz);
1378static inline void ConvertJzazbzToXYZ(
const double Jz,
const double az,
1379 const double bz,
const double white_luminance,
double *X,
double *Y,
double *Z)
1381#define Jzazbz_Ca (0.138605043271539)
1382#define Jzazbz_Cb (0.0580473161561189)
1383#define Jzazbz_Sa (-0.0960192420263189)
1384#define Jzazbz_Sb (-0.811891896056039)
1385#define Jzazbz_XL (1.92422643578761)
1386#define Jzazbz_XM (-1.00479231259537)
1387#define Jzazbz_XS (0.037651404030618)
1388#define Jzazbz_YL (0.350316762094999)
1389#define Jzazbz_YM (0.726481193931655)
1390#define Jzazbz_YS (-0.065384422948085)
1391#define Jzazbz_ZL (-0.0909828109828476)
1392#define Jzazbz_ZM (-0.312728290523074)
1393#define Jzazbz_ZS (1.52276656130526)
1394#define mJzazbz_c3 (-2392.0/128.0)
1425 C=Jzazbz_Ca*azz+Jzazbz_Cb*bzz;
1426 Sp=g/(1.0+Jzazbz_d*(1.0-g));
1439 dL=Jzazbz_c2+mJzazbz_c3*gL;
1440 dM=Jzazbz_c2+mJzazbz_c3*gM;
1441 dS=Jzazbz_c2+mJzazbz_c3*gS;
1457 Zp=IsNaN(Zp) != 0 ? 0.0 : Zp;
1458 Xp=Zp+(Xp-Zp)/Jzazbz_b;
1459 Xp=IsNaN(Xp) != 0 ? 0.0 : Xp;
1460 Yp=Xp+(Yp-Xp)/Jzazbz_g;
1461 Yp=IsNaN(Yp) != 0 ? 0.0 : Yp;
1467static inline void ConvertJzazbzToRGB(
const double Jz,
const double az,
1468 const double bz,
const double white_luminance,
double *red,
double *green,
1476 ConvertJzazbzToXYZ(Jz,az,bz,white_luminance,&X,&Y,&Z);
1477 ConvertXYZToRGB(X,Y,Z,red,blue,green);
1480static inline void ConvertOklabToRGB(
const double L,
const double a,
1481 const double b,
double *red,
double *green,
double *blue)
1483#define Oklab_la (0.3963377774)
1484#define Oklab_lb (0.2158037573)
1485#define Oklab_ma (-0.1055613458)
1486#define Oklab_mb (-0.0638541728)
1487#define Oklab_sa (-0.0894841775)
1488#define Oklab_sb (-1.2914855480)
1489#define Oklab_Rl (4.0767416621)
1490#define Oklab_Rm (-3.3077115913)
1491#define Oklab_Rs (0.2309699292)
1492#define Oklab_Gl (-1.2684380046)
1493#define Oklab_Gm (2.6097574011)
1494#define Oklab_Gs (-0.3413193965)
1495#define Oklab_Bl (-0.0041960863)
1496#define Oklab_Bm (-0.7034186147)
1497#define Oklab_Bs (1.7076147010)
1520 l=L+Oklab_la*aa+Oklab_lb*bb;
1521 m=L+Oklab_ma*aa+Oklab_mb*bb;
1522 s=L+Oklab_sa*aa+Oklab_sb*bb;
1526 Rl=Oklab_Rl*(double) QuantumRange;
1527 Rm=Oklab_Rm*(double) QuantumRange;
1528 Rs=Oklab_Rs*(double) QuantumRange;
1529 Gl=Oklab_Gl*(double) QuantumRange;
1530 Gm=Oklab_Gm*(double) QuantumRange;
1531 Gs=Oklab_Gs*(double) QuantumRange;
1532 Bl=Oklab_Bl*(double) QuantumRange;
1533 Bm=Oklab_Bm*(double) QuantumRange;
1534 Bs=Oklab_Bs*(double) QuantumRange;
1538 *red=EncodePixelGamma(R);
1539 *green=EncodePixelGamma(G);
1540 *blue=EncodePixelGamma(B);
1543static inline void ConvertOklchToRGB(
const double L,
const double C,
1544 const double h,
double *red,
double *green,
double *blue)
1550 a=C*cos(2.0*MagickPI*h);
1551 b=C*sin(2.0*MagickPI*h);
1552 ConvertOklabToRGB(L,a,b,red,green,blue);
1555static inline void ConvertRGBToOklab(
const double red,
const double green,
1556 const double blue,
double *L,
double *a,
double *b)
1558#define Oklab_lR (0.4122214708)
1559#define Oklab_lG (0.5363325363)
1560#define Oklab_lB (0.0514459929)
1561#define Oklab_mR (0.2119034982)
1562#define Oklab_mG (0.6806995451)
1563#define Oklab_mB (0.1073969566)
1564#define Oklab_sR (0.0883024619)
1565#define Oklab_sG (0.2817188376)
1566#define Oklab_sB (0.6299787005)
1567#define Oklab_Ll (0.2104542553)
1568#define Oklab_Lm (0.7936177850)
1569#define Oklab_Ls (-0.0040720468)
1570#define Oklab_al (1.9779984951)
1571#define Oklab_am (-2.4285922050)
1572#define Oklab_as (0.4505937099)
1573#define Oklab_bl (0.0259040371)
1574#define Oklab_bm (0.7827717662)
1575#define Oklab_bs (-0.8086757660)
1594 R=DecodePixelGamma(red);
1595 G=DecodePixelGamma(green);
1596 B=DecodePixelGamma(blue);
1597 lR=Oklab_lR*QuantumScale;
1598 lG=Oklab_lG*QuantumScale;
1599 lB=Oklab_lB*QuantumScale;
1600 mR=Oklab_mR*QuantumScale;
1601 mG=Oklab_mG*QuantumScale;
1602 mB=Oklab_mB*QuantumScale;
1603 sR=Oklab_sR*QuantumScale;
1604 sG=Oklab_sG*QuantumScale;
1605 sB=Oklab_sB*QuantumScale;
1612 *L=Oklab_Ll*l+Oklab_Lm*m+Oklab_Ls*s;
1613 *a=Oklab_al*l+Oklab_am*m+Oklab_as*s+0.5;
1614 *b=Oklab_bl*l+Oklab_bm*m+Oklab_bs*s+0.5;
1617static inline void ConvertRGBToOklch(
const double red,
const double green,
1618 const double blue,
double *L,
double *C,
double *h)
1624 ConvertRGBToOklab(red,green,blue,L,&a,&b);
1626 *h=0.5+0.5*atan2(-b,-a)/MagickPI;
1629static inline void ConvertRGBToYDbDr(
const double red,
const double green,
1630 const double blue,
double *Y,
double *Db,
double *Dr)
1632 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
1633 *Db=QuantumScale*(-0.450*red-0.883*green+1.333*blue)+0.5;
1634 *Dr=QuantumScale*(-1.333*red+1.116*green+0.217*blue)+0.5;
1637static inline void ConvertRGBToYIQ(
const double red,
const double green,
1638 const double blue,
double *Y,
double *I,
double *Q)
1640 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
1641 *I=QuantumScale*(0.595716*red-0.274453*green-0.321263*blue)+0.5;
1642 *Q=QuantumScale*(0.211456*red-0.522591*green+0.311135*blue)+0.5;
1645static inline void ConvertRGBToYPbPr(
const double red,
const double green,
1646 const double blue,
double *Y,
double *Pb,
double *Pr)
1648 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
1649 *Pb=QuantumScale*((-0.1687367)*red-0.331264*green+0.5*blue)+0.5;
1650 *Pr=QuantumScale*(0.5*red-0.418688*green-0.081312*blue)+0.5;
1653static inline void ConvertRGBToYCbCr(
const double red,
const double green,
1654 const double blue,
double *Y,
double *Cb,
double *Cr)
1656 ConvertRGBToYPbPr(red,green,blue,Y,Cb,Cr);
1659static inline void ConvertRGBToYUV(
const double red,
const double green,
1660 const double blue,
double *Y,
double *U,
double *V)
1662 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
1663 *U=QuantumScale*((-0.147)*red-0.289*green+0.436*blue)+0.5;
1664 *V=QuantumScale*(0.615*red-0.515*green-0.100*blue)+0.5;
1667static inline void ConvertRGBToCMYK(
PixelInfo *pixel)
1678 if (pixel->colorspace != sRGBColorspace)
1680 red=QuantumScale*pixel->red;
1681 green=QuantumScale*pixel->green;
1682 blue=QuantumScale*pixel->blue;
1686 red=QuantumScale*DecodePixelGamma(pixel->red);
1687 green=QuantumScale*DecodePixelGamma(pixel->green);
1688 blue=QuantumScale*DecodePixelGamma(pixel->blue);
1690 if ((fabs((
double) red) < MagickEpsilon) &&
1691 (fabs((
double) green) < MagickEpsilon) &&
1692 (fabs((
double) blue) < MagickEpsilon))
1694 pixel->black=(MagickRealType) QuantumRange;
1697 cyan=(MagickRealType) (1.0-red);
1698 magenta=(MagickRealType) (1.0-green);
1699 yellow=(MagickRealType) (1.0-blue);
1701 if (magenta < black)
1705 cyan=(MagickRealType) (PerceptibleReciprocal(1.0-black)*(cyan-black));
1706 magenta=(MagickRealType) (PerceptibleReciprocal(1.0-black)*(magenta-black));
1707 yellow=(MagickRealType) (PerceptibleReciprocal(1.0-black)*(yellow-black));
1708 pixel->colorspace=CMYKColorspace;
1709 pixel->red=(MagickRealType) QuantumRange*cyan;
1710 pixel->green=(MagickRealType) QuantumRange*magenta;
1711 pixel->blue=(MagickRealType) QuantumRange*yellow;
1712 pixel->black=(MagickRealType) QuantumRange*black;
1715static inline void ConvertYPbPrToRGB(
const double Y,
const double Pb,
1716 const double Pr,
double *red,
double *green,
double *blue)
1718 *red=(double) QuantumRange*(0.99999999999914679361*Y-1.2188941887145875e-06*
1719 (Pb-0.5)+1.4019995886561440468*(Pr-0.5));
1720 *green=(double) QuantumRange*(0.99999975910502514331*Y-0.34413567816504303521*
1721 (Pb-0.5)-0.71413649331646789076*(Pr-0.5));
1722 *blue=(double) QuantumRange*(1.00000124040004623180*Y+1.77200006607230409200*
1723 (Pb-0.5)+2.1453384174593273e-06*(Pr-0.5));
1726static inline void ConvertYCbCrToRGB(
const double Y,
const double Cb,
1727 const double Cr,
double *red,
double *green,
double *blue)
1729 ConvertYPbPrToRGB(Y,Cb,Cr,red,green,blue);
1732static inline void ConvertYDbDrToRGB(
const double Y,
const double Db,
1733 const double Dr,
double *red,
double *green,
double *blue)
1735 *red=(double) QuantumRange*(Y+9.2303716147657e-05*(Db-0.5)-
1736 0.52591263066186533*(Dr-0.5));
1737 *green=(double) QuantumRange*(Y-0.12913289889050927*(Db-0.5)+
1738 0.26789932820759876*(Dr-0.5));
1739 *blue=(double) QuantumRange*(Y+0.66467905997895482*(Db-0.5)-
1740 7.9202543533108e-05*(Dr-0.5));
1743static inline void ConvertYIQToRGB(
const double Y,
const double I,
const double Q,
1744 double *red,
double *green,
double *blue)
1746 *red=(double) QuantumRange*(Y+0.9562957197589482261*(I-0.5)+
1747 0.6210244164652610754*(Q-0.5));
1748 *green=(double) QuantumRange*(Y-0.2721220993185104464*(I-0.5)-
1749 0.6473805968256950427*(Q-0.5));
1750 *blue=(double) QuantumRange*(Y-1.1069890167364901945*(I-0.5)+
1751 1.7046149983646481374*(Q-0.5));
1754static inline void ConvertxyYToRGB(
const double low_x,
const double low_y,
1755 const double cap_Y,
double *red,
double *green,
double *blue)
1763 gamma=PerceptibleReciprocal(low_y);
1764 X=gamma*cap_Y*low_x;
1766 Z=gamma*cap_Y*(1.0-low_x-low_y);
1767 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1770static inline void ConvertYUVToRGB(
const double Y,
const double U,
const double V,
1771 double *red,
double *green,
double *blue)
1773 *red=(double) QuantumRange*(Y-3.945707070708279e-05*(U-0.5)+
1774 1.1398279671717170825*(V-0.5));
1775 *green=(double) QuantumRange*(Y-0.3946101641414141437*(U-0.5)-
1776 0.5805003156565656797*(V-0.5));
1777 *blue=(double) QuantumRange*(Y+2.0319996843434342537*(U-0.5)-
1778 4.813762626262513e-04*(V-0.5));
1781static inline MagickBooleanType IsCMYKColorspace(
1782 const ColorspaceType colorspace)
1784 if (colorspace == CMYKColorspace)
1786 return(MagickFalse);
1789static inline MagickBooleanType IsGrayColorspace(
1790 const ColorspaceType colorspace)
1792 if ((colorspace == LinearGRAYColorspace) || (colorspace == GRAYColorspace))
1794 return(MagickFalse);
1797static inline MagickBooleanType IsGrayImageType(
const ImageType type)
1799 if ((type == GrayscaleType) || (type == GrayscaleAlphaType) ||
1800 (type == BilevelType))
1802 return(MagickFalse);
1805static inline MagickBooleanType IsHueCompatibleColorspace(
1806 const ColorspaceType colorspace)
1808 if ((colorspace == HCLColorspace) || (colorspace == HCLpColorspace) ||
1809 (colorspace == HSBColorspace) || (colorspace == HSIColorspace) ||
1810 (colorspace == HSLColorspace) || (colorspace == HSVColorspace))
1812 return(MagickFalse);
1815static inline MagickBooleanType IsLabCompatibleColorspace(
1816 const ColorspaceType colorspace)
1818 if ((colorspace == LabColorspace) || (colorspace == LCHColorspace) ||
1819 (colorspace == LCHabColorspace) || (colorspace == LCHuvColorspace) ||
1820 (colorspace == OklabColorspace) || (colorspace == OklchColorspace))
1822 return(MagickFalse);
1825static inline MagickBooleanType IsRGBColorspace(
const ColorspaceType colorspace)
1827 if ((colorspace == RGBColorspace) || (colorspace == scRGBColorspace) ||
1828 (colorspace == LinearGRAYColorspace))
1830 return(MagickFalse);
1833static inline MagickBooleanType IssRGBColorspace(
1834 const ColorspaceType colorspace)
1836 if ((colorspace == sRGBColorspace) || (colorspace == TransparentColorspace))
1838 return(MagickFalse);
1841static inline MagickBooleanType IssRGBCompatibleColorspace(
1842 const ColorspaceType colorspace)
1844 if ((colorspace == sRGBColorspace) || (colorspace == RGBColorspace) ||
1845 (colorspace == Adobe98Colorspace) || (colorspace == ProPhotoColorspace) ||
1846 (colorspace == DisplayP3Colorspace) || (colorspace == scRGBColorspace) ||
1847 (colorspace == TransparentColorspace) || (colorspace == GRAYColorspace) ||
1848 (colorspace == LinearGRAYColorspace))
1850 return(MagickFalse);
1853static inline MagickBooleanType IsYCbCrCompatibleColorspace(
1854 const ColorspaceType colorspace)
1856 if ((colorspace == YCbCrColorspace) ||
1857 (colorspace == Rec709YCbCrColorspace) ||
1858 (colorspace == Rec601YCbCrColorspace))
1860 return(MagickFalse);
1863extern MagickPrivate
void
1864 ConvertGenericToRGB(
const ColorspaceType,
const double,
const double,
1865 const double,
const double,
const IlluminantType,
double *,
double *,
double *),
1866 ConvertRGBToGeneric(
const ColorspaceType,
const double,
const double,
1867 const double,
const double,
const IlluminantType,
double *,
double *,
double *);
1869#if defined(__cplusplus) || defined(c_plusplus)