]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/attribute.c
(no commit message)
[imagemagick] / MagickCore / attribute.c
index d6b36bd9129a0f577f1ec847825b807eae457536..ec953ec4e2ea01dfc1b1174b70843c5c9bb24f25 100644 (file)
 %                    MagickCore Get / Set Image Attributes                    %
 %                                                                             %
 %                              Software Design                                %
-%                                John Cristy                                  %
+%                                   Cristy                                    %
 %                                October 2002                                 %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2012 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  %
@@ -46,7 +46,9 @@
 #include "MagickCore/blob.h"
 #include "MagickCore/blob-private.h"
 #include "MagickCore/cache.h"
+#include "MagickCore/cache-private.h"
 #include "MagickCore/cache-view.h"
+#include "MagickCore/channel.h"
 #include "MagickCore/client.h"
 #include "MagickCore/color.h"
 #include "MagickCore/color-private.h"
@@ -171,7 +173,7 @@ MagickExport RectangleInfo GetImageBoundingBox(const Image *image,
   GetPixelInfo(image,&zero);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static,4) shared(status) \
-    dynamic_number_threads(image,image->columns,image->rows,1)
+    magick_threads(image,image,image->rows,1)
 #endif
   for (y=0; y < (ssize_t) image->rows; y++)
   {
@@ -234,7 +236,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);
@@ -276,7 +278,7 @@ MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
     status;
 
   register ssize_t
-    id;
+    i;
 
   size_t
     *current_depth,
@@ -299,13 +301,10 @@ MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
   if (current_depth == (size_t *) NULL)
     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
   status=MagickTrue;
