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

index e92723ca2ff7197630d745a432a679e4f3117577..987a882bd81f4636aeb951b061b293b78a05196b 100644 (file)
@@ -489,6 +489,71 @@ static MagickBooleanType sRGBTransformImage(Image *image,
         return(MagickFalse);
       return(status);
     }
+    case HSIColorspace:
+    {
+      /*
+        Transform image from sRGB to HSI.
+      */
+      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,
+            intensity,
+            red,
+            saturation;
+
+          red=DecodePixelGamma((MagickRealType) GetPixelRed(image,q));
+          green=DecodePixelGamma((MagickRealType) GetPixelGreen(image,q));
+          blue=DecodePixelGamma((MagickRealType) GetPixelBlue(image,q));
+          ConvertRGBToHSI(red,green,blue,&hue,&saturation,&intensity);
+          SetPixelRed(image,ClampToQuantum(QuantumRange*hue),q);
+          SetPixelGreen(image,ClampToQuantum(QuantumRange*saturation),q);
+          SetPixelBlue(image,ClampToQuantum(QuantumRange*intensity),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 HSLColorspace:
     {
       /*
@@ -2382,6 +2447,71 @@ static MagickBooleanType TransformsRGBImage(Image *image,
         return(MagickFalse);
       return(status);
     }
+    case HSIColorspace:
+    {
+      /*
+        Transform image from HSI 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,
+            intensity,
+            red,
+            saturation;
+
+          hue=(double) (QuantumScale*GetPixelRed(image,q));
+          saturation=(double) (QuantumScale*GetPixelGreen(image,q));
+          intensity=(double) (QuantumScale*GetPixelBlue(image,q));
+          ConvertHSIToRGB(hue,saturation,intensity,&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 HSLColorspace:
     {
       /*
index 9e200a609ecf413cbfa0e44c40dccabc0a82868b..5f11ab48cf07dbbfe5982976a1ab03de2104fdd9 100644 (file)
@@ -30,6 +30,7 @@ typedef enum
   GRAYColorspace,
   HCLColorspace,
   HSBColorspace,
+  HSIColorspace,
   HSLColorspace,
   HWBColorspace,
   LabColorspace,
index 093c40d4fb8bb6aa31c11030befb21e008378727..3fdbf9867df4bd5fbecb1e06930c932dba31d319 100644 (file)
@@ -2949,6 +2949,29 @@ static inline void ModulateHSB(const double percent_hue,
   ConvertHSBToRGB(hue,saturation,brightness,red,green,blue);
 }
 
+static inline void ModulateHSI(const double percent_hue,
+  const double percent_saturation,const double percent_intensity,double *red,
+  double *green,double *blue)
+{
+  double
+    intensity,
+    hue,
+    saturation;
+
+  /*
+    Increase or decrease color intensity, saturation, or hue.
+  */
+  ConvertRGBToHSI(*red,*green,*blue,&hue,&saturation,&intensity);
+  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;
+  intensity*=0.01*percent_intensity;
+  ConvertHSIToRGB(hue,saturation,intensity,red,green,blue);
+}
+
 static inline void ModulateHSL(const double percent_hue,
   const double percent_saturation,const double percent_lightness,double *red,
   double *green,double *blue)
@@ -3136,6 +3159,12 @@ MagickExport MagickBooleanType ModulateImage(Image *image,const char *modulate,
             &red,&green,&blue);
           break;
         }
+        case HSIColorspace:
+        {
+          ModulateHSI(percent_hue,percent_saturation,percent_brightness,
+            &red,&green,&blue);
+          break;
+        }
         case HSLColorspace:
         default:
         {
index 5cfb2960a6e865855b6eff8c827400cef55ab66a..b8db0ad33d157796b45c818b192544866233c065 100644 (file)
@@ -44,6 +44,8 @@ extern MagickPrivate void
     double *),
   ConvertHSBToRGB(const double,const double,const double,double *,double *,
     double *),
+  ConvertHSIToRGB(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 *,
@@ -54,6 +56,8 @@ extern MagickPrivate void
     double *),
   ConvertRGBToHSB(const double,const double,const double,double *,double *,
     double *),
+  ConvertRGBToHSI(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 c6eb401222b005cd064972f2152a960f1bddedd7..be51e32810366cbccadac40157e93a2ee76a3a8a 100644 (file)
@@ -271,6 +271,76 @@ MagickPrivate void ConvertHSBToRGB(const double hue,const double saturation,
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%   C o n v e r t H S I T o R G B                                             %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  ConvertHSIToRGB() transforms a (hue, saturation, intensity) to a (red,
+%  green, blue) triple.
+%
+%  The format of the ConvertHSIToRGBImage method is:
+%
+%      void ConvertHSIToRGB(const double hue,const double saturation,
+%        const double intensity,double *red,double *green,double *blue)
+%
+%  A description of each parameter follows:
+%
+%    o hue, saturation, intensity: A double value representing a
+%      component of the HSI color space.
+%
+%    o red, green, blue: A pointer to a pixel component of type Quantum.
+%
+*/
+MagickPrivate void ConvertHSIToRGB(const double hue,const double saturation,
+  const double intensity,double *red,double *green,double *blue)
+{
+  double
+    h;
+
+  /*
+    Convert HSI to RGB colorspace.
+  */
+  assert(red != (double *) NULL);
+  assert(green != (double *) NULL);
+  assert(blue != (double *) NULL);
+  h=360.0*hue;
+  h-=360.0*floor(h/360.0);
+  if (h < 120.0)
+    {
+      *blue=intensity*(1.0-saturation);
+      *red=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
+        (MagickPI/180.0)));
+      *green=3.0*intensity-*red-*blue;
+    }
+  else
+    if (h < 240.0)
+      {
+        h-=120.0;
+        *red=intensity*(1.0-saturation);
+        *green=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
+          (MagickPI/180.0)));
+        *blue=3.0*intensity-*red-*green;
+      }
+    else
+      {
+        h-=240.0;
+        *green=intensity*(1.0-saturation);
+        *blue=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
+          (MagickPI/180.0)));
+        *red=3.0*intensity-*green-*blue;
+      }
+  *red*=QuantumRange;
+  *green*=QuantumRange;
+  *blue*=QuantumRange;
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %   C o n v e r t H S L T o R G B                                             %
 %                                                                             %
 %                                                                             %
