]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Wed, 29 Aug 2012 17:54:59 +0000 (17:54 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Wed, 29 Aug 2012 17:54:59 +0000 (17:54 +0000)
MagickCore/colorspace.c
MagickCore/colorspace.h
MagickCore/option.c

index b4d1600894d7f27da8815d0c9d30bde081a20cbf..76f1e4ee9d309fcbe5a64ae5cab13495e9473029 100644 (file)
@@ -115,6 +115,28 @@ static MagickBooleanType
 %
 */
 
+static inline void ConvertXYZToLMS(const double x,const double y,
+  const double z,double *L,double *M,double *S)
+{
+  double
+    l,
+    m,
+    s;
+
+  /*
+    Convert XYZ to LMS colorspace.
+  */
+  assert(L != (double *) NULL);
+  assert(M != (double *) NULL);
+  assert(S != (double *) NULL);
+  l=0.7328*x+0.4296*y-0.1624*z;
+  m=(-0.7036*x+1.6975*y+0.0415*z);
+  s=0.0030*x+0.0136*y+0.9834*z;
+  *L=QuantumRange*l;
+  *M=QuantumRange*m;
+  *S=QuantumRange*s;
+}
+
 static inline void ConvertRGBToXYZ(const double red,const double green,
   const double blue,double *X,double *Y,double *Z)
 {
@@ -826,6 +848,75 @@ static MagickBooleanType sRGBTransformImage(Image *image,
         return(MagickFalse);
       return(status);
     }
+    case LMSColorspace:
+    {
+      /*
+        Transform image from sRGB to LMS.
+      */
+      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) \
+        dynamic_number_threads(image,image->columns,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,
+            L,
+            M,
+            red,
+            S,
+            X,
+            Y,
+            Z;
+
+          red=InversesRGBCompandor((double) GetPixelRed(image,q));
+          green=InversesRGBCompandor((double) GetPixelGreen(image,q));
+          blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
+          ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
+          ConvertXYZToLMS(X,Y,Z,&L,&M,&S);
+          SetPixelRed(image,ClampToQuantum(QuantumRange*L),q);
+          SetPixelGreen(image,ClampToQuantum(QuantumRange*M),q);
+          SetPixelBlue(image,ClampToQuantum(QuantumRange*S),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 LogColorspace:
     {
 #define DisplayGamma  (1.0/1.7)
@@ -1745,6 +1836,25 @@ MagickExport MagickBooleanType TransformImageColorspace(Image *image,
 %
 */
 
+static inline void ConvertLMSToXYZ(const double L,const double M,const double S,
+  double *X,double *Y,double *Z)
+{
+  double
+    l,
+    m,
+    s;
+
+  assert(X != (double *) NULL);
+  assert(Y != (double *) NULL);
+  assert(Z != (double *) NULL);
+  l=QuantumScale*L;
+  m=QuantumScale*M;
+  s=QuantumScale*S;
+  *X=1.096123820835514*l-0.278869000218287*m+0.182745179382773*s;
+  *Y=0.454369041975359*l+0.473533154307412*m+0.072097803717229*s;
+  *Z=(-0.009627608738429)*l-0.005698031216113*m+1.015325639954543*s;
+}
+
 static inline void ConvertLabToXYZ(const double L,const double a,const double b,
   double *X,double *Y,double *Z)
 {
@@ -2697,6 +2807,75 @@ static MagickBooleanType TransformsRGBImage(Image *image,
         return(MagickFalse);
       return(status);
     }
+    case LMSColorspace:
+    {
+      /*
+        Transform image from LMS 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) \
+        dynamic_number_threads(image,image->columns,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,
+            L,
+            M,
+            red,
+            S,
+            X,
+            Y,
+            Z;
+
+          L=QuantumScale*GetPixelRed(image,q);
+          M=QuantumScale*GetPixelGreen(image,q);
+          S=QuantumScale*GetPixelBlue(image,q);
+          ConvertLMSToXYZ(L,M,S,&X,&Y,&Z);
+          ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
+          SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
+          SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
+          SetPixelBlue(image,ClampToQuantum(sRGBCompandor(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 LogColorspace:
     {
       const char
index 321b4a69f1cddaad90f3bd4819759b8339d12651..8f33cc8aae2de8666d638032179031969eee003e 100644 (file)
@@ -35,6 +35,7 @@ typedef enum
   LabColorspace,
   LCHColorspace,
   LogColorspace,
+  LMSColorspace,
   LuvColorspace,
   OHTAColorspace,
   Rec601LumaColorspace,
index 9b081ea7817841e677e8d79770e65dfbfb5b7365..2100a1dcc1e7962b057cbe3e51710f390a589afd 100644 (file)
@@ -871,6 +871,7 @@ static const OptionInfo
     { "HWB", HWBColorspace, UndefinedOptionFlag, MagickFalse },
     { "Lab", LabColorspace, UndefinedOptionFlag, MagickFalse },
     { "LCH", LCHColorspace, UndefinedOptionFlag, MagickFalse },
+    { "LMS", LMSColorspace, UndefinedOptionFlag, MagickFalse },
     { "Log", LogColorspace, UndefinedOptionFlag, MagickFalse },
     { "Luv", LuvColorspace, UndefinedOptionFlag, MagickFalse },
     { "OHTA", OHTAColorspace, UndefinedOptionFlag, MagickFalse },