]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/colorspace.c
(no commit message)
[imagemagick] / MagickCore / colorspace.c
index 63e29f174635d1f6aa06e47b14918fcfa3248903..dbf6b4c3c69aa2d4d851ddba9f2bc7a074c56877 100644 (file)
@@ -61,6 +61,7 @@
 #include "MagickCore/quantize.h"
 #include "MagickCore/quantum.h"
 #include "MagickCore/quantum-private.h"
+#include "MagickCore/resource_.h"
 #include "MagickCore/string_.h"
 #include "MagickCore/string-private.h"
 #include "MagickCore/utility.h"
@@ -77,24 +78,30 @@ typedef struct _TransformPacket
 } TransformPacket;
 \f
 /*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  Forward declarations.
+*/
+static MagickBooleanType
+  TransformsRGBImage(Image *,const ColorspaceType,ExceptionInfo *);
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
 %                                                                             %
 %                                                                             %
-+     R G B T r a n s f o r m I m a g e                                       %
++     s R G B T r a n s f o r m I m a g e                                     %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  RGBTransformImage() converts the reference image from RGB to an alternate
+%  sRGBTransformImage() converts the reference image from sRGB to an alternate
 %  colorspace.  The transformation matrices are not the standard ones: the
 %  weights are rescaled to normalized the range of the transformed values to
 %  be [0..QuantumRange].
 %
-%  The format of the RGBTransformImage method is:
+%  The format of the sRGBTransformImage method is:
 %
