]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/colorspace.c
(no commit message)
[imagemagick] / MagickCore / colorspace.c
index 830c6beb23e31c2c02d6ae4ce7d62a0f785df746..0ea8c8a502bede2baccbd1afd5cec51ff66e6722 100644 (file)
 %                     MagickCore Image Colorspace Methods                     %
 %                                                                             %
 %                              Software Design                                %
-%                                John Cristy                                  %
+%                                   Cristy                                    %
 %                                 July 1992                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
@@ -167,6 +167,14 @@ static void ConvertRGBToLuv(const double red,const double green,
   ConvertXYZToLuv(X,Y,Z,L,u,v);
 }
 
+static void ConvertRGBToYDbDr(const double red,const double green,
+  const double blue,double *Y,double *Db,double *Dr)
+{
+  *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
+  *Db=QuantumScale*(-0.450*red-0.883*green+1.333*blue)+0.5;
+  *Dr=QuantumScale*(-1.333*red+1.116*green+0.217*blue)+0.5;
+}
+
 static void ConvertRGBToYIQ(const double red,const double green,
   const double blue,double *Y,double *I,double *Q)
 {
@@ -369,6 +377,7 @@ static MagickBooleanType sRGBTransformImage(Image *image,
     case LuvColorspace:
     case XYZColorspace:
     case YCbCrColorspace:
+    case YDbDrColorspace:
     case YIQColorspace:
     case YPbPrColorspace:
     case YUVColorspace:
@@ -499,6 +508,11 @@ static MagickBooleanType sRGBTransformImage(Image *image,
               ConvertRGBToYCbCr(red,green,blue,&X,&Y,&Z);
               break;
             }
+            case YDbDrColorspace:
+            {
+              ConvertRGBToYDbDr(red,green,blue,&X,&Y,&Z);
+              break;
+            }
             case YIQColorspace:
             {
               ConvertRGBToYIQ(red,green,blue,&X,&Y,&Z);
@@ -515,7 +529,12 @@ static MagickBooleanType sRGBTransformImage(Image *image,
               break;
             }
             default:
+            {
+              X=QuantumScale*red;
+              Y=QuantumScale*green;
+              Z=QuantumScale*blue;
               break;
+            }
           }
           SetPixelRed(image,ClampToQuantum(QuantumRange*X),q);
           SetPixelGreen(image,ClampToQuantum(QuantumRange*Y),q);
@@ -619,9 +638,12 @@ static MagickBooleanType sRGBTransformImage(Image *image,
             green,
             red;
 
-          red=(double) GetPixelRed(image,q);
-          green=(double) GetPixelGreen(image,q);
-          blue=(double) GetPixelBlue(image,q);
+          red=(double) DecodePixelGamma((MagickRealType)
+            GetPixelRed(image,q));
+          green=(double) DecodePixelGamma((MagickRealType)
+            GetPixelGreen(image,q));
+          blue=(double) DecodePixelGamma((MagickRealType)
+            GetPixelBlue(image,q));
           SetPixelRed(image,logmap[ScaleQuantumToMap(ClampToQuantum(red))],q);
           SetPixelGreen(image,logmap[ScaleQuantumToMap(ClampToQuantum(green))],
             q);
@@ -789,7 +811,7 @@ static MagickBooleanType sRGBTransformImage(Image *image,
       /*
         Initialize YCbCr tables (ITU-R BT.709):
 
-          Y =  0.212600*R+0.715200*G+0.072200*B
+          Y =  0.212656*R+0.715158*G+0.072186*B
           Cb= -0.114572*R-0.385428*G+0.500000*B
           Cr=  0.500000*R-0.454153*G-0.045847*B
 
@@ -804,9 +826,9 @@ static MagickBooleanType sRGBTransformImage(Image *image,
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
-        x_map[i].x=(MagickRealType) (0.212600*(double) i);
-        y_map[i].x=(MagickRealType) (0.715200*(double) i);
-        z_map[i].x=(MagickRealType) (0.072200*(double) i);
+        x_map[i].x=(MagickRealType) (0.212656*(double) i);
+        y_map[i].x=(MagickRealType) (0.715158*(double) i);
+        z_map[i].x=(MagickRealType) (0.072186*(double) i);
         x_map[i].y=(MagickRealType) (-0.114572*(double) i);
         y_map[i].y=(MagickRealType) (-0.385428*(double) i);
         z_map[i].y=(MagickRealType) (0.500000*(double) i);
@@ -1032,43 +1054,49 @@ static MagickBooleanType sRGBTransformImage(Image *image,
 MagickExport MagickBooleanType SetImageColorspace(Image *image,
   const ColorspaceType colorspace,ExceptionInfo *exception)
 {
+  ImageType
+    type;
+
+  MagickBooleanType
+    status;
+
   if (image->colorspace == colorspace)
     return(MagickTrue);
   image->colorspace=colorspace;
   image->rendering_intent=UndefinedIntent;
-  image->gamma=1.000;
+  image->gamma=1.000/2.200;
   (void) ResetMagickMemory(&image->chromaticity,0,sizeof(image->chromaticity));
+  type=image->type;
   if (IsGrayColorspace(colorspace) != MagickFalse)
     {
-      if ((image->intensity != Rec601LuminancePixelIntensityMethod) &&
-          (image->intensity != Rec709LuminancePixelIntensityMethod) &&
-          (image->intensity != UndefinedPixelIntensityMethod))
-        image->gamma=1.000/2.200;
-      image->type=GrayscaleType;
+      if ((image->intensity == Rec601LuminancePixelIntensityMethod) ||
+          (image->intensity == Rec709LuminancePixelIntensityMethod))
+        image->gamma=1.000;
+      type=GrayscaleType;
     }
   else
-    if (IssRGBColorspace(colorspace) != MagickFalse)
-      image->gamma=1.000/2.200;
-  if (image->gamma == (1.000/2.200))
-    {
-      image->rendering_intent=PerceptualIntent;
-      image->gamma=1.000/2.200;
-      image->chromaticity.red_primary.x=0.6400;
-      image->chromaticity.red_primary.y=0.3300;
-      image->chromaticity.red_primary.z=0.0300;
-      image->chromaticity.green_primary.x=0.3000;
-      image->chromaticity.green_primary.y=0.6000;
-      image->chromaticity.green_primary.z=0.1000;
-      image->chromaticity.blue_primary.x=0.1500;
-      image->chromaticity.blue_primary.y=0.0600;
-      image->chromaticity.blue_primary.z=0.7900;
-      image->chromaticity.white_point.x=0.3127;
-      image->chromaticity.white_point.y=0.3290;
-      image->chromaticity.white_point.z=0.3583;
-    }
-  if (IsGrayColorspace(colorspace) != MagickFalse)
-    image->type=GrayscaleType;
-  return(SyncImagePixelCache(image,exception));
+    if ((IsRGBColorspace(colorspace) != MagickFalse) ||
+        (colorspace == XYZColorspace))
+      image->gamma=1.000;
+    else
+      {
+        image->rendering_intent=PerceptualIntent;
+        image->chromaticity.red_primary.x=0.6400;
+        image->chromaticity.red_primary.y=0.3300;
+        image->chromaticity.red_primary.z=0.0300;
+        image->chromaticity.green_primary.x=0.3000;
+        image->chromaticity.green_primary.y=0.6000;
+        image->chromaticity.green_primary.z=0.1000;
+        image->chromaticity.blue_primary.x=0.1500;
+        image->chromaticity.blue_primary.y=0.0600;
+        image->chromaticity.blue_primary.z=0.7900;
+        image->chromaticity.white_point.x=0.3127;
+        image->chromaticity.white_point.y=0.3290;
+        image->chromaticity.white_point.z=0.3583;
+      }
+  status=SyncImagePixelCache(image,exception);
+  image->type=type;
+  return(status);
 }
 \f
 /*
@@ -1109,10 +1137,13 @@ MagickExport MagickBooleanType TransformImageColorspace(Image *image,
   assert(image->signature == MagickSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
+  if (image->colorspace == colorspace)
+    return(MagickTrue);
+  if ((image->colorspace == GRAYColorspace) && (image->gamma != 1.0) &&
+      (colorspace == sRGBColorspace))
+    return(MagickTrue);
   if (colorspace == UndefinedColorspace)
     return(SetImageColorspace(image,colorspace,exception));
-  if (image->colorspace == colorspace)
-    return(MagickTrue);  /* same colorspace: no op */
   /*
     Convert the reference image from an alternate colorspace to sRGB.
   */
@@ -1261,6 +1292,17 @@ static void ConvertYIQToRGB(const double Y,const double I,const double Q,
     (Q-0.5));
 }
 
+static void ConvertYDbDrToRGB(const double Y,const double Db,const double Dr,
+  double *red,double *green,double *blue)
+{
+  *red=QuantumRange*(Y+9.2303716147657e-05*(Db-0.5)-
+    0.52591263066186533*(Dr-0.5));
+  *green=QuantumRange*(Y-0.12913289889050927*(Db-0.5)+
+    0.26789932820759876*(Dr-0.5));
+  *blue=QuantumRange*(Y+0.66467905997895482*(Db-0.5)-
+    7.9202543533108e-05*(Dr-0.5));
+}
+
 static void ConvertYUVToRGB(const double Y,const double U,const double V,
   double *red,double *green,double *blue)
 {
@@ -1644,10 +1686,13 @@ static MagickBooleanType TransformsRGBImage(Image *image,
           }
         for (x=(ssize_t) image->columns; x != 0; x--)
         {
-          double
+          MagickRealType
             gray;
 
-          gray=EncodePixelGamma((MagickRealType) GetPixelGray(image,q));
+          gray=(MagickRealType) GetPixelGray(image,q);
+          if ((image->intensity == Rec601LuminancePixelIntensityMethod) ||
+              (image->intensity == Rec709LuminancePixelIntensityMethod))
+            gray=EncodePixelGamma(gray);
           SetPixelRed(image,ClampToQuantum(gray),q);
           SetPixelGreen(image,ClampToQuantum(gray),q);
           SetPixelBlue(image,ClampToQuantum(gray),q);
@@ -1678,6 +1723,7 @@ static MagickBooleanType TransformsRGBImage(Image *image,
     case LuvColorspace:
     case XYZColorspace:
     case YCbCrColorspace:
+    case YDbDrColorspace:
     case YIQColorspace:
     case YPbPrColorspace:
     case YUVColorspace:
@@ -1808,6 +1854,11 @@ static MagickBooleanType TransformsRGBImage(Image *image,
               ConvertYCbCrToRGB(X,Y,Z,&red,&green,&blue);
               break;
             }
+            case YDbDrColorspace:
+            {
+              ConvertYDbDrToRGB(X,Y,Z,&red,&green,&blue);
+              break;
+            }
             case YIQColorspace:
             {
               ConvertYIQToRGB(X,Y,Z,&red,&green,&blue);
@@ -1824,7 +1875,12 @@ static MagickBooleanType TransformsRGBImage(Image *image,
               break;
             }
             default:
+            {
+              red=QuantumRange*X;
+              green=QuantumRange*Y;
+              blue=QuantumRange*Z;
               break;
+            }
           }
           SetPixelRed(image,ClampToQuantum(red),q);
           SetPixelGreen(image,ClampToQuantum(green),q);
@@ -1933,9 +1989,12 @@ static MagickBooleanType TransformsRGBImage(Image *image,
           red=(double) logmap[ScaleQuantumToMap(GetPixelRed(image,q))];
           green=(double) logmap[ScaleQuantumToMap(GetPixelGreen(image,q))];
           blue=(double) logmap[ScaleQuantumToMap(GetPixelBlue(image,q))];
-          SetPixelRed(image,ClampToQuantum(red),q);
-          SetPixelGreen(image,ClampToQuantum(green),q);
-          SetPixelBlue(image,ClampToQuantum(blue),q);
+          SetPixelRed(image,ClampToQuantum(EncodePixelGamma((MagickRealType)
+            red)),q);
+          SetPixelGreen(image,ClampToQuantum(EncodePixelGamma((MagickRealType)
+            green)),q);
+          SetPixelBlue(image,ClampToQuantum(EncodePixelGamma((MagickRealType)
+            blue)),q);
           q+=GetPixelChannels(image);
         }
         sync=SyncCacheViewAuthenticPixels(image_view,exception);