]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Thu, 2 May 2013 16:35:53 +0000 (16:35 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Thu, 2 May 2013 16:35:53 +0000 (16:35 +0000)
MagickCore/colorspace.c
MagickCore/colorspace.h
MagickCore/enhance.c
MagickCore/gem-private.h
MagickCore/gem.c
MagickCore/option.c

index 987a882bd81f4636aeb951b061b293b78a05196b..0cd1b1d76b3d35765735f3fe07e8d1115f8b6309 100644 (file)
@@ -619,6 +619,71 @@ static MagickBooleanType sRGBTransformImage(Image *image,
         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:
     {
       /*
@@ -2577,6 +2642,71 @@ static MagickBooleanType TransformsRGBImage(Image *image,
         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:
     {
       /*
index 5f11ab48cf07dbbfe5982976a1ab03de2104fdd9..9882cd0d6e3c2d8ff2c75cdb914b290e388bf007 100644 (file)
@@ -32,6 +32,7 @@ typedef enum
   HSBColorspace,
   HSIColorspace,
   HSLColorspace,
+  HSVColorspace,
   HWBColorspace,
   LabColorspace,
   LCHColorspace,
index 3fdbf9867df4bd5fbecb1e06930c932dba31d319..8aa3b4cf78e894c813018b15a443dc69c2b58f86 100644 (file)
@@ -2995,6 +2995,29 @@ static inline void ModulateHSL(const double percent_hue,
   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)
@@ -3172,6 +3195,12 @@ MagickExport MagickBooleanType ModulateImage(Image *image,const char *modulate,
             &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,
index b8db0ad33d157796b45c818b192544866233c065..71bcf9a70b4afad79863971481a0a38310fa15eb 100644 (file)
@@ -46,6 +46,8 @@ extern MagickPrivate void
     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 *,
@@ -58,6 +60,8 @@ extern MagickPrivate void
     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 *,
index b628be96a1b38b04b3a6c00a8ebc4ae9bd11c92a..7cabf3fb47cffa60a38462d5e904465e6c27056c 100644 (file)
@@ -445,6 +445,107 @@ MagickExport void ConvertHSLToRGB(const double hue,const double saturation,
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%   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                                             %
 %                                                                             %
 %                                                                             %
@@ -919,6 +1020,75 @@ MagickExport void ConvertRGBToHSL(const double red,const double green,
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%   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                                             %
 %                                                                             %
 %                                                                             %
index 222347b36e3fc5373ae09209780c43fd77650413..64049078fd968a650d0e79f88ce2f6b0f3732af0 100644 (file)
@@ -889,6 +889,7 @@ static const OptionInfo
     { "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 },