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);
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);
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)
{
&red,&green,&blue);
break;
}
+ case LCHColorspace:
+ {
+ ModulateLCH(percent_brightness,percent_saturation,percent_hue,
+ &red,&green,&blue);
+ break;
+ }
}
if (IssRGBColorspace(image->colorspace) != MagickFalse)
{
&red,&green,&blue);
break;
}
+ case LCHColorspace:
+ {
+ ModulateLCH(percent_brightness,percent_saturation,percent_hue,
+ &red,&green,&blue);
+ break;
+ }
}
if (IssRGBColorspace(image->colorspace) != MagickFalse)
{
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.
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);
}
\f
/*
% %
% %
% %
+% 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);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
% C o n v e r t R G B T o H C L %
% %
% %
% 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.
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);
}
\f
/*
% 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)
{
% %
% %
% %
+% 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;
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
% E x p a n d A f f i n e %
% %
% %