-%      MagickBooleanType RGBTransformImage(Image *image,
+%      MagickBooleanType sRGBTransformImage(Image *image,
 %        const ColorspaceType colorspace,EsceptionInfo *exception)
 %
 %  A description of each parameter follows:
@@ -119,17 +126,17 @@ static inline void ConvertRGBToXYZ(const Quantum red,const Quantum green,
   assert(Y != (double *) NULL);
   assert(Z != (double *) NULL);
   r=QuantumScale*red;
-  if (r > 0.04045)
+  if (r > 0.0404482362771082)
     r=pow((r+0.055)/1.055,2.4);
   else
     r/=12.92;
   g=QuantumScale*green;
-  if (g > 0.04045)
+  if (g > 0.0404482362771082)
     g=pow((g+0.055)/1.055,2.4);
   else
     g/=12.92;
   b=QuantumScale*blue;
-  if (b > 0.04045)
+  if (b > 0.0404482362771082)
     b=pow((b+0.055)/1.055,2.4);
   else
     b/=12.92;
@@ -179,10 +186,10 @@ static inline void ConvertXYZToLab(const double X,const double Y,const double Z,
     *b+=1.0;
 }
 
-MagickExport MagickBooleanType RGBTransformImage(Image *image,
+static MagickBooleanType sRGBTransformImage(Image *image,
   const ColorspaceType colorspace,ExceptionInfo *exception)
 {
-#define RGBTransformImageTag  "RGBTransform/Image"
+#define sRGBTransformImageTag  "RGBTransform/Image"
 
   CacheView
     *image_view;
@@ -211,25 +218,14 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
   assert(image->signature == MagickSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
-  assert(colorspace != RGBColorspace);
+  assert(colorspace != sRGBColorspace);
   assert(colorspace != TransparentColorspace);
   assert(colorspace != UndefinedColorspace);
-  switch (image->colorspace)
-  {
-    case GRAYColorspace:
-    case Rec601LumaColorspace:
-    case Rec709LumaColorspace:
-    case RGBColorspace:
-    case TransparentColorspace:
-      break;
-    default:
-    {
-      (void) TransformImageColorspace(image,image->colorspace,exception);
-      break;
-    }
-  }
-  if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
-    return(MagickFalse);
+  if (IsGrayColorspace(colorspace) != MagickFalse)
+    (void) SetImageColorspace(image,sRGBColorspace,exception);
+  else
+    if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
+      return(MagickFalse);
   status=MagickTrue;
   progress=0;
   switch (colorspace)
@@ -246,9 +242,10 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
           if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
             return(MagickFalse);
         }
-      image_view=AcquireCacheView(image);
+      image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        dynamic_number_threads(image->columns,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -305,9 +302,10 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
             return(MagickFalse);
         }
       GetPixelInfo(image,&zero);
-      image_view=AcquireCacheView(image);
+      image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        dynamic_number_threads(image->columns,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -361,9 +359,10 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
           if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
             return(MagickFalse);
         }
-      image_view=AcquireCacheView(image);
+      image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        dynamic_number_threads(image->columns,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -425,9 +424,10 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
           if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
             return(MagickFalse);
         }
-      image_view=AcquireCacheView(image);
+      image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        dynamic_number_threads(image->columns,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -489,9 +489,10 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
           if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
             return(MagickFalse);
         }
-      image_view=AcquireCacheView(image);
+      image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        dynamic_number_threads(image->columns,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -553,9 +554,10 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
           if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
             return(MagickFalse);
         }
-      image_view=AcquireCacheView(image);
+      image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        dynamic_number_threads(image->columns,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -661,15 +663,17 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
       black=pow(10.0,(reference_black-reference_white)*(gamma/density)*
         0.002/film_gamma);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
         logmap[i]=ScaleMapToQuantum((MagickRealType) (MaxMap*(reference_white+
           log10(black+((MagickRealType) i/MaxMap)*(1.0-black))/((gamma/density)*
           0.002/film_gamma))/1024.0));
-      image_view=AcquireCacheView(image);
+      image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        dynamic_number_threads(image->columns,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -744,7 +748,8 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
       primary_info.y=(double) (MaxMap+1.0)/2.0;
       primary_info.z=(double) (MaxMap+1.0)/2.0;
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -769,7 +774,8 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
           G = 0.29900*R+0.58700*G+0.11400*B
       */
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -802,7 +808,8 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
       primary_info.y=(double) (MaxMap+1.0)/2.0;
       primary_info.z=(double) (MaxMap+1.0)/2.0;
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -826,7 +833,8 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
           G = 0.21260*R+0.71520*G+0.07220*B
       */
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -857,7 +865,8 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
       primary_info.y=(double) (MaxMap+1.0)/2.0;
       primary_info.z=(double) (MaxMap+1.0)/2.0;
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -873,17 +882,15 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
       }
       break;
     }
-    case sRGBColorspace:
+    case RGBColorspace:
     {
       /*
-        Nonlinear sRGB to linear RGB (http://www.w3.org/Graphics/Color/sRGB):
-
-          R = 1.0*R+0.0*G+0.0*B
-          G = 0.0*R+0.1*G+0.0*B
-          B = 0.0*R+0.0*G+1.0*B
+        Nonlinear sRGB to linear RGB.
+        Mostly removal of a gamma function, but with a linear component
       */
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -891,7 +898,7 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
           v;
 
         v=(MagickRealType) i/(MagickRealType) MaxMap;
-        if (((MagickRealType) i/(MagickRealType) MaxMap) <= 0.04045f)
+        if (((MagickRealType) i/(MagickRealType) MaxMap) <= 0.0404482362771082f)
           v/=12.92f;
         else
           v=(MagickRealType) pow((((double) i/MaxMap)+0.055)/1.055,2.4);
@@ -917,7 +924,8 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
           Z = 0.0193339*R+0.1191920*G+0.9503041*B
       */
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -987,7 +995,8 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
       primary_info.y=(double) (MaxMap+1.0)/2.0;
       primary_info.z=(double) (MaxMap+1.0)/2.0;
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -1018,7 +1027,8 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
       primary_info.y=(double) (MaxMap+1.0)/2.0;
       primary_info.z=(double) (MaxMap+1.0)/2.0;
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -1035,7 +1045,6 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
       break;
     }
     case YUVColorspace:
-    default:
     {
       /*
         Initialize YUV tables:
@@ -1050,7 +1059,8 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
       primary_info.y=(double) (MaxMap+1.0)/2.0;
       primary_info.z=(double) (MaxMap+1.0)/2.0;
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -1066,6 +1076,29 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
       }
       break;
     }
+    default:
+    {
+      /*
+        Linear conversion tables.
+      */
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
+#endif
+      for (i=0; i <= (ssize_t) MaxMap; i++)
+      {
+        x_map[i].x=(MagickRealType) i;
+        y_map[i].x=0.0f;
+        z_map[i].x=0.0f;
+        x_map[i].y=0.0f;
+        y_map[i].y=(MagickRealType) i;
+        z_map[i].y=0.0f;
+        x_map[i].z=0.0f;
+        y_map[i].z=0.0f;
+        z_map[i].z=(MagickRealType) i;
+      }
+      break;
+    }
   }
   /*
     Convert from RGB.
@@ -1078,9 +1111,10 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
       /*
         Convert DirectClass image.
       */
-      image_view=AcquireCacheView(image);
+      image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        dynamic_number_threads(image->columns,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -1135,9 +1169,9 @@ MagickExport MagickBooleanType RGBTransformImage(Image *image,
               proceed;
 
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-            #pragma omp critical (MagickCore_RGBTransformImage)
+            #pragma omp critical (MagickCore_sRGBTransformImage)
 #endif
-            proceed=SetImageProgress(image,RGBTransformImageTag,progress++,
+            proceed=SetImageProgress(image,sRGBTransformImageTag,progress++,
               image->rows);
             if (proceed == MagickFalse)
               status=MagickFalse;
@@ -1217,6 +1251,26 @@ MagickExport MagickBooleanType SetImageColorspace(Image *image,
   const ColorspaceType colorspace,ExceptionInfo *exception)
 {
   image->colorspace=colorspace;
+  image->rendering_intent=UndefinedIntent;
+  image->gamma=1.000f;
+  ResetMagickMemory(&image->chromaticity,0,sizeof(image->chromaticity));
+  if (IssRGBColorspace(colorspace) != MagickFalse)
+    {
+      image->rendering_intent=PerceptualIntent;
+      image->gamma=1.000f/2.200f;
+      image->chromaticity.red_primary.x=0.6400f;
+      image->chromaticity.red_primary.y=0.3300f;
+      image->chromaticity.red_primary.z=0.0300f;
+      image->chromaticity.green_primary.x=0.3000f;
+      image->chromaticity.green_primary.y=0.6000f;
+      image->chromaticity.green_primary.z=0.1000f;
+      image->chromaticity.blue_primary.x=0.1500f;
+      image->chromaticity.blue_primary.y=0.0600f;
+      image->chromaticity.blue_primary.z=0.7900f;
+      image->chromaticity.white_point.x=0.3127f;
+      image->chromaticity.white_point.y=0.3290f;
+      image->chromaticity.white_point.z=0.3583f;
+    }
   return(SyncImagePixelCache(image,exception));
 }
 \f
@@ -1231,7 +1285,8 @@ MagickExport MagickBooleanType SetImageColorspace(Image *image,
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  TransformImageColorspace() transforms an image colorspace.
+%  TransformImageColorspace() transforms an image colorspace, changing the
+%  image data to reflect the new colorspace.
 %
 %  The format of the TransformImageColorspace method is:
 %
@@ -1260,15 +1315,26 @@ MagickExport MagickBooleanType TransformImageColorspace(Image *image,
   if (colorspace == UndefinedColorspace)
     return(SetImageColorspace(image,colorspace,exception));
   if (image->colorspace == colorspace)
-    return(MagickTrue);
-  if ((colorspace == RGBColorspace) || (colorspace == TransparentColorspace))
-    return(TransformRGBImage(image,colorspace,exception));
+    return(MagickTrue);  /* same colorspace: no op */
+  /*
+    Convert the reference image from an alternate colorspace to sRGB.
+  */
+  if (IssRGBColorspace(colorspace) != MagickFalse)
+    return(TransformsRGBImage(image,colorspace,exception));
   status=MagickTrue;
-  if ((image->colorspace != RGBColorspace) &&
-      (image->colorspace != TransparentColorspace) &&
-      (image->colorspace != GRAYColorspace))
-    status=TransformRGBImage(image,image->colorspace,exception);
-  if (RGBTransformImage(image,colorspace,exception) == MagickFalse)
+  if ((IsRGBColorspace(image->colorspace) != MagickFalse) ||
+      (IsGrayColorspace(image->colorspace) != MagickFalse))
+    status=TransformsRGBImage(image,sRGBColorspace,exception);
+  if (status == MagickFalse)
+    return(status);
+  if (IssRGBColorspace(image->colorspace) == MagickFalse)
+    status=TransformsRGBImage(image,image->colorspace,exception);
+  if (status == MagickFalse)
+    return(status);
+  /*
+    Convert the reference image from sRGB to an alternate colorspace.
+  */
+  if (sRGBTransformImage(image,colorspace,exception) == MagickFalse)
     status=MagickFalse;
   return(status);
 }
@@ -1278,20 +1344,20 @@ MagickExport MagickBooleanType TransformImageColorspace(Image *image,
 %                                                                             %
 %                                                                             %
 %                                                                             %
-+     T r a n s f o r m R G B I m a g e                                       %
++     T r a n s f o r m s R G B I m a g e                                     %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  TransformRGBImage() converts the reference image from an alternate
-%  colorspace to RGB.  The transformation matrices are not the standard ones:
-%  the weights are rescaled to normalize the range of the transformed values to
-%  be [0..QuantumRange].
+%  TransformsRGBImage() converts the reference image from an alternate
+%  colorspace to sRGB.  The transformation matrices are not the standard ones:
+%  the weights are rescaled to normalize the range of the transformed values
+%  to be [0..QuantumRange].
 %
-%  The format of the TransformRGBImage method is:
+%  The format of the TransformsRGBImage method is:
 %
-%      MagickBooleanType TransformRGBImage(Image *image,
+%      MagickBooleanType TransformsRGBImage(Image *image,
 %        const ColorspaceType colorspace,ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
@@ -1368,15 +1434,15 @@ static inline void ConvertXYZToRGB(const double x,const double y,const double z,
   r=3.2404542*x-1.5371385*y-0.4985314*z;
   g=(-0.9692660*x+1.8760108*y+0.0415560*z);
   b=0.0556434*x-0.2040259*y+1.0572252*z;
-  if (r > 0.0031308)
+  if (r > 0.00313066844250063)
     r=1.055*pow(r,1.0/2.4)-0.055;
   else
     r*=12.92;
-  if (g > 0.0031308)
+  if (g > 0.00313066844250063)
     g=1.055*pow(g,1.0/2.4)-0.055;
   else
     g*=12.92;
-  if (b > 0.0031308)
+  if (b > 0.00313066844250063)
     b=1.055*pow(b,1.0/2.4)-0.055;
   else
     b*=12.92;
@@ -1395,13 +1461,13 @@ static inline void ConvertCMYKToRGB(PixelInfo *pixel)
     (QuantumRange-pixel->black)+pixel->black);
 }
 
-MagickExport MagickBooleanType TransformRGBImage(Image *image,
+static MagickBooleanType TransformsRGBImage(Image *image,
   const ColorspaceType colorspace,ExceptionInfo *exception)
 {
 #define D50X  (0.9642)
 #define D50Y  (1.0)
 #define D50Z  (0.8249)
-#define TransformRGBImageTag  "Transform/Image"
+#define TransformsRGBImageTag  "Transform/Image"
 
 #if !defined(MAGICKCORE_HDRI_SUPPORT)
   static const float
@@ -1666,25 +1732,9 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
   assert(image->signature == MagickSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
-  switch (colorspace)
-  {
-    case GRAYColorspace:
-    case RGBColorspace:
-    {
-      image->colorspace=colorspace;
-      return(MagickTrue);
-    }
-    case Rec601LumaColorspace:
-    case Rec709LumaColorspace:
-    case TransparentColorspace:
-    case UndefinedColorspace:
-      return(MagickTrue);
-    default:
-      break;
-  }
   status=MagickTrue;
   progress=0;
-  switch (colorspace)
+  switch (image->colorspace)
   {
     case CMYColorspace:
     {
@@ -1698,9 +1748,10 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
           if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
             return(MagickFalse);
         }
-      image_view=AcquireCacheView(image);
+      image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        dynamic_number_threads(image->columns,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -1737,7 +1788,7 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
           status=MagickFalse;
       }
       image_view=DestroyCacheView(image_view);
-      if (SetImageColorspace(image,RGBColorspace,exception) == MagickFalse)
+      if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
         return(MagickFalse);
       return(status);
     }
@@ -1757,9 +1808,10 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
             return(MagickFalse);
         }
       GetPixelInfo(image,&zero);
-      image_view=AcquireCacheView(image);
+      image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        dynamic_number_threads(image->columns,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -1797,7 +1849,7 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
           status=MagickFalse;
       }
       image_view=DestroyCacheView(image_view);
-      if (SetImageColorspace(image,RGBColorspace,exception) == MagickFalse)
+      if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
         return(MagickFalse);
       return(status);
     }
@@ -1813,9 +1865,10 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
           if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
             return(MagickFalse);
         }
-      image_view=AcquireCacheView(image);
+      image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        dynamic_number_threads(image->columns,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -1863,7 +1916,7 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
           status=MagickFalse;
       }
       image_view=DestroyCacheView(image_view);
-      if (SetImageColorspace(image,RGBColorspace,exception) == MagickFalse)
+      if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
         return(MagickFalse);
       return(status);
     }
@@ -1879,9 +1932,10 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
           if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
             return(MagickFalse);
         }
-      image_view=AcquireCacheView(image);
+      image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        dynamic_number_threads(image->columns,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -1929,7 +1983,7 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
           status=MagickFalse;
       }
       image_view=DestroyCacheView(image_view);
-      if (SetImageColorspace(image,RGBColorspace,exception) == MagickFalse)
+      if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
         return(MagickFalse);
       return(status);
     }
@@ -1945,9 +1999,10 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
           if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
             return(MagickFalse);
         }
-      image_view=AcquireCacheView(image);
+      image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        dynamic_number_threads(image->columns,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -1995,7 +2050,7 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
           status=MagickFalse;
       }
       image_view=DestroyCacheView(image_view);
-      if (SetImageColorspace(image,RGBColorspace,exception) == MagickFalse)
+      if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
         return(MagickFalse);
       return(status);
     }
@@ -2011,9 +2066,10 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
           if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
             return(MagickFalse);
         }
-      image_view=AcquireCacheView(image);
+      image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        dynamic_number_threads(image->columns,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -2068,7 +2124,7 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
           status=MagickFalse;
       }
       image_view=DestroyCacheView(image_view);
-      if (SetImageColorspace(image,RGBColorspace,exception) == MagickFalse)
+      if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
         return(MagickFalse);
       return(status);
     }
@@ -2126,9 +2182,10 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
         logmap[i]=(Quantum) QuantumRange;
       if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
         return(MagickFalse);
-      image_view=AcquireCacheView(image);
+      image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        dynamic_number_threads(image->columns,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -2166,7 +2223,7 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
       }
       image_view=DestroyCacheView(image_view);
       logmap=(Quantum *) RelinquishMagickMemory(logmap);
-      if (SetImageColorspace(image,RGBColorspace,exception) == MagickFalse)
+      if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
         return(MagickFalse);
       return(status);
     }
@@ -2195,7 +2252,7 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
       ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
         image->filename);
     }
