]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/attribute.c
(no commit message)
[imagemagick] / MagickCore / attribute.c
index 482c284b2c55fbc5e6666ed111f8d88b19448345..227645bb40586660d5ddfb9ad2ba7c61cccd2324 100644 (file)
@@ -17,7 +17,7 @@
 %                                October 2002                                 %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2012 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  %
@@ -52,6 +52,7 @@
 #include "MagickCore/colormap.h"
 #include "MagickCore/colormap-private.h"
 #include "MagickCore/colorspace.h"
+#include "MagickCore/colorspace-private.h"
 #include "MagickCore/composite.h"
 #include "MagickCore/composite-private.h"
 #include "MagickCore/constitute.h"
@@ -148,26 +149,27 @@ MagickExport RectangleInfo GetImageBoundingBox(const Image *image,
   bounds.x=(ssize_t) image->columns;
   bounds.y=(ssize_t) image->rows;
   GetPixelInfo(image,&target[0]);
-  image_view=AcquireCacheView(image);
+  image_view=AcquireVirtualCacheView(image,exception);
   p=GetCacheViewVirtualPixels(image_view,0,0,1,1,exception);
   if (p == (const Quantum *) NULL)
     {
       image_view=DestroyCacheView(image_view);
       return(bounds);
     }
-  SetPixelInfo(image,p,&target[0]);
+  GetPixelInfoPixel(image,p,&target[0]);
   GetPixelInfo(image,&target[1]);
   p=GetCacheViewVirtualPixels(image_view,(ssize_t) image->columns-1,0,1,1,
     exception);
-  SetPixelInfo(image,p,&target[1]);
+  GetPixelInfoPixel(image,p,&target[1]);
   GetPixelInfo(image,&target[2]);
   p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) image->rows-1,1,1,
     exception);
