]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/colorspace.c
Fixed detection of Ghostscript location.
[imagemagick] / MagickCore / colorspace.c
index c4f44a5e895cbaa0b7b9197f380abc05c56dd92a..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  %
@@ -115,15 +115,17 @@ static MagickBooleanType
 %
 */
 
+static inline void ConvertRGBToCMY(const double red,const double green,
+  const double blue,double *cyan,double *magenta,double *yellow)
+{
+  *cyan=QuantumScale*(QuantumRange-red);
+  *magenta=QuantumScale*(QuantumRange-green);
+  *yellow=QuantumScale*(QuantumRange-blue);
+}
+
 static inline void ConvertXYZToLMS(const double x,const double y,
   const double z,double *L,double *M,double *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.0061*z);
   *S=0.0030*x+0.0136*y+0.9834*z;
@@ -165,61 +167,42 @@ 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)
 {
-  /*
-    Convert RGB to YIQ colorspace.
-  */
-  assert(Y != (double *) NULL);
-  assert(I != (double *) NULL);
-  assert(Q != (double *) NULL);
-  *Y=0.298839*red+0.586811*green+0.114350*blue;
-  *I=0.595716*red-0.274453*green-0.321263*blue+0.5;
-  *Q=0.211456*red-0.522591*green+0.311135*blue+0.5;
+  *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
+  *I=QuantumScale*(0.595716*red-0.274453*green-0.321263*blue)+0.5;
+  *Q=QuantumScale*(0.211456*red-0.522591*green+0.311135*blue)+0.5;
 }
 
 static void ConvertRGBToYPbPr(const double red,const double green,
   const double blue,double *Y,double *Pb,double *Pr)
 {
-  /*
-    Convert RGB to YPbPr colorspace.
-  */
-  assert(Y != (double *) NULL);
-  assert(Pb != (double *) NULL);
-  assert(Pr != (double *) NULL);
-  *Y=0.298839*QuantumScale*red+0.586811*QuantumScale*green+0.114350*
-    QuantumScale*blue;
-  *Pb=(-0.1687367)*QuantumScale*red-0.331264*QuantumScale*green+0.5*
-    QuantumScale*blue+0.5;
-  *Pr=0.5*QuantumScale*red-0.418688*QuantumScale*green-0.081312*
-    QuantumScale*blue+0.5;
+  *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
+  *Pb=QuantumScale*((-0.1687367)*red-0.331264*green+0.5*blue)+0.5;
+  *Pr=QuantumScale*(0.5*red-0.418688*green-0.081312*blue)+0.5;
 }
 
 static void ConvertRGBToYCbCr(const double red,const double green,
   const double blue,double *Y,double *Cb,double *Cr)
 {
-  /*
-    Convert RGB to -YCbCr colorspace.
-  */
-  assert(Y != (double *) NULL);
-  assert(Cb != (double *) NULL);
-  assert(Cr != (double *) NULL);
   ConvertRGBToYPbPr(red,green,blue,Y,Cb,Cr);
 }
 
 static void ConvertRGBToYUV(const double red,const double green,
   const double blue,double *Y,double *U,double *V)
 {
-  /*
-    Convert RGB to YUV colorspace.
-  */
-  assert(Y != (double *) NULL);
-  assert(U != (double *) NULL);
-  assert(V != (double *) NULL);
-  *Y=0.298839*red+0.586811*green+0.114350*blue;
-  *U=(-0.147)*red-0.289*green+0.436*blue+0.5;
-  *V=0.615*red-0.515*green-0.100*blue+0.5;
+  *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
+  *U=QuantumScale*((-0.147)*red-0.289*green+0.436*blue)+0.5;
+  *V=QuantumScale*(0.615*red-0.515*green-0.100*blue)+0.5;
 }
 
 static MagickBooleanType sRGBTransformImage(Image *image,
@@ -261,69 +244,6 @@ static MagickBooleanType sRGBTransformImage(Image *image,
   progress=0;
   switch (colorspace)
   {
-    case CMYColorspace:
-    {
-      /*
-        Convert RGB to CMY colorspace.
-      */
-      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
-            cyan,
-            magenta,
-            yellow;
-
-          cyan=(MagickRealType) GetPixelCyan(image,q);
-          magenta=(MagickRealType) GetPixelMagenta(image,q);
-          yellow=(MagickRealType) GetPixelYellow(image,q);
-          SetPixelCyan(image,ClampToQuantum(QuantumRange-cyan),q);
-          SetPixelMagenta(image,ClampToQuantum(QuantumRange-magenta),q);
-          SetPixelYellow(image,ClampToQuantum(QuantumRange-yellow),q);
-          q+=GetPixelChannels(image);
-        }
-        sync=SyncCacheViewAuthenticPixels(image_view,exception);
-        if (sync == MagickFalse)
-          status=MagickFalse;
-      }
-      image_view=DestroyCacheView(image_view);
-      image->type=image->alpha_trait != BlendPixelTrait ? ColorSeparationType :
-        ColorSeparationMatteType;
-      if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
-        return(MagickFalse);
-      return(status);
-    }
     case CMYKColorspace:
     {
       PixelInfo
@@ -441,6 +361,7 @@ static MagickBooleanType sRGBTransformImage(Image *image,
       image->type=GrayscaleType;
       return(status);
     }
+    case CMYColorspace:
     case HCLColorspace:
     case HCLpColorspace:
     case HSBColorspace:
@@ -456,6 +377,7 @@ static MagickBooleanType sRGBTransformImage(Image *image,
     case LuvColorspace:
     case XYZColorspace:
     case YCbCrColorspace:
+    case YDbDrColorspace:
     case YIQColorspace:
     case YPbPrColorspace:
     case YUVColorspace:
@@ -510,6 +432,11 @@ static MagickBooleanType sRGBTransformImage(Image *image,
           blue=(double) GetPixelBlue(image,q);
           switch (colorspace)
           {
+            case CMYColorspace:
+            {
+              ConvertRGBToCMY(red,green,blue,&X,&Y,&Z);
+              break;
+            }
             case HCLColorspace:
             {
               ConvertRGBToHCL(red,green,blue,&X,&Y,&Z);
@@ -581,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);
@@ -597,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);
@@ -701,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);
@@ -871,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
 
@@ -886,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);
@@ -1114,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
 /*
@@ -1191,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.
   */
@@ -1244,12 +1193,17 @@ MagickExport MagickBooleanType TransformImageColorspace(Image *image,
 %
 */
 
+static inline void ConvertCMYToRGB(const double cyan,const double magenta,
+  const double yellow,double *red,double *green,double *blue)
+{
+  *red=QuantumRange*(1.0-cyan);
+  *green=QuantumRange*(1.0-magenta);
+  *blue=QuantumRange*(1.0-yellow);
+}
+
 static inline void ConvertLMSToXYZ(const double L,const double M,const double S,
   double *X,double *Y,double *Z)
 {
-  assert(X != (double *) NULL);
-  assert(Y != (double *) NULL);
-  assert(Z != (double *) NULL);
   *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;
@@ -1275,7 +1229,7 @@ static inline void ConvertLuvToRGB(const double L,const double u,
     Y,
     Z;
 
-  ConvertLuvToXYZ(L,u,v,&X,&Y,&Z);
+  ConvertLuvToXYZ(100.0*L,354.0*u-134.0,262.0*v-140.0,&X,&Y,&Z);
   ConvertXYZToRGB(X,Y,Z,red,green,blue);
 }
 
@@ -1306,19 +1260,13 @@ static inline void ConvertLabToRGB(const double L,const double a,
     Y,
     Z;
 
-  ConvertLabToXYZ(L,a,b,&X,&Y,&Z);
+  ConvertLabToXYZ(100.0*L,255.0*(a-0.5),255.0*(b-0.5),&X,&Y,&Z);
   ConvertXYZToRGB(X,Y,Z,red,green,blue);
 }
 
 static void ConvertYPbPrToRGB(const double Y,const double Pb,const double Pr,
   double *red,double *green,double *blue)
 {
-  /*
-    Convert YPbPr to RGB colorspace.
-  */
-  assert(red != (double *) NULL);
-  assert(green != (double *) NULL);
-  assert(blue != (double *) NULL);
   *red=QuantumRange*(0.99999999999914679361*Y-1.2188941887145875e-06*(Pb-0.5)+
     1.4019995886561440468*(Pr-0.5));
   *green=QuantumRange*(0.99999975910502514331*Y-0.34413567816504303521*(Pb-0.5)-
@@ -1330,41 +1278,40 @@ static void ConvertYPbPrToRGB(const double Y,const double Pb,const double Pr,
 static void ConvertYCbCrToRGB(const double Y,const double Cb,
   const double Cr,double *red,double *green,double *blue)
 {
-  /*
-    Convert -YCbCr to RGB colorspace.
-  */
-  assert(red != (double *) NULL);
-  assert(green != (double *) NULL);
-  assert(blue != (double *) NULL);
   ConvertYPbPrToRGB(Y,Cb,Cr,red,green,blue);
 }
 
 static void ConvertYIQToRGB(const double Y,const double I,const double Q,
   double *red,double *green,double *blue)
 {
-  /*
-    Convert YIQ to RGB colorspace.
-  */
-  assert(red != (double *) NULL);
-  assert(green != (double *) NULL);
-  assert(blue != (double *) NULL);
-  *red=Y+0.9562957197589482261*(I-0.5)+0.6210244164652610754*(Q-0.5);
-  *green=Y-0.2721220993185104464*(I-0.5)-0.6473805968256950427*(Q-0.5);
-  *blue=Y-1.1069890167364901945*(I-0.5)+1.7046149983646481374*(Q-0.5);
+  *red=QuantumRange*(Y+0.9562957197589482261*(I-0.5)+0.6210244164652610754*
+    (Q-0.5));
+  *green=QuantumRange*(Y-0.2721220993185104464*(I-0.5)-0.6473805968256950427*
+    (Q-0.5));
+  *blue=QuantumRange*(Y-1.1069890167364901945*(I-0.5)+1.7046149983646481374*
+    (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)
 {
-  /*
-    Convert YUV to RGB colorspace.
-  */
-  assert(red != (double *) NULL);
-  assert(green != (double *) NULL);
-  assert(blue != (double *) NULL);
-  *red=Y-3.945707070708279e-05*(U-0.5)+1.1398279671717170825*(V-0.5);
-  *green=Y-0.3946101641414141437*(U-0.5)-0.5805003156565656797*(V-0.5);
-  *blue=Y+2.0319996843434342537*(U-0.5)-4.813762626262513e-04*(V-0.5);
+  *red=QuantumRange*(Y-3.945707070708279e-05*(U-0.5)+1.1398279671717170825*
+    (V-0.5));
+  *green=QuantumRange*(Y-0.3946101641414141437*(U-0.5)-0.5805003156565656797*
+    (V-0.5));
+  *blue=QuantumRange*(Y+2.0319996843434342537*(U-0.5)-4.813762626262513e-04*
+    (V-0.5));
 }
 
 static MagickBooleanType TransformsRGBImage(Image *image,
@@ -1637,67 +1584,6 @@ static MagickBooleanType TransformsRGBImage(Image *image,
   progress=0;
   switch (image->colorspace)
   {
-    case CMYColorspace:
-    {
-      /*
-        Transform image from CMY 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
-            cyan,
-            magenta,
-            yellow;
-
-          cyan=(MagickRealType) (QuantumRange-GetPixelCyan(image,q));
-          magenta=(MagickRealType) (QuantumRange-GetPixelMagenta(image,q));
-          yellow=(MagickRealType) (QuantumRange-GetPixelYellow(image,q));
-          SetPixelCyan(image,ClampToQuantum(cyan),q);
-          SetPixelMagenta(image,ClampToQuantum(magenta),q);
-          SetPixelYellow(image,ClampToQuantum(yellow),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 CMYKColorspace:
     {
       PixelInfo
@@ -1800,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);
@@ -1818,6 +1707,7 @@ static MagickBooleanType TransformsRGBImage(Image *image,
         return(MagickFalse);
       return(status);
     }
+    case CMYColorspace:
     case HCLColorspace:
     case HCLpColorspace:
     case HSBColorspace:
@@ -1833,6 +1723,7 @@ static MagickBooleanType TransformsRGBImage(Image *image,
     case LuvColorspace:
     case XYZColorspace:
     case YCbCrColorspace:
+    case YDbDrColorspace:
     case YIQColorspace:
     case YPbPrColorspace:
     case YUVColorspace:
@@ -1887,6 +1778,11 @@ static MagickBooleanType TransformsRGBImage(Image *image,
           Z=QuantumScale*GetPixelBlue(image,q);
           switch (image->colorspace)
           {
+            case CMYColorspace:
+            {
+              ConvertCMYToRGB(X,Y,Z,&red,&green,&blue);
+              break;
+            }
             case HCLColorspace:
             {
               ConvertHCLToRGB(X,Y,Z,&red,&green,&blue);
@@ -1958,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);
@@ -1974,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);
@@ -2083,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);
@@ -2192,6 +2101,9 @@ static MagickBooleanType TransformsRGBImage(Image *image,
       /*
         Initialize OHTA tables:
 
+          I1 = 0.33333*R+0.33334*G+0.33333*B
+          I2 = 0.50000*R+0.00000*G-0.50000*B
+          I3 =-0.25000*R+0.50000*G-0.25000*B
           R = I1+1.00000*I2-0.66668*I3
           G = I1+0.00000*I2+1.33333*I3
           B = I1-1.00000*I2-0.66668*I3