-  switch (colorspace)
+  switch (image->colorspace)
   {
     case OHTAColorspace:
     {
@@ -2210,7 +2267,8 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
         through QuantumRange.
       */
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -2245,7 +2303,8 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
         through QuantumRange.
       */
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -2278,7 +2337,8 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
         through QuantumRange.
       */
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -2298,29 +2358,38 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
       }
       break;
     }
-    case sRGBColorspace:
+    case RGBColorspace:
     {
       /*
-        Nonlinear sRGB to linear RGB.
+        Nonlinear sRGB to linear RGB (http://www.w3.org/Graphics/Color/sRGB):
 
           R = 1.0*R+0.0*G+0.0*B
           G = 0.0*R+1.0*G+0.0*B
           B = 0.0*R+0.0*G+1.0*B
       */
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
-        x_map[i].x=1.0f*(MagickRealType) i;
-        y_map[i].x=0.0f*(MagickRealType) i;
-        z_map[i].x=0.0f*(MagickRealType) i;
-        x_map[i].y=0.0f*(MagickRealType) i;
-        y_map[i].y=1.0f*(MagickRealType) i;
-        z_map[i].y=0.0f*(MagickRealType) i;
-        x_map[i].z=0.0f*(MagickRealType) i;
-        y_map[i].z=0.0f*(MagickRealType) i;
-        z_map[i].z=1.0f*(MagickRealType) i;
+        MagickRealType
+          v;
+
+        v=(MagickRealType) i/(MagickRealType) MaxMap;
+        if (((MagickRealType) i/(MagickRealType) MaxMap) <= 0.00313066844250063)
+          v*=12.92f;
+        else
+          v=(MagickRealType) (1.055*pow((double) i/MaxMap,1.0/2.4)-0.055);
+        x_map[i].x=1.0f*MaxMap*v;
+        y_map[i].x=0.0f*MaxMap*v;
+        z_map[i].x=0.0f*MaxMap*v;
+        x_map[i].y=0.0f*MaxMap*v;
+        y_map[i].y=1.0f*MaxMap*v;
+        z_map[i].y=0.0f*MaxMap*v;
+        x_map[i].z=0.0f*MaxMap*v;
+        y_map[i].z=0.0f*MaxMap*v;
+        z_map[i].z=1.0f*MaxMap*v;
       }
       break;
     }
