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