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 "MagickCore/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 extern MagickPrivate double
00034   GenerateDifferentialNoise(RandomInfo *,const Quantum,const NoiseType,
00035     const double);
00036 
00037 extern MagickPrivate size_t
00038   GetOptimalKernelWidth(const double,const double),
00039   GetOptimalKernelWidth1D(const double,const double),
00040   GetOptimalKernelWidth2D(const double,const double);
00041 
00042 extern MagickPrivate void
00043   ConvertHCLToRGB(const double,const double,const double,double *,double *,
00044     double *),
00045   ConvertHCLpToRGB(const double,const double,const double,double *,double *,
00046     double *),
00047   ConvertHSBToRGB(const double,const double,const double,double *,double *,
00048     double *),
00049   ConvertHSIToRGB(const double,const double,const double,double *,double *,
00050     double *),
00051   ConvertHSVToRGB(const double,const double,const double,double *,double *,
00052     double *),
00053   ConvertHWBToRGB(const double,const double,const double,double *,double *,
00054     double *),
00055   ConvertLCHabToRGB(const double,const double,const double,double *,double *,
00056     double *),
00057   ConvertLCHuvToRGB(const double,const double,const double,double *,double *,
00058     double *),
00059   ConvertRGBToHCL(const double,const double,const double,double *,double *,
00060     double *),
00061   ConvertRGBToHCLp(const double,const double,const double,double *,double *,
00062     double *),
00063   ConvertRGBToHSB(const double,const double,const double,double *,double *,
00064     double *),
00065   ConvertRGBToHSI(const double,const double,const double,double *,double *,
00066     double *),
00067   ConvertRGBToHSV(const double,const double,const double,double *,double *,
00068     double *),
00069   ConvertRGBToHWB(const double,const double,const double,double *,double *,
00070     double *),
00071   ConvertRGBToLCHab(const double,const double,const double,double *,double *,
00072     double *),
00073   ConvertRGBToLCHuv(const double,const double,const double,double *,double *,
00074     double *);
00075 
00076 static inline void ConvertLabToXYZ(const double L,const double a,const double b,
00077   double *X,double *Y,double *Z)
00078 {
00079   double
00080     x,
00081     y,
00082     z;
00083 
00084   assert(X != (double *) NULL);
00085   assert(Y != (double *) NULL);
00086   assert(Z != (double *) NULL);
00087   y=(L+16.0)/116.0;
00088   x=y+a/500.0;
00089   z=y-b/200.0;
00090   if ((x*x*x) > CIEEpsilon)
00091     x=(x*x*x);
00092   else
00093     x=(116.0*x-16.0)/CIEK;
00094   if ((y*y*y) > CIEEpsilon)
00095     y=(y*y*y);
00096   else
00097     y=L/CIEK;
00098   if ((z*z*z) > CIEEpsilon)
00099     z=(z*z*z);
00100   else
00101     z=(116.0*z-16.0)/CIEK;
00102   *X=D65X*x;
00103   *Y=D65Y*y;
00104   *Z=D65Z*z;
00105 }
00106 
00107 static inline void ConvertLuvToXYZ(const double L,const double u,const double v,
00108   double *X,double *Y,double *Z)
00109 {
00110   double
00111     gamma;
00112 
00113   assert(X != (double *) NULL);
00114   assert(Y != (double *) NULL);
00115   assert(Z != (double *) NULL);
00116   if (L > (CIEK*CIEEpsilon))
00117     *Y=(double) pow((L+16.0)/116.0,3.0);
00118   else
00119     *Y=L/CIEK;
00120   gamma=PerceptibleReciprocal((((52.0*L/(u+13.0*L*(4.0*D65X/(D65X+15.0*D65Y+
00121     3.0*D65Z))))-1.0)/3.0)-(-1.0/3.0));
00122   *X=gamma*((*Y*((39.0*L/(v+13.0*L*(9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z))))-5.0))+
00123     5.0*(*Y));
00124   *Z=(*X*(((52.0*L/(u+13.0*L*(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z))))-1.0)/3.0))-
00125     5.0*(*Y);
00126 }
00127 
00128 static inline void ConvertRGBToXYZ(const double red,const double green,
00129   const double blue,double *X,double *Y,double *Z)
00130 {
00131   double
00132     b,
00133     g,
00134     r;
00135 
00136   /*
00137     Convert RGB to XYZ colorspace.
00138   */
00139   assert(X != (double *) NULL);
00140   assert(Y != (double *) NULL);
00141   assert(Z != (double *) NULL);
00142   r=QuantumScale*DecodePixelGamma(red);
00143   g=QuantumScale*DecodePixelGamma(green);
00144   b=QuantumScale*DecodePixelGamma(blue);
00145   *X=0.4124564*r+0.3575761*g+0.1804375*b;
00146   *Y=0.2126729*r+0.7151522*g+0.0721750*b;
00147   *Z=0.0193339*r+0.1191920*g+0.9503041*b;
00148 }
00149 
00150 static inline void ConvertXYZToLab(const double X,const double Y,const double Z,
00151   double *L,double *a,double *b)
00152 {
00153   double
00154     x,
00155     y,
00156     z;
00157 
00158   assert(L != (double *) NULL);
00159   assert(a != (double *) NULL);
00160   assert(b != (double *) NULL);
00161   if ((X/D65X) > CIEEpsilon)
00162     x=pow(X/D65X,1.0/3.0);
00163   else
00164     x=(CIEK*X/D65X+16.0)/116.0;
00165   if ((Y/D65Y) > CIEEpsilon)
00166     y=pow(Y/D65Y,1.0/3.0);
00167   else
00168     y=(CIEK*Y/D65Y+16.0)/116.0;
00169   if ((Z/D65Z) > CIEEpsilon)
00170     z=pow(Z/D65Z,1.0/3.0);
00171   else
00172     z=(CIEK*Z/D65Z+16.0)/116.0;
00173   *L=((116.0*y)-16.0)/100.0;
00174   *a=(500.0*(x-y))/255.0+0.5;
00175   *b=(200.0*(y-z))/255.0+0.5;
00176 }
00177 
00178 static inline void ConvertXYZToLuv(const double X,const double Y,const double Z,
00179   double *L,double *u,double *v)
00180 {
00181   double
00182     alpha;
00183 
00184   assert(L != (double *) NULL);
00185   assert(u != (double *) NULL);
00186   assert(v != (double *) NULL);
00187   if ((Y/D65Y) > CIEEpsilon)
00188     *L=(double) (116.0*pow(Y/D65Y,1.0/3.0)-16.0);
00189   else
00190     *L=CIEK*(Y/D65Y);
00191   alpha=PerceptibleReciprocal(X+15.0*Y+3.0*Z);
00192   *u=13.0*(*L)*((4.0*alpha*X)-(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z)));
00193   *v=13.0*(*L)*((9.0*alpha*Y)-(9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z)));
00194   *L/=100.0;
00195   *u=(*u+134.0)/354.0;
00196   *v=(*v+140.0)/262.0;
00197 }
00198 
00199 static inline void ConvertXYZToRGB(const double X,const double Y,const double Z,
00200   double *red,double *green,double *blue)
00201 {
00202   double
00203     b,
00204     g,
00205     r;
00206 
00207   assert(red != (double *) NULL);
00208   assert(green != (double *) NULL);
00209   assert(blue != (double *) NULL);
00210   r=3.2404542*X-1.5371385*Y-0.4985314*Z;
00211   g=(-0.9692660)*X+1.8760108*Y+0.0415560*Z;
00212   b=0.0556434*X-0.2040259*Y+1.0572252*Z;
00213   *red=EncodePixelGamma(QuantumRange*r);
00214   *green=EncodePixelGamma(QuantumRange*g);
00215   *blue=EncodePixelGamma(QuantumRange*b);
00216 }
00217 
00218 #if defined(__cplusplus) || defined(c_plusplus)
00219 }
00220 #endif
00221 
00222 #endif

Generated on 18 Dec 2019 for MagickCore by  doxygen 1.6.1