@@ -2334,7 +2403,8 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
           B =  0.0556434*X-0.2040259*Y+1.057225*Z
       */
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -2362,7 +2432,8 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
         YCC is scaled by 1.3584.  C1 zero is 156 and C2 is at 137.
       */
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -2395,7 +2466,8 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
         through QuantumRange.
       */
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -2430,7 +2502,8 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
         through QuantumRange.
       */
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -2451,7 +2524,6 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
       break;
     }
     case YUVColorspace:
-    default:
     {
       /*
         Initialize YUV tables:
@@ -2464,7 +2536,8 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
         through QuantumRange.
       */
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i <= (ssize_t) MaxMap; i++)
       {
@@ -2484,6 +2557,29 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
       }
       break;
     }
+    default:
+    {
+      /*
+        Linear conversion tables.
+      */
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+      #pragma omp parallel for schedule(static) \
+        dynamic_number_threads(image->columns,1,1)
+#endif
+      for (i=0; i <= (ssize_t) MaxMap; i++)
+      {
+        x_map[i].x=(MagickRealType) i;
+        y_map[i].x=0.0f;
+        z_map[i].x=0.0f;
+        x_map[i].y=0.0f;
+        y_map[i].y=(MagickRealType) i;
+        z_map[i].y=0.0f;
+        x_map[i].z=0.0f;
+        y_map[i].z=0.0f;
+        z_map[i].z=(MagickRealType) i;
+      }
+      break;
+    }
   }
   /*
     Convert to RGB.
@@ -2496,9 +2592,10 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
       /*
         Convert DirectClass image.
       */
