From b285095a81498ca0f0b24a0591e02aa599065b12 Mon Sep 17 00:00:00 2001 From: cristy Date: Thu, 4 Apr 2013 19:00:52 +0000 Subject: [PATCH] --- MagickCore/colorspace.c | 52 +++----- MagickCore/enhance.c | 35 ++++++ MagickCore/gem-private.h | 4 + MagickCore/gem.c | 253 +++++++++++++++++++++++++++++++-------- 4 files changed, 261 insertions(+), 83 deletions(-) diff --git a/MagickCore/colorspace.c b/MagickCore/colorspace.c index 6e336f87a..75d5a5ec9 100644 --- a/MagickCore/colorspace.c +++ b/MagickCore/colorspace.c @@ -749,32 +749,20 @@ static MagickBooleanType sRGBTransformImage(Image *image, for (x=0; x < (ssize_t) image->columns; x++) { double - a, - b, blue, - C, + chroma, green, - H, - L, - red, - X, - Y, - Z; + hue, + luma, + red; red=DecodePixelGamma((MagickRealType) GetPixelRed(image,q)); green=DecodePixelGamma((MagickRealType) GetPixelGreen(image,q)); blue=DecodePixelGamma((MagickRealType) GetPixelBlue(image,q)); - ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z); - ConvertXYZToLab(X,Y,Z,&L,&a,&b); - C=hypot(a-0.5,b-0.5); - H=180.0*atan2(b-0.5,a-0.5)/MagickPI; - if (H < 360.0) - H+=360.0; - if (H > 360.0) - H-=360.0; - SetPixelRed(image,ClampToQuantum(QuantumRange*L),q); - SetPixelGreen(image,ClampToQuantum(QuantumRange*C),q); - SetPixelBlue(image,ClampToQuantum(QuantumRange*H/360.0),q); + ConvertRGBToLCH(red,green,blue,&luma,&chroma,&hue); + SetPixelRed(image,ClampToQuantum(QuantumRange*luma),q); + SetPixelGreen(image,ClampToQuantum(QuantumRange*chroma),q); + SetPixelBlue(image,ClampToQuantum(QuantumRange*hue),q); q+=GetPixelChannels(image); } sync=SyncCacheViewAuthenticPixels(image_view,exception); @@ -2604,25 +2592,17 @@ static MagickBooleanType TransformsRGBImage(Image *image, for (x=0; x < (ssize_t) image->columns; x++) { double - a, - b, blue, - C, + chroma, green, - H, - L, - red, - X, - Y, - Z; + hue, + luma, + red; - L=QuantumScale*GetPixelRed(image,q); - C=QuantumScale*GetPixelGreen(image,q); - H=QuantumScale*GetPixelBlue(image,q); - a=C*cos(360.0*H*MagickPI/180.0)+0.5; - b=C*sin(360.0*H*MagickPI/180.0)+0.5; - ConvertLabToXYZ(L,a,b,&X,&Y,&Z); - ConvertXYZToRGB(X,Y,Z,&red,&green,&blue); + luma=(double) (QuantumScale*GetPixelRed(image,q)); + chroma=(double) (QuantumScale*GetPixelGreen(image,q)); + hue=(double) (QuantumScale*GetPixelBlue(image,q)); + ConvertLCHToRGB(luma,chroma,hue,&red,&green,&blue); SetPixelRed(image,ClampToQuantum(EncodePixelGamma(red)),q); SetPixelGreen(image,ClampToQuantum(EncodePixelGamma(green)),q); SetPixelBlue(image,ClampToQuantum(EncodePixelGamma(blue)),q); diff --git a/MagickCore/enhance.c b/MagickCore/enhance.c index 78029e076..2f28e4cc6 100644 --- a/MagickCore/enhance.c +++ b/MagickCore/enhance.c @@ -2954,6 +2954,29 @@ static inline void ModulateHWB(const double percent_hue, ConvertHWBToRGB(hue,whiteness,blackness,red,green,blue); } +static inline void ModulateLCH(const double percent_luma, + const double percent_chroma,const double percent_hue,double *red, + double *green,double *blue) +{ + double + hue, + luma, + chroma; + + /* + Increase or decrease color luma, chroma, or hue. + */ + ConvertRGBToLCH(*red,*green,*blue,&luma,&chroma,&hue); + luma*=0.01*percent_luma; + chroma*=0.01*percent_chroma; + hue+=0.5*(0.01*percent_hue-1.0); + while (hue < 0.0) + hue+=1.0; + while (hue > 1.0) + hue-=1.0; + ConvertHCLToRGB(luma,chroma,hue,red,green,blue); +} + MagickExport MagickBooleanType ModulateImage(Image *image,const char *modulate, ExceptionInfo *exception) { @@ -3062,6 +3085,12 @@ MagickExport MagickBooleanType ModulateImage(Image *image,const char *modulate, &red,&green,&blue); break; } + case LCHColorspace: + { + ModulateLCH(percent_brightness,percent_saturation,percent_hue, + &red,&green,&blue); + break; + } } if (IssRGBColorspace(image->colorspace) != MagickFalse) { @@ -3142,6 +3171,12 @@ MagickExport MagickBooleanType ModulateImage(Image *image,const char *modulate, &red,&green,&blue); break; } + case LCHColorspace: + { + ModulateLCH(percent_brightness,percent_saturation,percent_hue, + &red,&green,&blue); + break; + } } if (IssRGBColorspace(image->colorspace) != MagickFalse) { diff --git a/MagickCore/gem-private.h b/MagickCore/gem-private.h index 12d95e088..d51e7c9ba 100644 --- a/MagickCore/gem-private.h +++ b/MagickCore/gem-private.h @@ -44,11 +44,15 @@ extern MagickPrivate void double *), ConvertHWBToRGB(const double,const double,const double,double *,double *, double *), + ConvertLCHToRGB(const double,const double,const double,double *,double *, + double *), ConvertRGBToHCL(const double,const double,const double,double *,double *, double *), ConvertRGBToHSB(const double,const double,const double,double *,double *, double *), ConvertRGBToHWB(const double,const double,const double,double *,double *, + double *), + ConvertRGBToLCH(const double,const double,const double,double *,double *, double *); static inline void ConvertLabToXYZ(const double L,const double a,const double b, diff --git a/MagickCore/gem.c b/MagickCore/gem.c index 913a92c9d..c74ca1aed 100644 --- a/MagickCore/gem.c +++ b/MagickCore/gem.c @@ -89,14 +89,13 @@ MagickPrivate void ConvertHCLToRGB(const double hue,const double chroma, const double luma,double *red,double *green,double *blue) { double - a, b, - C, - H, - L, - X, - Y, - Z; + c, + g, + h, + m, + r, + x; /* Convert HCL to RGB colorspace. @@ -104,13 +103,51 @@ MagickPrivate void ConvertHCLToRGB(const double hue,const double chroma, assert(red != (double *) NULL); assert(green != (double *) NULL); assert(blue != (double *) NULL); - L=luma; - C=chroma; - H=hue; - a=C*cos(360.0*H*MagickPI/180.0)+0.5; - b=C*sin(360.0*H*MagickPI/180.0)+0.5; - ConvertLabToXYZ(L,a,b,&X,&Y,&Z); - ConvertXYZToRGB(X,Y,Z,red,green,blue); + h=6.0*hue; + c=chroma; + x=c*(1.0-fabs(fmod(h,2.0)-1.0)); + r=0.0; + g=0.0; + b=0.0; + if ((0.0 <= h) && (h < 1.0)) + { + r=c; + g=x; + } + else + if ((1.0 <= h) && (h < 2.0)) + { + r=x; + g=c; + } + else + if ((2.0 <= h) && (h < 3.0)) + { + g=c; + b=x; + } + else + if ((3.0 <= h) && (h < 4.0)) + { + g=x; + b=c; + } + else + if ((4.0 <= h) && (h < 5.0)) + { + r=x; + b=c; + } + else + if ((5.0 <= h) && (h < 6.0)) + { + r=c; + b=x; + } + m=luma-(0.298839f*r+0.586811f*g+0.114350f*b); + *red=QuantumRange*(r+m); + *green=QuantumRange*(g+m); + *blue=QuantumRange*(b+m); } /* @@ -376,6 +413,61 @@ MagickPrivate void ConvertHWBToRGB(const double hue,const double whiteness, % % % % % % +% C o n v e r t L C H T o R G B % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% ConvertLCHToRGB() transforms a (luma, chroma, hue) to a (red, green, +% blue) triple. +% +% The format of the ConvertLCHToRGBImage method is: +% +% void ConvertLCHToRGB(const double luma,const double chroma, +% const double hue,double *red,double *green,double *blue) +% +% A description of each parameter follows: +% +% o luma, chroma, hue: A double value representing a +% component of the LCH color space. +% +% o red, green, blue: A pointer to a pixel component of type Quantum. +% +*/ +MagickPrivate void ConvertLCHToRGB(const double luma,const double chroma, + const double hue,double *red,double *green,double *blue) +{ + double + a, + b, + C, + H, + L, + X, + Y, + Z; + + /* + Convert LCH to RGB colorspace. + */ + assert(red != (double *) NULL); + assert(green != (double *) NULL); + assert(blue != (double *) NULL); + L=luma; + C=chroma; + H=hue; + a=C*cos(360.0*H*MagickPI/180.0)+0.5; + b=C*sin(360.0*H*MagickPI/180.0)+0.5; + ConvertLabToXYZ(L,a,b,&X,&Y,&Z); + ConvertXYZToRGB(X,Y,Z,red,green,blue); +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % % C o n v e r t R G B T o H C L % % % % % @@ -399,18 +491,31 @@ MagickPrivate void ConvertHWBToRGB(const double hue,const double whiteness, % component of the HCL color space. % */ + +static inline double MagickMax(const double x,const double y) +{ + if (x > y) + return(x); + return(y); +} + +static inline double MagickMin(const double x,const double y) +{ + if (x < y) + return(x); + return(y); +} + MagickPrivate void ConvertRGBToHCL(const double red,const double green, const double blue,double *hue,double *chroma,double *luma) { double - a, b, - C, - H, - L, - X, - Y, - Z; + c, + g, + h, + max, + r; /* Convert RGB to HCL colorspace. @@ -418,17 +523,26 @@ MagickPrivate void ConvertRGBToHCL(const double red,const double green, assert(hue != (double *) NULL); assert(chroma != (double *) NULL); assert(luma != (double *) NULL); - ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z); - ConvertXYZToLab(X,Y,Z,&L,&a,&b); - C=hypot(a-0.5,b-0.5); - H=180.0*atan2(b-0.5,a-0.5)/MagickPI; - if (H < 360.0) - H+=360.0; - if (H > 360.0) - H-=360.0; - *hue=H/360.0; - *chroma=C; - *luma=L; + r=red; + g=green; + b=blue; + max=MagickMax(r,MagickMax(g,b)); + c=max-(double) MagickMin(r,MagickMin(g,b)); + h=0.0; + if (c == 0.0) + h=0.0; + else + if (red == max) + h=fmod((g-b)/c+6.0,6.0); + else + if (green == max) + h=((b-r)/c)+2.0; + else + if (blue == max) + h=((r-g)/c)+4.0; + *hue=(h/6.0); + *chroma=QuantumScale*c; + *luma=QuantumScale*(0.298839f*r+0.586811f*g+0.114350f*b); } /* @@ -535,21 +649,6 @@ MagickPrivate void ConvertRGBToHSB(const double red,const double green, % component of the HSL color space. % */ - -static inline double MagickMax(const double x,const double y) -{ - if (x > y) - return(x); - return(y); -} - -static inline double MagickMin(const double x,const double y) -{ - if (x < y) - return(x); - return(y); -} - MagickExport void ConvertRGBToHSL(const double red,const double green, const double blue,double *hue,double *saturation,double *lightness) { @@ -668,6 +767,66 @@ MagickPrivate void ConvertRGBToHWB(const double red,const double green, % % % % % % +% C o n v e r t R G B T o L C H % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% ConvertRGBToLCH() transforms a (red, green, blue) to a (luma, chroma, +% hue) triple. +% +% The format of the ConvertRGBToLCH method is: +% +% void ConvertRGBToLCH(const double red,const double green, +% const double blue,double *luma,double *chroma,double *hue) +% +% A description of each parameter follows: +% +% o red, green, blue: A Quantum value representing the red, green, and +% blue component of a pixel. +% +% o luma, chroma, hue: A pointer to a double value representing a +% component of the LCH color space. +% +*/ +MagickPrivate void ConvertRGBToLCH(const double red,const double green, + const double blue,double *luma,double *chroma,double *hue) +{ + double + a, + b, + C, + H, + L, + X, + Y, + Z; + + /* + Convert RGB to LCH colorspace. + */ + assert(luma != (double *) NULL); + assert(chroma != (double *) NULL); + assert(hue != (double *) NULL); + ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z); + ConvertXYZToLab(X,Y,Z,&L,&a,&b); + C=hypot(a-0.5,b-0.5); + H=180.0*atan2(b-0.5,a-0.5)/MagickPI; + if (H < 360.0) + H+=360.0; + if (H > 360.0) + H-=360.0; + *luma=L; + *chroma=C; + *hue=H/360.0; +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % % E x p a n d A f f i n e % % % % % -- 2.40.0