00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef MAGICKCORE_GEM_PRIVATE_H
00019 #define MAGICKCORE_GEM_PRIVATE_H
00020
00021 #include "magick/pixel-accessor.h"
00022
00023 #if defined(__cplusplus) || defined(c_plusplus)
00024 extern "C" {
00025 #endif
00026
00027 #define D65X 0.950456
00028 #define D65Y 1.0
00029 #define D65Z 1.088754
00030 #define CIEEpsilon (216.0/24389.0)
00031 #define CIEK (24389.0/27.0)
00032
00033 static inline void ConvertLabToXYZ(const double L,const double a,const double b,
00034 double *X,double *Y,double *Z)
00035 {
00036 double
00037 x,
00038 y,
00039 z;
00040
00041 assert(X != (double *) NULL);
00042 assert(Y != (double *) NULL);
00043 assert(Z != (double *) NULL);
00044 y=(L+16.0)/116.0;
00045 x=y+a/500.0;
00046 z=y-b/200.0;
00047 if ((x*x*x) > CIEEpsilon)
00048 x=(x*x*x);
00049 else
00050 x=(116.0*x-16.0)/CIEK;
00051 if ((y*y*y) > CIEEpsilon)
00052 y=(y*y*y);
00053 else
00054 y=L/CIEK;
00055 if ((z*z*z) > CIEEpsilon)
00056 z=(z*z*z);
00057 else
00058 z=(116.0*z-16.0)/CIEK;
00059 *X=D65X*x;
00060 *Y=D65Y*y;
00061 *Z=D65Z*z;
00062 }
00063
00064 static inline void ConvertXYZToLuv(const double X,const double Y,const double Z,
00065 double *L,double *u,double *v)
00066 {
00067 double
00068 alpha;
00069
00070 assert(L != (double *) NULL);
00071 assert(u != (double *) NULL);
00072 assert(v != (double *) NULL);
00073 if ((Y/D65Y) > CIEEpsilon)
00074 *L=(double) (116.0*pow(Y/D65Y,1.0/3.0)-16.0);
00075 else
00076 *L=CIEK*(Y/D65Y);
00077 alpha=PerceptibleReciprocal(X+15.0*Y+3.0*Z);
00078 *u=13.0*(*L)*((4.0*alpha*X)-(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z)));
00079 *v=13.0*(*L)*((9.0*alpha*Y)-(9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z)));
00080 *L/=100.0;
00081 *u=(*u+134.0)/354.0;
00082 *v=(*v+140.0)/262.0;
00083 }
00084
00085 static inline void ConvertRGBToXYZ(const Quantum red,const Quantum green,
00086 const Quantum blue,double *X,double *Y,double *Z)
00087 {
00088 double
00089 b,
00090 g,
00091 r;
00092
00093 assert(X != (double *) NULL);
00094 assert(Y != (double *) NULL);
00095 assert(Z != (double *) NULL);
00096 r=QuantumScale*DecodePixelGamma((MagickRealType) red);
00097 g=QuantumScale*DecodePixelGamma((MagickRealType) green);
00098 b=QuantumScale*DecodePixelGamma((MagickRealType) blue);
00099 *X=0.4124564*r+0.3575761*g+0.1804375*b;
00100 *Y=0.2126729*r+0.7151522*g+0.0721750*b;
00101 *Z=0.0193339*r+0.1191920*g+0.9503041*b;
00102 }
00103
00104 static inline void ConvertXYZToLab(const double X,const double Y,const double Z,
00105 double *L,double *a,double *b)
00106 {
00107 double
00108 x,
00109 y,
00110 z;
00111
00112 assert(L != (double *) NULL);
00113 assert(a != (double *) NULL);
00114 assert(b != (double *) NULL);
00115 if ((X/D65X) > CIEEpsilon)
00116 x=pow(X/D65X,1.0/3.0);
00117 else
00118 x=(CIEK*X/D65X+16.0)/116.0;
00119 if ((Y/D65Y) > CIEEpsilon)
00120 y=pow(Y/D65Y,1.0/3.0);
00121 else
00122 y=(CIEK*Y/D65Y+16.0)/116.0;
00123 if ((Z/D65Z) > CIEEpsilon)
00124 z=pow(Z/D65Z,1.0/3.0);
00125 else
00126 z=(CIEK*Z/D65Z+16.0)/116.0;
00127 *L=((116.0*y)-16.0)/100.0;
00128 *a=(500.0*(x-y))/255.0+0.5;
00129 *b=(200.0*(y-z))/255.0+0.5;
00130 }
00131
00132 static inline void ConvertLuvToXYZ(const double L,const double u,const double v,
00133 double *X,double *Y,double *Z)
00134 {
00135 assert(X != (double *) NULL);
00136 assert(Y != (double *) NULL);
00137 assert(Z != (double *) NULL);
00138 if (L > (CIEK*CIEEpsilon))
00139 *Y=(double) pow((L+16.0)/116.0,3.0);
00140 else
00141 *Y=L/CIEK;
00142 *X=((*Y*((39.0*L/(v+13.0*L*(9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z))))-5.0))+
00143 5.0*(*Y))/((((52.0f*L/(u+13.0*L*(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z))))-1.0)/
00144 3.0)-(-1.0/3.0));
00145 *Z=(*X*(((52.0f*L/(u+13.0*L*(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z))))-1.0)/3.0))-
00146 5.0*(*Y);
00147 }
00148
00149 static inline void ConvertXYZToRGB(const double X,const double Y,const double Z,
00150 Quantum *red,Quantum *green,Quantum *blue)
00151 {
00152 double
00153 b,
00154 g,
00155 r;
00156
00157 assert(red != (Quantum *) NULL);
00158 assert(green != (Quantum *) NULL);
00159 assert(blue != (Quantum *) NULL);
00160 r=3.2404542*X-1.5371385*Y-0.4985314*Z;
00161 g=(-0.9692660)*X+1.8760108*Y+0.0415560*Z;
00162 b=0.0556434*X-0.2040259*Y+1.0572252*Z;
00163 *red=ClampToQuantum((MagickRealType) EncodePixelGamma(QuantumRange*r));
00164 *green=ClampToQuantum((MagickRealType) EncodePixelGamma(QuantumRange*g));
00165 *blue=ClampToQuantum((MagickRealType) EncodePixelGamma(QuantumRange*b));
00166 }
00167
00168 #if defined(__cplusplus) || defined(c_plusplus)
00169 }
00170 #endif
00171
00172 #endif