-      image_view=AcquireCacheView(image);
+      image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        dynamic_number_threads(image->columns,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -2550,34 +2647,30 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
 #endif
               break;
             }
-            case sRGBColorspace:
+            case RGBColorspace:
             {
-              if ((QuantumScale*pixel.red) <= 0.0031308)
+              if ((QuantumScale*pixel.red) <= 0.00313066844250063)
                 pixel.red*=12.92f;
               else
-                pixel.red=(MagickRealType) QuantumRange*(1.055*
-                  pow(QuantumScale*pixel.red,(1.0/2.4))-0.055);
-              if ((QuantumScale*pixel.green) <= 0.0031308)
+                pixel.red=(MagickRealType) QuantumRange*(1.055*pow(
+                  QuantumScale*pixel.red,(1.0/2.4))-0.055);
+              if ((QuantumScale*pixel.green) <= 0.00313066844250063)
                 pixel.green*=12.92f;
               else
-                pixel.green=(MagickRealType) QuantumRange*(1.055*
-                  pow(QuantumScale*pixel.green,(1.0/2.4))-0.055);
-              if ((QuantumScale*pixel.blue) <= 0.0031308)
+                pixel.green=(MagickRealType) QuantumRange*(1.055*pow(
+                  QuantumScale*pixel.green,(1.0/2.4))-0.055);
+              if ((QuantumScale*pixel.blue) <= 0.00313066844250063)
                 pixel.blue*=12.92f;
               else
-                pixel.blue=(MagickRealType) QuantumRange*(1.055*
-                  pow(QuantumScale*pixel.blue,(1.0/2.4))-0.055);
-              break;
+                pixel.blue=(MagickRealType) QuantumRange*(1.055*pow(
+                  QuantumScale*pixel.blue,(1.0/2.4))-0.055);
             }
             default:
               break;
           }
