]> granicus.if.org Git - imagemagick/commitdiff
Fix Schrödinger's cat problem with clip / composite mask
authorCristy <urban-warrior@imagemagick.org>
Fri, 18 May 2018 00:38:41 +0000 (20:38 -0400)
committerCristy <urban-warrior@imagemagick.org>
Fri, 18 May 2018 00:38:41 +0000 (20:38 -0400)
o Please enter the commit message for your changes. Lines starting

MagickCore/attribute.c
MagickCore/cache.c
MagickCore/channel.c
MagickCore/image.c
MagickCore/image.h
MagickCore/pixel.c

index 432df00956fc33432c895028a2368418cc28b68d..32ddfa062483fc1b90b1d38026336f672c8f6453 100644 (file)
@@ -409,10 +409,7 @@ MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
           {
             PixelChannel channel = GetPixelChannelChannel(image,i);
             PixelTrait traits = GetPixelChannelTraits(image,channel);
-            if ((traits == UndefinedPixelTrait) ||
-                (channel == IndexPixelChannel) ||
-                (channel == ReadMaskPixelChannel) ||
-                (channel == MetaPixelChannel))
+            if ((traits & UpdatePixelTrait) == 0)
               continue;
             if (depth_map[ScaleQuantumToMap(p[i])] > current_depth[id])
               current_depth[id]=depth_map[ScaleQuantumToMap(p[i])];
@@ -470,8 +467,7 @@ MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
 
         channel=GetPixelChannelChannel(image,i);
         traits=GetPixelChannelTraits(image,channel);
-        if ((traits == UndefinedPixelTrait) || (channel == IndexPixelChannel) ||
-            (channel == ReadMaskPixelChannel))
+        if ((traits & UpdatePixelTrait) == 0)
           continue;
         while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
         {
@@ -1094,9 +1090,7 @@ MagickExport MagickBooleanType SetImageDepth(Image *image,
 
             channel=GetPixelChannelChannel(image,i);
             traits=GetPixelChannelTraits(image,channel);
-            if ((traits == UndefinedPixelTrait) ||
-                (channel == IndexPixelChannel) ||
-                (channel == ReadMaskPixelChannel))
+            if ((traits & UpdatePixelTrait) == 0)
               continue;
             q[i]=depth_map[ScaleQuantumToMap(q[i])];
           }
@@ -1153,8 +1147,7 @@ MagickExport MagickBooleanType SetImageDepth(Image *image,
 
         channel=GetPixelChannelChannel(image,i);
         traits=GetPixelChannelTraits(image,channel);
-        if ((traits == UndefinedPixelTrait) || (channel == IndexPixelChannel) ||
-            (channel == ReadMaskPixelChannel))
+        if ((traits & UpdatePixelTrait) == 0)
           continue;
         q[i]=ScaleAnyToQuantum(ScaleQuantumToAny(ClampPixel((MagickRealType)
           q[i]),range),range);
index a036f8b2fac00b4017c21e2c752b4f8932af366b..2a8f20ee92854ce83e489ddd19c3d2a882edea14 100644 (file)
@@ -5340,12 +5340,15 @@ MagickPrivate MagickBooleanType SyncAuthenticPixelCacheNexus(Image *image,
   assert(cache_info->signature == MagickCoreSignature);
   if (cache_info->type == UndefinedCache)
     return(MagickFalse);
-  if ((image->write_mask != MagickFalse) &&
-      (ClipPixelCacheNexus(image,nexus_info,exception) == MagickFalse))
-    return(MagickFalse);
-  if ((image->composite_mask != MagickFalse) &&
-      (MaskPixelCacheNexus(image,nexus_info,exception) == MagickFalse))
-    return(MagickFalse);
+  if (image->mask_trait != UpdatePixelTrait)
+    {
+      if ((image->write_mask != MagickFalse) &&
+          (ClipPixelCacheNexus(image,nexus_info,exception) == MagickFalse))
+        return(MagickFalse);
+      if ((image->composite_mask != MagickFalse) &&
+          (MaskPixelCacheNexus(image,nexus_info,exception) == MagickFalse))
+        return(MagickFalse);
+    }
   if (nexus_info->authentic_pixel_cache != MagickFalse)
     {
       image->taint=MagickTrue;
index a5955833f10e74d4ac18f70e4193595dc0115101..c2aafb73839b70cb5886e5a99e339d551d6fa7a2 100644 (file)
@@ -376,6 +376,11 @@ MagickExport Image *ChannelFxImage(const Image *image,const char *expression,
               destination_image->alpha_trait=BlendPixelTrait;
               break;
             }
+            case CompositeMaskPixelChannel:
+            {
+              destination_image->composite_mask=MagickTrue;
+              break;
+            }
             case ReadMaskPixelChannel:
             {
               destination_image->read_mask=MagickTrue;
index 21be905c59cc54fa06cd851f8c33a20d0c119b36..2b2bde8228d6989bad54fe405c2de160ab175c51 100644 (file)
@@ -828,7 +828,9 @@ MagickExport Image *CloneImage(const Image *image,const size_t columns,
   clone_image->colorspace=image->colorspace;
   clone_image->read_mask=image->read_mask;
   clone_image->write_mask=image->write_mask;
+  clone_image->composite_mask=image->composite_mask;
   clone_image->alpha_trait=image->alpha_trait;
+  clone_image->mask_trait=image->mask_trait;
   clone_image->columns=image->columns;
   clone_image->rows=image->rows;
   clone_image->dither=image->dither;
@@ -3193,6 +3195,7 @@ MagickExport MagickBooleanType SetImageMask(Image *image,const PixelMask type,
   if (SyncImagePixelCache(image,exception) == MagickFalse)
     return(MagickFalse);
   status=MagickTrue;
+  image->mask_trait=UpdatePixelTrait;
   mask_view=AcquireVirtualCacheView(mask,exception);
   image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
@@ -3251,6 +3254,7 @@ MagickExport MagickBooleanType SetImageMask(Image *image,const PixelMask type,
     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
       status=MagickFalse;
   }
+  image->mask_trait=UndefinedPixelTrait;
   mask_view=DestroyCacheView(mask_view);
   image_view=DestroyCacheView(image_view);
   return(status);
@@ -3321,9 +3325,10 @@ MagickExport MagickBooleanType SetImageRegionMask(Image *image,
     case WritePixelMask: image->write_mask=MagickTrue; break;
     default: image->composite_mask=MagickTrue; break;
   }
-  if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
+  if (SyncImagePixelCache(image,exception) == MagickFalse)
     return(MagickFalse);
   status=MagickTrue;
+  image->mask_trait=UpdatePixelTrait;
   image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static) shared(status) \
@@ -3377,6 +3382,7 @@ MagickExport MagickBooleanType SetImageRegionMask(Image *image,
     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
       status=MagickFalse;
   }
+  image->mask_trait=UndefinedPixelTrait;
   image_view=DestroyCacheView(image_view);
   return(status);
 }
index 1ef596baa7b54b8e6fa35ca5221abf791dc9992a..62a56a21d4e13597f57dddd12608da2899c4b4d2 100644 (file)
@@ -358,6 +358,9 @@ struct _Image
 
   MagickBooleanType
     composite_mask;
+
+  PixelTrait
+    mask_trait;       /* apply the clip or composite mask */
 };
 
 /*
index dd55ce52fac1904bccb8efb690988cc524955f7c..f74170465aa789ff232351d4f606adcb68e266be 100644 (file)
@@ -6239,6 +6239,11 @@ static void LogPixelChannels(const Image *image)
         name="write-mask";
         break;
       }
+      case CompositeMaskPixelChannel:
+      {
+        name="composite-mask";
+        break;
+      }
       case MetaPixelChannel:
       {
         name="meta";
@@ -6318,6 +6323,8 @@ MagickExport ChannelType SetPixelChannelMask(Image *image,
     SetPixelChannelTraits(image,ReadMaskPixelChannel,CopyPixelTrait);
   if (image->write_mask != MagickFalse)
     SetPixelChannelTraits(image,WriteMaskPixelChannel,CopyPixelTrait);
+  if (image->composite_mask != MagickFalse)
+    SetPixelChannelTraits(image,CompositeMaskPixelChannel,CopyPixelTrait);
   if (image->debug != MagickFalse)
     LogPixelChannels(image);
   return(mask);