From 09d746f0cc2c7c9cb04a9a8984945cefe269d59b Mon Sep 17 00:00:00 2001 From: cristy Date: Wed, 29 Aug 2012 17:54:59 +0000 Subject: [PATCH] --- MagickCore/colorspace.c | 179 ++++++++++++++++++++++++++++++++++++++++ MagickCore/colorspace.h | 1 + MagickCore/option.c | 1 + 3 files changed, 181 insertions(+) diff --git a/MagickCore/colorspace.c b/MagickCore/colorspace.c index b4d160089..76f1e4ee9 100644 --- a/MagickCore/colorspace.c +++ b/MagickCore/colorspace.c @@ -115,6 +115,28 @@ static MagickBooleanType % */ +static inline void ConvertXYZToLMS(const double x,const double y, + const double z,double *L,double *M,double *S) +{ + double + l, + m, + s; + + /* + Convert XYZ to LMS colorspace. + */ + assert(L != (double *) NULL); + assert(M != (double *) NULL); + assert(S != (double *) NULL); + l=0.7328*x+0.4296*y-0.1624*z; + m=(-0.7036*x+1.6975*y+0.0415*z); + s=0.0030*x+0.0136*y+0.9834*z; + *L=QuantumRange*l; + *M=QuantumRange*m; + *S=QuantumRange*s; +} + static inline void ConvertRGBToXYZ(const double red,const double green, const double blue,double *X,double *Y,double *Z) { @@ -826,6 +848,75 @@ static MagickBooleanType sRGBTransformImage(Image *image, return(MagickFalse); return(status); } + case LMSColorspace: + { + /* + Transform image from sRGB to LMS. + */ + if (image->storage_class == PseudoClass) + { + if (SyncImage(image,exception) == MagickFalse) + return(MagickFalse); + if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) + return(MagickFalse); + } + image_view=AcquireAuthenticCacheView(image,exception); +#if defined(MAGICKCORE_OPENMP_SUPPORT) + #pragma omp parallel for schedule(static,4) shared(status) \ + dynamic_number_threads(image,image->columns,image->rows,1) +#endif + for (y=0; y < (ssize_t) image->rows; y++) + { + MagickBooleanType + sync; + + register ssize_t + x; + + register Quantum + *restrict q; + + if (status == MagickFalse) + continue; + q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, + exception); + if (q == (Quantum *) NULL) + { + status=MagickFalse; + continue; + } + for (x=0; x < (ssize_t) image->columns; x++) + { + double + blue, + green, + L, + M, + red, + S, + X, + Y, + Z; + + red=InversesRGBCompandor((double) GetPixelRed(image,q)); + green=InversesRGBCompandor((double) GetPixelGreen(image,q)); + blue=InversesRGBCompandor((double) GetPixelBlue(image,q)); + ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z); + ConvertXYZToLMS(X,Y,Z,&L,&M,&S); + SetPixelRed(image,ClampToQuantum(QuantumRange*L),q); + SetPixelGreen(image,ClampToQuantum(QuantumRange*M),q); + SetPixelBlue(image,ClampToQuantum(QuantumRange*S),q); + q+=GetPixelChannels(image); + } + sync=SyncCacheViewAuthenticPixels(image_view,exception); + if (sync == MagickFalse) + status=MagickFalse; + } + image_view=DestroyCacheView(image_view); + if (SetImageColorspace(image,colorspace,exception) == MagickFalse) + return(MagickFalse); + return(status); + } case LogColorspace: { #define DisplayGamma (1.0/1.7) @@ -1745,6 +1836,25 @@ MagickExport MagickBooleanType TransformImageColorspace(Image *image, % */ +static inline void ConvertLMSToXYZ(const double L,const double M,const double S, + double *X,double *Y,double *Z) +{ + double + l, + m, + s; + + assert(X != (double *) NULL); + assert(Y != (double *) NULL); + assert(Z != (double *) NULL); + l=QuantumScale*L; + m=QuantumScale*M; + s=QuantumScale*S; + *X=1.096123820835514*l-0.278869000218287*m+0.182745179382773*s; + *Y=0.454369041975359*l+0.473533154307412*m+0.072097803717229*s; + *Z=(-0.009627608738429)*l-0.005698031216113*m+1.015325639954543*s; +} + static inline void ConvertLabToXYZ(const double L,const double a,const double b, double *X,double *Y,double *Z) { @@ -2697,6 +2807,75 @@ static MagickBooleanType TransformsRGBImage(Image *image, return(MagickFalse); return(status); } + case LMSColorspace: + { + /* + Transform image from LMS to sRGB. + */ + if (image->storage_class == PseudoClass) + { + if (SyncImage(image,exception) == MagickFalse) + return(MagickFalse); + if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) + return(MagickFalse); + } + image_view=AcquireAuthenticCacheView(image,exception); +#if defined(MAGICKCORE_OPENMP_SUPPORT) + #pragma omp parallel for schedule(static,4) shared(status) \ + dynamic_number_threads(image,image->columns,image->rows,1) +#endif + for (y=0; y < (ssize_t) image->rows; y++) + { + MagickBooleanType + sync; + + register ssize_t + x; + + register Quantum + *restrict q; + + if (status == MagickFalse) + continue; + q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, + exception); + if (q == (Quantum *) NULL) + { + status=MagickFalse; + continue; + } + for (x=0; x < (ssize_t) image->columns; x++) + { + double + blue, + green, + L, + M, + red, + S, + X, + Y, + Z; + + L=QuantumScale*GetPixelRed(image,q); + M=QuantumScale*GetPixelGreen(image,q); + S=QuantumScale*GetPixelBlue(image,q); + ConvertLMSToXYZ(L,M,S,&X,&Y,&Z); + ConvertXYZToRGB(X,Y,Z,&red,&green,&blue); + SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q); + SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q); + SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q); + q+=GetPixelChannels(image); + } + sync=SyncCacheViewAuthenticPixels(image_view,exception); + if (sync == MagickFalse) + status=MagickFalse; + } + image_view=DestroyCacheView(image_view); + if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse) + return(MagickFalse); + return(status); + } case LogColorspace: { const char diff --git a/MagickCore/colorspace.h b/MagickCore/colorspace.h index 321b4a69f..8f33cc8aa 100644 --- a/MagickCore/colorspace.h +++ b/MagickCore/colorspace.h @@ -35,6 +35,7 @@ typedef enum LabColorspace, LCHColorspace, LogColorspace, + LMSColorspace, LuvColorspace, OHTAColorspace, Rec601LumaColorspace, diff --git a/MagickCore/option.c b/MagickCore/option.c index 9b081ea78..2100a1dcc 100644 --- a/MagickCore/option.c +++ b/MagickCore/option.c @@ -871,6 +871,7 @@ static const OptionInfo { "HWB", HWBColorspace, UndefinedOptionFlag, MagickFalse }, { "Lab", LabColorspace, UndefinedOptionFlag, MagickFalse }, { "LCH", LCHColorspace, UndefinedOptionFlag, MagickFalse }, + { "LMS", LMSColorspace, UndefinedOptionFlag, MagickFalse }, { "Log", LogColorspace, UndefinedOptionFlag, MagickFalse }, { "Luv", LuvColorspace, UndefinedOptionFlag, MagickFalse }, { "OHTA", OHTAColorspace, UndefinedOptionFlag, MagickFalse }, -- 2.50.1