-          SetPixelRed(image,ScaleMapToQuantum((MagickRealType) MaxMap*
-            QuantumScale*pixel.red),q);
-          SetPixelGreen(image,ScaleMapToQuantum((MagickRealType) MaxMap*
-            QuantumScale*pixel.green),q);
-          SetPixelBlue(image,ScaleMapToQuantum((MagickRealType) MaxMap*
-            QuantumScale*pixel.blue),q);
+          SetPixelRed(image,ScaleMapToQuantum(pixel.red),q);
+          SetPixelGreen(image,ScaleMapToQuantum(pixel.green),q);
+          SetPixelBlue(image,ScaleMapToQuantum(pixel.blue),q);
           q+=GetPixelChannels(image);
         }
         sync=SyncCacheViewAuthenticPixels(image_view,exception);
@@ -2589,9 +2682,9 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
               proceed;
 
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-            #pragma omp critical (MagickCore_TransformRGBImage)
+            #pragma omp critical (MagickCore_TransformsRGBImage)
 #endif
-            proceed=SetImageProgress(image,TransformRGBImageTag,progress++,
+            proceed=SetImageProgress(image,TransformsRGBImageTag,progress++,
               image->rows);
             if (proceed == MagickFalse)
               status=MagickFalse;
@@ -2605,9 +2698,9 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
       /*
         Convert PseudoClass image.
       */
-      image_view=AcquireCacheView(image);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        dynamic_number_threads(image->columns,1,1)
 #endif
       for (i=0; i < (ssize_t) image->colors; i++)
       {
@@ -2630,46 +2723,40 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
           case YCCColorspace:
           {
 #if !defined(MAGICKCORE_HDRI_SUPPORT)
-            image->colormap[i].red=(double) (QuantumRange*YCCMap[
-              RoundToYCC(1024.0*QuantumScale*pixel.red)]);
-            image->colormap[i].green=(double) (QuantumRange*YCCMap[
-              RoundToYCC(1024.0*QuantumScale*pixel.green)]);
-            image->colormap[i].blue=(double) (QuantumRange*YCCMap[
-              RoundToYCC(1024.0*QuantumScale*pixel.blue)]);
+            pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
+              pixel.red)];
+            pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
+              pixel.green)];
+            pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
+              pixel.blue)];
 #endif
             break;
           }
