gem-private.h

Go to the documentation of this file.
00001 /*
00002   Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization
00003   dedicated to making software imaging solutions freely available.
00004   
00005   You may not use this file except in compliance with the License.  You may
00006   obtain a copy of the License at
00007   
00008     https://imagemagick.org/script/license.php
00009   
00010   Unless required by applicable law or agreed to in writing, software
00011   distributed under the License is distributed on an "AS IS" BASIS,
00012   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013   See the License for the specific language governing permissions and
00014   limitations under the License.
00015 
00016   MagickCore private graphic gems methods.
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   double
00136     gamma;
00137 
00138   assert(X != (double *) NULL);
00139   assert(Y != (double *) NULL);
00140   assert(Z != (double *) NULL);
00141   if (L > (CIEK*CIEEpsilon))
00142     *Y=(double) pow((L+16.0)/116.0,3.0);
00143   else
00144     *Y=L/CIEK;
00145   gamma=PerceptibleReciprocal((((52.0*L/(u+13.0*L*(4.0*D65X/(D65X+15.0*D65Y+
00146     3.0*D65Z))))-1.0)/3.0)-(-1.0/3.0));
00147   *X=gamma*((*Y*((39.0*L/(v+13.0*L*(9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z))))-5.0))+
00148     5.0*(*Y));
00149   *Z=(*X*(((52.0f*L/(u+13.0*L*(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z))))-1.0)/3.0))-
00150     5.0*(*Y);
00151 }
00152 
00153 static inline void ConvertXYZToRGB(const double X,const double Y,const double Z,
00154   Quantum *red,Quantum *green,Quantum *blue)
00155 {
00156   double
00157     b,
00158     g,
00159     r;
00160 
00161   assert(red != (Quantum *) NULL);
00162   assert(green != (Quantum *) NULL);
00163   assert(blue != (Quantum *) NULL);
00164   r=3.2404542*X-1.5371385*Y-0.4985314*Z;
00165   g=(-0.9692660)*X+1.8760108*Y+0.0415560*Z;
00166   b=0.0556434*X-0.2040259*Y+1.0572252*Z;
00167   *red=ClampToQuantum((MagickRealType) EncodePixelGamma(QuantumRange*r));
00168   *green=ClampToQuantum((MagickRealType) EncodePixelGamma(QuantumRange*g));
00169   *blue=ClampToQuantum((MagickRealType) EncodePixelGamma(QuantumRange*b));
00170 }
00171 
00172 #if defined(__cplusplus) || defined(c_plusplus)
00173 }
00174 #endif
00175 
00176 #endif

Generated on 31 Oct 2019 for MagickCore by  doxygen 1.6.1