@@ -695,6 +765,65 @@ MagickPrivate void ConvertRGBToHSB(const double red,const double green,
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%   C o n v e r t R G B T o H S I                                             %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  ConvertRGBToHSI() transforms a (red, green, blue) to a (hue, saturation,
+%  intensity) triple.
+%
+%  The format of the ConvertRGBToHSI method is:
+%
+%      void ConvertRGBToHSI(const double red,const double green,
+%        const double blue,double *hue,double *saturation,double *intensity)
+%
+%  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, intensity: A pointer to a double value representing a
+%      component of the HSI color space.
+%
+*/
+MagickPrivate void ConvertRGBToHSI(const double red,const double green,
+  const double blue,double *hue,double *saturation,double *intensity)
+{
+  double
+    alpha,
+    beta;
+
+  /*
+    Convert RGB to HSI colorspace.
+  */
+  assert(hue != (double *) NULL);
+  assert(saturation != (double *) NULL);
+  assert(intensity != (double *) NULL);
+  *intensity=(QuantumScale*red+QuantumScale*green+QuantumScale*blue)/3.0;
+  if (*intensity <= 0.0)
+    {
+      *hue=0.0;
+      *saturation=0.0;
+    }
+  else
+    {
+      *saturation=1.0-MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
+        QuantumScale*blue))/(*intensity);
+      alpha=0.5*(2.0*QuantumScale*red-QuantumScale*green-QuantumScale*blue);
+      beta=0.866025403784439*(QuantumScale*green-QuantumScale*blue);
+      *hue=atan2(beta,alpha)*(180.0/MagickPI)/360.0;
+      if (*hue < 0.0)
+        *hue+=1.0;
+    }
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %   C o n v e r t R G B T o H S L                                             %
 %                                                                             %
 %                                                                             %
index 1800d140c44f92a37e046bdf47c9a9a564d63eaa..222347b36e3fc5373ae09209780c43fd77650413 100644 (file)
@@ -887,6 +887,7 @@ static const OptionInfo
     { "Gray", GRAYColorspace, UndefinedOptionFlag, MagickFalse },
     { "HCL", HCLColorspace, UndefinedOptionFlag, MagickFalse },
     { "HSB", HSBColorspace, UndefinedOptionFlag, MagickFalse },
+    { "HSI", HSIColorspace, UndefinedOptionFlag, MagickFalse },
     { "HSL", HSLColorspace, UndefinedOptionFlag, MagickFalse },
     { "HWB", HWBColorspace, UndefinedOptionFlag, MagickFalse },
     { "Lab", LabColorspace, UndefinedOptionFlag, MagickFalse },