-          case sRGBColorspace:
+          case RGBColorspace:
           {
-            if ((QuantumScale*pixel.red) <= 0.0031308)
+            if ((QuantumScale*pixel.red) <= 0.00313066844250063)
               pixel.red*=12.92f;
             else
-              pixel.red=(MagickRealType) QuantumRange*(1.055*pow(QuantumScale*
-                pixel.red,(1.0/2.4))-0.055);
-            if ((QuantumScale*pixel.green) <= 0.0031308)
+              pixel.red=(MagickRealType) QuantumRange*(1.055*
+                pow(QuantumScale*pixel.red,(1.0/2.4))-0.055);
+            if ((QuantumScale*pixel.green) <= 0.00313066844250063)
               pixel.green*=12.92f;
             else
-              pixel.green=(MagickRealType) QuantumRange*(1.055*pow(QuantumScale*
-                pixel.green,(1.0/2.4))-0.055);
-            if ((QuantumScale*pixel.blue) <= 0.0031308)
+              pixel.green=(MagickRealType) QuantumRange*(1.055*
+                pow(QuantumScale*pixel.green,(1.0/2.4))-0.055);
+            if ((QuantumScale*pixel.blue) <= 0.00313066844250063)
               pixel.blue*=12.92f;
             else
-              pixel.blue=(MagickRealType) QuantumRange*(1.055*pow(QuantumScale*
-                pixel.blue,(1.0/2.4))-0.055);
+              pixel.blue=(MagickRealType) QuantumRange*(1.055*
+                pow(QuantumScale*pixel.blue,(1.0/2.4))-0.055);
           }
           default:
-          {
-            image->colormap[i].red=(double) ScaleMapToQuantum((MagickRealType)
-              MaxMap*QuantumScale*pixel.red);
-            image->colormap[i].green=(double) ScaleMapToQuantum((MagickRealType)
-              MaxMap*QuantumScale*pixel.green);
-            image->colormap[i].blue=(double) ScaleMapToQuantum((MagickRealType)
-              MaxMap*QuantumScale*pixel.blue);
             break;
-          }
         }
+        image->colormap[i].red=(double) ScaleMapToQuantum(pixel.red);
+        image->colormap[i].green=(double) ScaleMapToQuantum(pixel.green);
+        image->colormap[i].blue=(double) ScaleMapToQuantum(pixel.blue);
       }
-      image_view=DestroyCacheView(image_view);
       (void) SyncImage(image,exception);
       break;
     }
@@ -2680,7 +2767,7 @@ MagickExport MagickBooleanType TransformRGBImage(Image *image,
   z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
   y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
   x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
-  if (SetImageColorspace(image,RGBColorspace,exception) == MagickFalse)
+  if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
     return(MagickFalse);
   return(MagickTrue);
 }