-  for (id=0; id < (ssize_t) number_threads; id++)
-    current_depth[id]=1;
+  for (i=0; i < (ssize_t) number_threads; i++)
+    current_depth[i]=1;
   if ((image->storage_class == PseudoClass) && (image->alpha_trait != BlendPixelTrait))
     {
-      register ssize_t
-        i;
-
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
       #pragma omp parallel for schedule(static,4) shared(status) \
         if ((image->colors) > 256) \
@@ -316,39 +315,37 @@ MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
         const int
           id = GetOpenMPThreadId();
 
-        if (status == MagickFalse)
-          continue;
         while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
         {
-          MagickStatusType
-            status;
+          MagickBooleanType
+            atDepth;
 
           QuantumAny
             range;
 
-          status=0;
+          atDepth=MagickTrue;
           range=GetQuantumRange(current_depth[id]);
-          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)
+          if ((atDepth != MagickFalse) &&
+              (GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
+            if (IsPixelAtDepth(image->colormap[i].red,range) == MagickFalse)
+              atDepth=MagickFalse;
+          if ((atDepth != MagickFalse) &&
+              (GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
+            if (IsPixelAtDepth(image->colormap[i].green,range) == MagickFalse)
+              atDepth=MagickFalse;
+          if ((atDepth != MagickFalse) &&
+              (GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
+            if (IsPixelAtDepth(image->colormap[i].blue,range) == MagickFalse)
+              atDepth=MagickFalse;
+          if ((atDepth != MagickFalse))
             break;
           current_depth[id]++;
         }
       }
       depth=current_depth[0];
-      for (id=1; id < (ssize_t) number_threads; id++)
-        if (depth < current_depth[id])
-          depth=current_depth[id];
+      for (i=1; i < (ssize_t) number_threads; i++)
+        if (depth < current_depth[i])
+          depth=current_depth[i];
       current_depth=(size_t *) RelinquishMagickMemory(current_depth);
       return(depth);
     }
@@ -356,9 +353,6 @@ MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
 #if !defined(MAGICKCORE_HDRI_SUPPORT)
   if (QuantumRange <= MaxMap)
     {
-      register ssize_t
-        i;
-
       size_t
         *depth_map;
 
@@ -390,7 +384,7 @@ MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
       }
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
       #pragma omp parallel for schedule(static,4) shared(status) \
-        dynamic_number_threads(image,image->columns,image->rows,1)
+        magick_threads(image,image,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -410,26 +404,19 @@ MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
           continue;
         for (x=0; x < (ssize_t) image->columns; x++)
         {
-          register ssize_t
-            i;
-
-          if (GetPixelMask(image,p) != 0)
+          if (GetPixelReadMask(image,p) == 0)
             {
               p+=GetPixelChannels(image);
               continue;
             }
           for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
           {
-            PixelChannel
-              channel;
-
-            PixelTrait
-              traits;
-
-            channel=GetPixelChannelChannel(image,i);
-            traits=GetPixelChannelTraits(image,channel);
+            PixelChannel channel=GetPixelChannelChannel(image,i);
+            PixelTrait traits=GetPixelChannelTraits(image,channel);
             if ((traits == UndefinedPixelTrait) ||
-                (channel == IndexPixelChannel) || (channel == MaskPixelChannel))
+                (channel == IndexPixelChannel) ||
+                (channel == ReadMaskPixelChannel) ||
+                (channel == MetaPixelChannel))
               continue;
             if (depth_map[ScaleQuantumToMap(p[i])] > current_depth[id])
               current_depth[id]=depth_map[ScaleQuantumToMap(p[i])];
@@ -441,9 +428,9 @@ MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
       }
       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];
+      for (i=1; i < (ssize_t) number_threads; i++)
+        if (depth < current_depth[i])
+          depth=current_depth[i];
       depth_map=(size_t *) RelinquishMagickMemory(depth_map);
       current_depth=(size_t *) RelinquishMagickMemory(current_depth);
       return(depth);
@@ -454,7 +441,7 @@ MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
   */
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static,4) shared(status) \
-    dynamic_number_threads(image,image->columns,image->rows,1)
+    magick_threads(image,image,image->rows,1)
 #endif
   for (y=0; y < (ssize_t) image->rows; y++)
   {
@@ -474,10 +461,7 @@ MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
       continue;
     for (x=0; x < (ssize_t) image->columns; x++)
     {
-      register ssize_t
-        i;
-
-      if (GetPixelMask(image,p) != 0)
+      if (GetPixelReadMask(image,p) == 0)
         {
           p+=GetPixelChannels(image);
           continue;
@@ -493,7 +477,7 @@ MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
         channel=GetPixelChannelChannel(image,i);
         traits=GetPixelChannelTraits(image,channel);
         if ((traits == UndefinedPixelTrait) || (channel == IndexPixelChannel) ||
-            (channel == MaskPixelChannel))
+            (channel == ReadMaskPixelChannel))
           continue;
         while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
         {
@@ -513,9 +497,9 @@ MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
   }
   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];
+  for (i=1; i < (ssize_t) number_threads; i++)
+    if (depth < current_depth[i])
+      depth=current_depth[i];
   current_depth=(size_t *) RelinquishMagickMemory(current_depth);
   return(depth);
 }
@@ -693,7 +677,7 @@ MagickExport MagickBooleanType IsImageGray(const Image *image,
       (image->type == GrayscaleMatteType))
     return(MagickTrue);
   if ((IsGrayColorspace(image->colorspace) == MagickFalse) &&
-      (IsRGBColorspace(image->colorspace) == MagickFalse))
+      (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse))
     return(MagickFalse);
   type=BilevelType;
   image_view=AcquireVirtualCacheView(image,exception);
@@ -720,6 +704,9 @@ MagickExport MagickBooleanType IsImageGray(const Image *image,
   image_view=DestroyCacheView(image_view);
   if (type == UndefinedType)
     return(MagickFalse);
+  ((Image *) image)->colorspace=GRAYColorspace;
+  if (SyncImagePixelCache((Image *) image,exception) == MagickFalse)
+    return(MagickFalse);
   ((Image *) image)->type=type;
   if ((type == GrayscaleType) && (image->alpha_trait == BlendPixelTrait))
     ((Image *) image)->type=GrayscaleMatteType;
@@ -778,7 +765,7 @@ MagickExport MagickBooleanType IsImageMonochrome(const Image *image,
   if (image->type == BilevelType)
     return(MagickTrue);
   if ((IsGrayColorspace(image->colorspace) == MagickFalse) &&
-      (IsRGBColorspace(image->colorspace) == MagickFalse))
+      (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse))
     return(MagickFalse);
   type=BilevelType;
   image_view=AcquireVirtualCacheView(image,exception);
@@ -802,6 +789,9 @@ MagickExport MagickBooleanType IsImageMonochrome(const Image *image,
   image_view=DestroyCacheView(image_view);
   if (type == UndefinedType)
     return(MagickFalse);
+  ((Image *) image)->colorspace=GRAYColorspace;
+  if (SyncImagePixelCache((Image *) image,exception) == MagickFalse)
+    return(MagickFalse);
   ((Image *) image)->type=type;
   return(MagickTrue);
 }
@@ -906,6 +896,20 @@ MagickExport MagickBooleanType IsImageOpaque(const Image *image,
 %    o exception: return any errors or warnings in this structure.
 %
 */
+
+static inline Quantum ClampPixel(const MagickRealType value)
+{
+#if !defined(MAGICKCORE_HDRI_SUPPORT)
+  return((Quantum) value);
+#else
+  if (value < 0.0f)
+    return(0.0f);
+  if (value >= (MagickRealType) QuantumRange)
+    return((Quantum) QuantumRange);
+  return(value);
+#endif
+}
+
 MagickExport MagickBooleanType SetImageDepth(Image *image,
   const size_t depth,ExceptionInfo *exception)
 {
@@ -938,22 +942,22 @@ MagickExport MagickBooleanType SetImageDepth(Image *image,
 
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
       #pragma omp parallel for schedule(static,4) shared(status) \
-        dynamic_number_threads(image,image->columns,1,1)
+        magick_threads(image,image,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);
+            ClampPixel(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);
+            ClampPixel(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);
+            ClampPixel(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);
+            ClampPixel(image->colormap[i].alpha),range),range);
       }
     }
   status=MagickTrue;
@@ -978,7 +982,7 @@ MagickExport MagickBooleanType SetImageDepth(Image *image,
           range);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
       #pragma omp parallel for schedule(static,4) shared(status) \
-        dynamic_number_threads(image,image->columns,image->rows,1)
+        magick_threads(image,image,image->rows,1)
 #endif
       for (y=0; y < (ssize_t) image->rows; y++)
       {
@@ -1002,7 +1006,7 @@ MagickExport MagickBooleanType SetImageDepth(Image *image,
           register ssize_t
             i;
 
-          if (GetPixelMask(image,q) != 0)
+          if (GetPixelReadMask(image,q) == 0)
             {
               q+=GetPixelChannels(image);
               continue;
@@ -1018,7 +1022,8 @@ MagickExport MagickBooleanType SetImageDepth(Image *image,
             channel=GetPixelChannelChannel(image,i);
             traits=GetPixelChannelTraits(image,channel);
             if ((traits == UndefinedPixelTrait) ||
-                (channel == IndexPixelChannel) || (channel == MaskPixelChannel))
+                (channel == IndexPixelChannel) ||
+                (channel == ReadMaskPixelChannel))
               continue;
             q[i]=depth_map[ScaleQuantumToMap(q[i])];
           }
@@ -1042,7 +1047,7 @@ MagickExport MagickBooleanType SetImageDepth(Image *image,
   */
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static,4) shared(status) \
-    dynamic_number_threads(image,image->columns,image->rows,1)
+    magick_threads(image,image,image->rows,1)
 #endif
   for (y=0; y < (ssize_t) image->rows; y++)
   {
@@ -1065,7 +1070,7 @@ MagickExport MagickBooleanType SetImageDepth(Image *image,
       register ssize_t
         i;
 
-      if (GetPixelMask(image,q) != 0)
+      if (GetPixelReadMask(image,q) == 0)
         {
           q+=GetPixelChannels(image);
           continue;
@@ -1081,9 +1086,9 @@ MagickExport MagickBooleanType SetImageDepth(Image *image,
         channel=GetPixelChannelChannel(image,i);
         traits=GetPixelChannelTraits(image,channel);
         if ((traits == UndefinedPixelTrait) || (channel == IndexPixelChannel) ||
-            (channel == MaskPixelChannel))
+            (channel == ReadMaskPixelChannel))
           continue;
-        q[i]=ScaleAnyToQuantum(ScaleQuantumToAny(q[i],range),range);
+        q[i]=ScaleAnyToQuantum(ScaleQuantumToAny(ClampPixel(q[i]),range),range);
       }
       q+=GetPixelChannels(image);
     }
@@ -1160,6 +1165,9 @@ MagickExport MagickBooleanType SetImageType(Image *image,const ImageType type,
   {
     case BilevelType:
     {
+      if (IsImageGray(image,exception) == MagickFalse)
+        status=TransformImageColorspace(image,GRAYColorspace,exception);
+      (void) NormalizeImage(image,exception);
       if (IsImageMonochrome(image,exception) == MagickFalse)
         {
           quantize_info=AcquireQuantizeInfo(image_info);
@@ -1279,7 +1287,9 @@ MagickExport MagickBooleanType SetImageType(Image *image,const ImageType type,
     case UndefinedType:
       break;
   }
-  image->type=type;
   image_info=DestroyImageInfo(image_info);
-  return(status);
+  if (status == MagickFalse)
+    return(status);
+  image->type=type;
+  return(MagickTrue);
 }