gem-private.h

Go to the documentation of this file.
00001 /*
00002   Copyright 1999-2020 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 #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

Generated on 7 Sep 2020 for MagickCore by  doxygen 1.6.1