return(MagickFalse);
return(status);
}
+ case HSVColorspace:
+ {
+ /*
+ Transform image from sRGB to HSV.
+ */
+ 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) \
+ magick_threads(image,image,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,
+ hue,
+ red,
+ saturation,
+ value;
+
+ red=DecodePixelGamma((MagickRealType) GetPixelRed(image,q));
+ green=DecodePixelGamma((MagickRealType) GetPixelGreen(image,q));
+ blue=DecodePixelGamma((MagickRealType) GetPixelBlue(image,q));
+ ConvertRGBToHSV(red,green,blue,&hue,&saturation,&value);
+ SetPixelRed(image,ClampToQuantum(QuantumRange*hue),q);
+ SetPixelGreen(image,ClampToQuantum(QuantumRange*saturation),q);
+ SetPixelBlue(image,ClampToQuantum(QuantumRange*value),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 HWBColorspace:
{
/*
return(MagickFalse);
return(status);
}
+ case HSVColorspace:
+ {
+ /*
+ Transform image from HSV 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) \
+ magick_threads(image,image,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,
+ hue,
+ red,
+ saturation,
+ value;
+
+ hue=(double) (QuantumScale*GetPixelRed(image,q));
+ saturation=(double) (QuantumScale*GetPixelGreen(image,q));
+ value=(double) (QuantumScale*GetPixelBlue(image,q));
+ ConvertHSVToRGB(hue,saturation,value,&red,&green,&blue);
+ SetPixelRed(image,ClampToQuantum(EncodePixelGamma(red)),q);
+ SetPixelGreen(image,ClampToQuantum(EncodePixelGamma(green)),q);
+ SetPixelBlue(image,ClampToQuantum(EncodePixelGamma(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 HWBColorspace:
{
/*
HSBColorspace,
HSIColorspace,
HSLColorspace,
+ HSVColorspace,
HWBColorspace,
LabColorspace,
LCHColorspace,
ConvertHSLToRGB(hue,saturation,lightness,red,green,blue);
}
+static inline void ModulateHSV(const double percent_hue,
+ const double percent_saturation,const double percent_value,double *red,
+ double *green,double *blue)
+{
+ double
+ hue,
+ saturation,
+ value;
+
+ /*
+ Increase or decrease color value, saturation, or hue.
+ */
+ ConvertRGBToHSV(*red,*green,*blue,&hue,&saturation,&value);
+ hue+=0.5*(0.01*percent_hue-1.0);
+ while (hue < 0.0)
+ hue+=1.0;
+ while (hue >= 1.0)
+ hue-=1.0;
+ saturation*=0.01*percent_saturation;
+ value*=0.01*percent_value;
+ ConvertHSVToRGB(hue,saturation,value,red,green,blue);
+}
+
static inline void ModulateHWB(const double percent_hue,
const double percent_whiteness,const double percent_blackness,double *red,
double *green,double *blue)
&red,&green,&blue);
break;
}
+ case HSVColorspace:
+ {
+ ModulateHSV(percent_hue,percent_saturation,percent_brightness,
+ &red,&green,&blue);
+ break;
+ }
case HWBColorspace:
{
ModulateHWB(percent_hue,percent_saturation,percent_brightness,
double *),
ConvertHSIToRGB(const double,const double,const double,double *,double *,
double *),
+ ConvertHSVToRGB(const double,const double,const double,double *,double *,
+ double *),
ConvertHWBToRGB(const double,const double,const double,double *,double *,
double *),
ConvertLCHabToRGB(const double,const double,const double,double *,double *,
double *),
ConvertRGBToHSI(const double,const double,const double,double *,double *,
double *),
+ ConvertRGBToHSV(const double,const double,const double,double *,double *,
+ double *),
ConvertRGBToHWB(const double,const double,const double,double *,double *,
double *),
ConvertRGBToLCHab(const double,const double,const double,double *,double *,
% %
% %
% %
+% C o n v e r t H S V T o R G B %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ConvertHSVToRGB() transforms a (hue, saturation, value) to a (red,
+% green, blue) triple.
+%
+% The format of the ConvertHSVToRGBImage method is:
+%
+% void ConvertHSVToRGB(const double hue,const double saturation,
+% const double value,double *red,double *green,double *blue)
+%
+% A description of each parameter follows:
+%
+% o hue, saturation, value: A double value representing a
+% component of the HSV color space.
+%
+% o red, green, blue: A pointer to a pixel component of type Quantum.
+%
+*/
+MagickPrivate void ConvertHSVToRGB(const double hue,const double saturation,
+ const double value,double *red,double *green,double *blue)
+{
+ double
+ c,
+ h,
+ min,
+ x;
+
+ /*
+ Convert HSV to RGB colorspace.
+ */
+ assert(red != (double *) NULL);
+ assert(green != (double *) NULL);
+ assert(blue != (double *) NULL);
+ h=hue*360.0;
+ c=value*saturation;
+ min=value-c;
+ h-=360.0*floor(h/360.0);
+ h/=60.0;
+ x=c*(1.0-fabs(h-2.0*floor(h/2.0)-1.0));
+ switch ((int) floor(h))
+ {
+ case 0:
+ {
+ *red=QuantumRange*(min+c);
+ *green=QuantumRange*(min+x);
+ *blue=QuantumRange*min;
+ break;
+ }
+ case 1:
+ {
+ *red=QuantumRange*(min+x);
+ *green=QuantumRange*(min+c);
+ *blue=QuantumRange*min;
+ break;
+ }
+ case 2:
+ {
+ *red=QuantumRange*min;
+ *green=QuantumRange*(min+c);
+ *blue=QuantumRange*(min+x);
+ break;
+ }
+ case 3:
+ {
+ *red=QuantumRange*min;
+ *green=QuantumRange*(min+x);
+ *blue=QuantumRange*(min+c);
+ break;
+ }
+ case 4:
+ {
+ *red=QuantumRange*(min+x);
+ *green=QuantumRange*min;
+ *blue=QuantumRange*(min+c);
+ break;
+ }
+ case 5:
+ {
+ *red=QuantumRange*(min+c);
+ *green=QuantumRange*min;
+ *blue=QuantumRange*(min+x);
+ break;
+ }
+ default:
+ {
+ *red=0.0;
+ *green=0.0;
+ *blue=0.0;
+ }
+ }
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
% C o n v e r t H W B T o R G B %
% %
% %
% %
% %
% %
+% C o n v e r t R G B T o H S V %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ConvertRGBToHSV() transforms a (red, green, blue) to a (hue, saturation,
+% value) triple.
+%
+% The format of the ConvertRGBToHSV method is:
+%
+% void ConvertRGBToHSV(const double red,const double green,
+% const double blue,double *hue,double *saturation,double *value)
+%
+% A description of each parameter follows:
+%
+% o red, green, blue: A Quantum value representing the red, green, and
+% blue component of a pixel..
+%
+% o hue, saturation, value: A pointer to a double value representing a
+% component of the HSV color space.
+%
+*/
+MagickPrivate void ConvertRGBToHSV(const double red,const double green,
+ const double blue,double *hue,double *saturation,double *value)
+{
+ double
+ c,
+ max,
+ min;
+
+ /*
+ Convert RGB to HSV colorspace.
+ */
+ assert(hue != (double *) NULL);
+ assert(saturation != (double *) NULL);
+ assert(value != (double *) NULL);
+ max=MagickMax(QuantumScale*red,MagickMax(QuantumScale*green,
+ QuantumScale*blue));
+ min=MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
+ QuantumScale*blue));
+ c=max-min;
+ *value=max;
+ if (c <= 0.0)
+ {
+ *hue=0.0;
+ *saturation=0.0;
+ return;
+ }
+ if (max == (QuantumScale*red))
+ {
+ *hue=(QuantumScale*green-QuantumScale*blue)/c;
+ if ((QuantumScale*green) < (QuantumScale*blue))
+ *hue+=6.0;
+ }
+ else
+ if (max == (QuantumScale*green))
+ *hue=2.0+(QuantumScale*blue-QuantumScale*red)/c;
+ else
+ *hue=4.0+(QuantumScale*red-QuantumScale*green)/c;
+ *hue*=60.0/360.0;
+ *saturation=c/max;
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
% C o n v e r t R G B T o H W B %
% %
% %
{ "HSB", HSBColorspace, UndefinedOptionFlag, MagickFalse },
{ "HSI", HSIColorspace, UndefinedOptionFlag, MagickFalse },
{ "HSL", HSLColorspace, UndefinedOptionFlag, MagickFalse },
+ { "HSV", HSVColorspace, UndefinedOptionFlag, MagickFalse },
{ "HWB", HWBColorspace, UndefinedOptionFlag, MagickFalse },
{ "Lab", LabColorspace, UndefinedOptionFlag, MagickFalse },
{ "LCH", LCHColorspace, UndefinedOptionFlag, MagickFalse },