-  SetPixelInfo(image,p,&target[2]);
+  GetPixelInfoPixel(image,p,&target[2]);
   status=MagickTrue;
   GetPixelInfo(image,&zero);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-  #pragma omp parallel for schedule(dynamic,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++)
   {
@@ -198,7 +200,7 @@ MagickExport RectangleInfo GetImageBoundingBox(const Image *image,
     pixel=zero;
     for (x=0; x < (ssize_t) image->columns; x++)
     {
-      SetPixelInfo(image,p,&pixel);
+      GetPixelInfoPixel(image,p,&pixel);
       if ((x < bounding_box.x) &&
           (IsFuzzyEquivalencePixelInfo(&pixel,&target[0]) == MagickFalse))
         bounding_box.x=x;
@@ -211,7 +213,7 @@ MagickExport RectangleInfo GetImageBoundingBox(const Image *image,
       if ((y > (ssize_t) bounding_box.height) &&
           (IsFuzzyEquivalencePixelInfo(&pixel,&target[2]) == MagickFalse))
         bounding_box.height=(size_t) y;
-      p+=GetPixelComponents(image);
+      p+=GetPixelChannels(image);
     }
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
 #  pragma omp critical (MagickCore_GetImageBoundingBox)
@@ -230,7 +232,7 @@ MagickExport RectangleInfo GetImageBoundingBox(const Image *image,
   image_view=DestroyCacheView(image_view);
   if ((bounds.width == 0) || (bounds.height == 0))
     (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
-      "GeometryDoesNotContainImage","`%s'",image->filename);
+      "GeometryDoesNotContainImage","'%s'",image->filename);
   else
     {
       bounds.width-=(bounds.x-1);
@@ -263,8 +265,7 @@ MagickExport RectangleInfo GetImageBoundingBox(const Image *image,
 %    o exception: return any errors or warnings in this structure.
 %
 */
-MagickExport size_t GetImageDepth(const Image *image,
-  ExceptionInfo *exception)
+MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
 {
   CacheView
     *image_view;
@@ -300,15 +301,13 @@ MagickExport size_t GetImageDepth(const Image *image,
     current_depth[id]=1;
   if ((image->storage_class == PseudoClass) && (image->matte == MagickFalse))
     {
-      register const PixelPacket
-        *restrict p;
-
       register ssize_t
         i;
 
-      p=image->colormap;
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-  #pragma omp parallel for schedule(dynamic,4) shared(status)
+      #pragma omp parallel for schedule(static) shared(status) \
+        if ((image->colors) > 256) \
+          num_threads(GetMagickResourceLimit(ThreadResource))
 #endif
       for (i=0; i < (ssize_t) image->colors; i++)
       {
@@ -327,20 +326,22 @@ MagickExport size_t GetImageDepth(const Image *image,
 
           status=0;
           range=GetQuantumRange(current_depth[id]);
-          if ((GetPixelRedTraits(image) & ActivePixelTrait) != 0)
-            status|=p->red != ScaleAnyToQuantum(ScaleQuantumToAny(p->red,
-              range),range);
-          if ((GetPixelGreenTraits(image) & ActivePixelTrait) != 0)
-            status|=p->green != ScaleAnyToQuantum(ScaleQuantumToAny(p->green,
-              range),range);
-          if ((GetPixelBlueTraits(image) & ActivePixelTrait) != 0)
-            status|=p->blue != ScaleAnyToQuantum(ScaleQuantumToAny(p->blue,
-              range),range);
+          if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
+            status|=ClampToQuantum(image->colormap[i].red) !=
+              ScaleAnyToQuantum(ScaleQuantumToAny(ClampToQuantum(
+              image->colormap[i].red),range),range);
+          if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
+            status|=ClampToQuantum(image->colormap[i].green) !=
+              ScaleAnyToQuantum(ScaleQuantumToAny(ClampToQuantum(
+              image->colormap[i].green),range),range);
+          if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
+            status|=ClampToQuantum(image->colormap[i].blue) !=
+              ScaleAnyToQuantum(ScaleQuantumToAny(ClampToQuantum(
+              image->colormap[i].blue),range),range);
           if (status == 0)
             break;
           current_depth[id]++;
         }
-        p++;
       }
       depth=current_depth[0];
       for (id=1; id < (ssize_t) number_threads; id++)
@@ -349,9 +350,109 @@ MagickExport size_t GetImageDepth(const Image *image,
       current_depth=(size_t *) RelinquishMagickMemory(current_depth);
       return(depth);
     }
-  image_view=AcquireCacheView(image);
+  image_view=AcquireVirtualCacheView(image,exception);
+#if !defined(MAGICKCORE_HDRI_SUPPORT)
+  if (QuantumRange <= MaxMap)
+    {
+      register ssize_t
+        i;
+
+      size_t
+        *depth_map;
+
+      /*
+        Scale pixels to desired (optimized with depth map).
+      */
+      depth_map=(size_t *) AcquireQuantumMemory(MaxMap+1,sizeof(*depth_map));
+      if (depth_map == (size_t *) NULL)
+        ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
+      for (i=0; i <= (ssize_t) MaxMap; i++)
+      {
+        unsigned int
+          depth;
+
+        for (depth=1; depth < MAGICKCORE_QUANTUM_DEPTH; depth++)
+        {
+          Quantum
+            pixel;
+
+          QuantumAny
+            range;
+
+          range=GetQuantumRange(depth);
+          pixel=(Quantum) i;
+          if (pixel == ScaleAnyToQuantum(ScaleQuantumToAny(pixel,range),range))
+            break;
+        }
+        depth_map[i]=depth;
+      }
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+      #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++)
+      {
+        const int
+          id = GetOpenMPThreadId();
+
+        register const Quantum
+          *restrict p;
+
+        register ssize_t
+          x;
+
+        if (status == MagickFalse)
+          continue;
+        p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
+        if (p == (const Quantum *) NULL)
+          continue;
+        for (x=0; x < (ssize_t) image->columns; x++)
+        {
+          register ssize_t
+            i;
+
+          if (GetPixelMask(image,p) != 0)
+            {
+              p+=GetPixelChannels(image);
+              continue;
+            }
+          for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+          {
+            PixelChannel
+              channel;
+
+            PixelTrait
+              traits;
+
+            channel=GetPixelChannelMapChannel(image,i);
+            traits=GetPixelChannelMapTraits(image,channel);
+            if ((traits == UndefinedPixelTrait) ||
+                (channel == IndexPixelChannel) || (channel == MaskPixelChannel))
+              continue;
+            if (depth_map[ScaleQuantumToMap(p[i])] > current_depth[id])
+              current_depth[id]=depth_map[ScaleQuantumToMap(p[i])];
+          }
+          p+=GetPixelChannels(image);
+        }
+        if (current_depth[id] == MAGICKCORE_QUANTUM_DEPTH)
+          status=MagickFalse;
+      }
+      image_view=DestroyCacheView(image_view);
+      depth=current_depth[0];
+      for (id=1; id < (ssize_t) number_threads; id++)
+        if (depth < current_depth[id])
+          depth=current_depth[id];
+      depth_map=(size_t *) RelinquishMagickMemory(depth_map);
+      current_depth=(size_t *) RelinquishMagickMemory(current_depth);
+      return(depth);
+    }
+#endif
+  /*
+    Compute pixel depth.
+  */
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-  #pragma omp parallel for schedule(dynamic,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++)
   {
@@ -371,38 +472,39 @@ MagickExport size_t GetImageDepth(const Image *image,
       continue;
     for (x=0; x < (ssize_t) image->columns; x++)
     {
-      while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
+      register ssize_t
+        i;
+
+      if (GetPixelMask(image,p) != 0)
+        {
+          p+=GetPixelChannels(image);
+          continue;
+        }
+      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
       {
-        MagickStatusType
-          status;
-
-        QuantumAny
-          range;
-
-        status=0;
-        range=GetQuantumRange(current_depth[id]);
-        if ((GetPixelRedTraits(image) & ActivePixelTrait) != 0)
-          status|=GetPixelRed(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
-            GetPixelRed(image,p),range),range);
-        if ((GetPixelGreenTraits(image) & ActivePixelTrait) != 0)
-          status|=GetPixelGreen(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
-            GetPixelGreen(image,p),range),range);
-        if ((GetPixelBlueTraits(image) & ActivePixelTrait) != 0)
-          status|=GetPixelBlue(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
-            GetPixelBlue(image,p),range),range);
-        if (((GetPixelAlphaTraits(image) & ActivePixelTrait) != 0) &&
-            (image->matte != MagickFalse))
-          status|=GetPixelAlpha(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
-            GetPixelAlpha(image,p),range),range);
-        if (((GetPixelBlackTraits(image) & ActivePixelTrait) != 0) &&
-            (image->colorspace == CMYKColorspace))
-          status|=GetPixelBlack(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
-            GetPixelBlack(image,p),range),range);
-        if (status == 0)
-          break;
-        current_depth[id]++;
+        PixelChannel
+          channel;
+
+        PixelTrait
+          traits;
+
+        channel=GetPixelChannelMapChannel(image,i);
+        traits=GetPixelChannelMapTraits(image,channel);
+        if ((traits == UndefinedPixelTrait) || (channel == IndexPixelChannel) ||
+            (channel == MaskPixelChannel))
+          continue;
+        while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
+        {
+          QuantumAny
+            range;
+
+          range=GetQuantumRange(current_depth[id]);
+          if (p[i] == ScaleAnyToQuantum(ScaleQuantumToAny(p[i],range),range))
+            break;
+          current_depth[id]++;
+        }
       }
-      p+=GetPixelComponents(image);
+      p+=GetPixelChannels(image);
     }
     if (current_depth[id] == MAGICKCORE_QUANTUM_DEPTH)
       status=MagickFalse;
@@ -470,8 +572,7 @@ MagickExport size_t GetImageQuantumDepth(const Image *image,
         if (depth <= 64)
           depth=64;
   if (constrain != MagickFalse)
-    depth=(size_t) MagickMin((double) depth,(double)
-      MAGICKCORE_QUANTUM_DEPTH);
+    depth=(size_t) MagickMin((double) depth,(double) MAGICKCORE_QUANTUM_DEPTH);
   return(depth);
 }
 \f
@@ -589,10 +690,10 @@ MagickExport MagickBooleanType IsImageGray(const Image *image,
   if ((image->type == BilevelType) || (image->type == GrayscaleType) ||
       (image->type == GrayscaleMatteType))
     return(MagickTrue);
-  if (image->colorspace == CMYKColorspace)
+  if (IssRGBColorspace(image->colorspace) == MagickFalse)
     return(MagickFalse);
   type=BilevelType;
-  image_view=AcquireCacheView(image);
+  image_view=AcquireVirtualCacheView(image,exception);
   for (y=0; y < (ssize_t) image->rows; y++)
   {
     p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
@@ -608,7 +709,7 @@ MagickExport MagickBooleanType IsImageGray(const Image *image,
       if ((type == BilevelType) &&
           (IsPixelMonochrome(image,p) == MagickFalse))
         type=GrayscaleType;
-      p+=GetPixelComponents(image);
+      p+=GetPixelChannels(image);
     }
     if (type == UndefinedType)
       break;
@@ -673,10 +774,10 @@ MagickExport MagickBooleanType IsImageMonochrome(const Image *image,
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   if (image->type == BilevelType)
     return(MagickTrue);
-  if (image->colorspace == CMYKColorspace)
+  if (IssRGBColorspace(image->colorspace) == MagickFalse)
     return(MagickFalse);
   type=BilevelType;
-  image_view=AcquireCacheView(image);
+  image_view=AcquireVirtualCacheView(image,exception);
   for (y=0; y < (ssize_t) image->rows; y++)
   {
     p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
@@ -689,7 +790,7 @@ MagickExport MagickBooleanType IsImageMonochrome(const Image *image,
           type=UndefinedType;
           break;
         }
-      p+=GetPixelComponents(image);
+      p+=GetPixelChannels(image);
     }
     if (type == UndefinedType)
       break;
@@ -713,7 +814,9 @@ MagickExport MagickBooleanType IsImageMonochrome(const Image *image,
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 %  IsImageOpaque() returns MagickTrue if none of the pixels in the image have
-%  an opacity value other than opaque (0).
+%  an alpha value other than OpaqueAlpha (QuantumRange).
+%
+%  Will return true immediatally is alpha channel is not available.
 %
 %  The format of the IsImageOpaque method is:
 %
@@ -749,9 +852,11 @@ MagickExport MagickBooleanType IsImageOpaque(const Image *image,
   assert(image->signature == MagickSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
+
   if (image->matte == MagickFalse)
     return(MagickTrue);
-  image_view=AcquireCacheView(image);
+
+  image_view=AcquireVirtualCacheView(image,exception);
   for (y=0; y < (ssize_t) image->rows; y++)
   {
     p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
@@ -761,7 +866,7 @@ MagickExport MagickBooleanType IsImageOpaque(const Image *image,
     {
       if (GetPixelAlpha(image,p) != OpaqueAlpha)
         break;
-      p+=GetPixelComponents(image);
+      p+=GetPixelChannels(image);
     }
     if (x < (ssize_t) image->columns)
      break;
@@ -785,9 +890,8 @@ MagickExport MagickBooleanType IsImageOpaque(const Image *image,
 %
 %  The format of the SetImageDepth method is:
 %
-%      MagickBooleanType SetImageDepth(Image *image,const size_t depth)
-%      MagickBooleanType SetImageDepth(Image *image,
-%        const ChannelType channel,const size_t depth)
+%      MagickBooleanType SetImageDepth(Image *image,const size_t depth,
+%        ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
@@ -797,16 +901,15 @@ MagickExport MagickBooleanType IsImageOpaque(const Image *image,
 %
 %    o depth: the image depth.
 %
+%    o exception: return any errors or warnings in this structure.
+%
 */
 MagickExport MagickBooleanType SetImageDepth(Image *image,
-  const size_t depth)
+  const size_t depth,ExceptionInfo *exception)
 {
   CacheView
     *image_view;
 
-  ExceptionInfo
-    *exception;
-
   MagickBooleanType
     status;
 
@@ -820,21 +923,128 @@ MagickExport MagickBooleanType SetImageDepth(Image *image,
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   assert(image->signature == MagickSignature);
-  if (GetImageDepth(image,&image->exception) <= (size_t)
-      MagickMin((double) depth,(double) MAGICKCORE_QUANTUM_DEPTH))
+  if (depth >= MAGICKCORE_QUANTUM_DEPTH)
     {
-      image->depth=depth;
+      image->depth=MAGICKCORE_QUANTUM_DEPTH;
       return(MagickTrue);
     }
+  range=GetQuantumRange(depth);
+  if (image->storage_class == PseudoClass)
+    {
+      register ssize_t
+        i;
+
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+      #pragma omp parallel for schedule(static) shared(status) \
+        dynamic_number_threads(image->columns,1,1)
+#endif
+      for (i=0; i < (ssize_t) image->colors; i++)
+      {
+        if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
+          image->colormap[i].red=(double) ScaleAnyToQuantum(ScaleQuantumToAny(
+            ClampToQuantum(image->colormap[i].red),range),range);
+        if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
+          image->colormap[i].green=(double) ScaleAnyToQuantum(ScaleQuantumToAny(
+            ClampToQuantum(image->colormap[i].green),range),range);
+        if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
+          image->colormap[i].blue=(double) ScaleAnyToQuantum(ScaleQuantumToAny(
+            ClampToQuantum(image->colormap[i].blue),range),range);
+        if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
+          image->colormap[i].alpha=(double) ScaleAnyToQuantum(ScaleQuantumToAny(
+            ClampToQuantum(image->colormap[i].alpha),range),range);
+      }
+      status=SyncImage(image,exception);
+      if (status != MagickFalse)
+        image->depth=depth;
+      return(status);
+    }
+  status=MagickTrue;
+  image_view=AcquireAuthenticCacheView(image,exception);
+#if !defined(MAGICKCORE_HDRI_SUPPORT)
+  if (QuantumRange <= MaxMap)
+    {
+      Quantum
+        *depth_map;
+
+      register ssize_t
+        i;
+
+      /*
+        Scale pixels to desired (optimized with depth map).
+      */
+      depth_map=(Quantum *) AcquireQuantumMemory(MaxMap+1,sizeof(*depth_map));
+      if (depth_map == (Quantum *) NULL)
+        ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
+      for (i=0; i <= (ssize_t) MaxMap; i++)
+        depth_map[i]=ScaleAnyToQuantum(ScaleQuantumToAny((Quantum) i,range),
+          range);
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+      #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++)
+      {
+        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++)
+        {
+          register ssize_t
+            i;
+
+          if (GetPixelMask(image,q) != 0)
+            {
+              q+=GetPixelChannels(image);
+              continue;
+            }
+          for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+          {
+            PixelChannel
+              channel;
+
+            PixelTrait
+              traits;
+
+            channel=GetPixelChannelMapChannel(image,i);
+            traits=GetPixelChannelMapTraits(image,channel);
+            if ((traits == UndefinedPixelTrait) ||
+                (channel == IndexPixelChannel) || (channel == MaskPixelChannel))
+              continue;
+            q[i]=depth_map[ScaleQuantumToMap(q[i])];
+          }
+          q+=GetPixelChannels(image);
+        }
+        if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
+          {
+            status=MagickFalse;
+            continue;
+          }
+      }
+      image_view=DestroyCacheView(image_view);
+      depth_map=(Quantum *) RelinquishMagickMemory(depth_map);
+      if (status != MagickFalse)
+        image->depth=depth;
+      return(status);
+    }
+#endif
   /*
     Scale pixels to desired depth.
   */
-  status=MagickTrue;
-  range=GetQuantumRange(depth);
-  exception=(&image->exception);
-  image_view=AcquireCacheView(image);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-  #pragma omp parallel for schedule(dynamic,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++)
   {
@@ -846,33 +1056,38 @@ MagickExport MagickBooleanType SetImageDepth(Image *image,
 
     if (status == MagickFalse)
       continue;
-    q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
-      exception);
-    if (q == (const Quantum *) NULL)
+    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++)
     {
-      if ((GetPixelRedTraits(image) & ActivePixelTrait) != 0)
-        SetPixelRed(image,ScaleAnyToQuantum(ScaleQuantumToAny(
-          GetPixelRed(image,q),range),range),q);
-      if ((GetPixelGreenTraits(image) & ActivePixelTrait) != 0)
-        SetPixelGreen(image,ScaleAnyToQuantum(ScaleQuantumToAny(
-          GetPixelGreen(image,q),range),range),q);
-      if ((GetPixelBlueTraits(image) & ActivePixelTrait) != 0)
-        SetPixelBlue(image,ScaleAnyToQuantum(ScaleQuantumToAny(
-          GetPixelBlue(image,q),range),range),q);
-      if (((GetPixelBlackTraits(image) & ActivePixelTrait) != 0) &&
-          (image->colorspace == CMYKColorspace))
-        SetPixelBlack(image,ScaleAnyToQuantum(ScaleQuantumToAny(
-          GetPixelBlack(image,q),range),range),q);
-      if (((GetPixelAlphaTraits(image) & ActivePixelTrait) != 0) &&
-          (image->matte != MagickFalse))
-        SetPixelAlpha(image,ScaleAnyToQuantum(ScaleQuantumToAny(
-          GetPixelAlpha(image,q),range),range),q);
-      q+=GetPixelComponents(image);
+      register ssize_t
+        i;
+
+      if (GetPixelMask(image,q) != 0)
+        {
+          q+=GetPixelChannels(image);
+          continue;
+        }
+      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+      {
+        PixelChannel
+          channel;
+
+        PixelTrait
+          traits;
+
+        channel=GetPixelChannelMapChannel(image,i);
+        traits=GetPixelChannelMapTraits(image,channel);
+        if ((traits == UndefinedPixelTrait) || (channel == IndexPixelChannel) ||
+            (channel == MaskPixelChannel))
+          continue;
+        q[i]=ScaleAnyToQuantum(ScaleQuantumToAny(q[i],range),range);
+      }
+      q+=GetPixelChannels(image);
     }
     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
       {
@@ -881,31 +1096,7 @@ MagickExport MagickBooleanType SetImageDepth(Image *image,
       }
   }
   image_view=DestroyCacheView(image_view);
-  if (image->storage_class == PseudoClass)
-    {
-      register ssize_t
-        i;
-
-      register PixelPacket
-        *restrict p;
-
-      p=image->colormap;
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
-  #pragma omp parallel for schedule(dynamic,4) shared(status)
-#endif
-      for (i=0; i < (ssize_t) image->colors; i++)
-      {
-        if ((GetPixelRedTraits(image) & ActivePixelTrait) != 0)
-          p->red=ScaleAnyToQuantum(ScaleQuantumToAny(p->red,range),range);
-        if ((GetPixelGreenTraits(image) & ActivePixelTrait) != 0)
-          p->green=ScaleAnyToQuantum(ScaleQuantumToAny(p->green,range),range);
-        if ((GetPixelBlueTraits(image) & ActivePixelTrait) != 0)
-          p->blue=ScaleAnyToQuantum(ScaleQuantumToAny(p->blue,range),range);
-        if ((GetPixelAlphaTraits(image) & ActivePixelTrait) != 0)
-          p->alpha=ScaleAnyToQuantum(ScaleQuantumToAny(p->alpha,range),range);
-        p++;
-      }
-    }
-  image->depth=depth;
+  if (status != MagickFalse)
+    image->depth=depth;
   return(status);
 }