]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/composite.c
sigmoidal-contrast: prevent argument out of range and remove unnecessary ClampToQuantum
[imagemagick] / MagickCore / composite.c
index 9093844733db8c55540c9f31bbb1de07020d3877..788bae850f048999970b5d918d906bc6e725938f 100644 (file)
@@ -217,7 +217,8 @@ static void HCLComposite(const double hue,const double chroma,const double luma,
     h,
     m,
     r,
-    x;
+    x,
+    z;
 
   /*
     Convert HCL to RGB colorspace.
@@ -233,43 +234,59 @@ static void HCLComposite(const double hue,const double chroma,const double luma,
   b=0.0;
   if ((0.0 <= h) && (h < 1.0))
     {
-      r=c;      
-      g=x;      
+      r=c;
+      g=x;
     }
   else
     if ((1.0 <= h) && (h < 2.0))
       {
-        r=x;      
-        g=c;      
+        r=x;
+        g=c;
       }
     else
       if ((2.0 <= h) && (h < 3.0))
         {
-          g=c;      
-          b=x;      
+          g=c;
+          b=x;
         }
       else
         if ((3.0 <= h) && (h < 4.0))
           {
-            g=x;      
-            b=c;      
+            g=x;
+            b=c;
           }
         else
           if ((4.0 <= h) && (h < 5.0))
             {
-              r=x;      
-              b=c;      
+              r=x;
+              b=c;
             }
           else
             if ((5.0 <= h) && (h < 6.0))
               {
-                r=c;      
-                b=x;      
+                r=c;
+                b=x;
               }
   m=luma-(0.298839*r+0.586811*g+0.114350*b);
-  *red=QuantumRange*(r+m);
-  *green=QuantumRange*(g+m);
-  *blue=QuantumRange*(b+m);
+  /*
+    Choose saturation strategy to clip it into the RGB cube; hue and luma are
+    preserved and chroma may be changed.
+  */
+  z=1.0;
+  if (m < 0.0)
+    {
+      z=luma/(luma-m);
+      m=0.0;
+    }
+  else
+    if (m+c > 1.0)
+      {
+        z=(1.0-luma)/(m+c-luma);
+        m=1.0-z*c;
+      }
+  *red=QuantumRange*(z*r+m);
+  *green=QuantumRange*(z*g+m);
+  *blue=QuantumRange*(z*b+m);
 }
 
 static void CompositeHCL(const double red,const double green,const double blue,
@@ -441,9 +458,9 @@ static MagickBooleanType CompositeOverImage(Image *image,
               composite_traits,
               traits;
 
-            channel=GetPixelChannelMapChannel(image,i);
-            traits=GetPixelChannelMapTraits(image,channel);
-            composite_traits=GetPixelChannelMapTraits(composite_image,channel);
+            channel=GetPixelChannelChannel(image,i);
+            traits=GetPixelChannelTraits(image,channel);
+            composite_traits=GetPixelChannelTraits(composite_image,channel);
             if ((traits == UndefinedPixelTrait) ||
                 (composite_traits == UndefinedPixelTrait))
               continue;
@@ -478,9 +495,9 @@ static MagickBooleanType CompositeOverImage(Image *image,
           composite_traits,
           traits;
 
-        channel=GetPixelChannelMapChannel(image,i);
-        traits=GetPixelChannelMapTraits(image,channel);
-        composite_traits=GetPixelChannelMapTraits(composite_image,channel);
+        channel=GetPixelChannelChannel(image,i);
+        traits=GetPixelChannelTraits(image,channel);
+        composite_traits=GetPixelChannelTraits(composite_image,channel);
         if ((traits == UndefinedPixelTrait) ||
             (composite_traits == UndefinedPixelTrait))
           continue;
@@ -663,9 +680,9 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
               composite_traits,
               traits;
 
-            channel=GetPixelChannelMapChannel(composite_image,i);
-            composite_traits=GetPixelChannelMapTraits(composite_image,channel);
-            traits=GetPixelChannelMapTraits(image,channel);
+            channel=GetPixelChannelChannel(composite_image,i);
+            composite_traits=GetPixelChannelTraits(composite_image,channel);
+            traits=GetPixelChannelTraits(image,channel);
             if ((traits == UndefinedPixelTrait) ||
                 (composite_traits == UndefinedPixelTrait))
               continue;
@@ -704,7 +721,7 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
         Modify destination outside the overlaid region and require an alpha
         channel to exist, to add transparency.
       */
-      if (image->matte == MagickFalse)
+      if (image->alpha_trait != BlendPixelTrait)
         (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
       break;
     }
@@ -1307,9 +1324,9 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
               composite_traits,
               traits;
 
-            channel=GetPixelChannelMapChannel(image,i);
-            traits=GetPixelChannelMapTraits(image,channel);
-            composite_traits=GetPixelChannelMapTraits(composite_image,channel);
+            channel=GetPixelChannelChannel(image,i);
+            traits=GetPixelChannelTraits(image,channel);
+            composite_traits=GetPixelChannelTraits(composite_image,channel);
             if ((traits == UndefinedPixelTrait) ||
                 (composite_traits == UndefinedPixelTrait))
               continue;
@@ -1498,9 +1515,9 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
           composite_traits,
           traits;
 
-        channel=GetPixelChannelMapChannel(image,i);
-        traits=GetPixelChannelMapTraits(image,channel);
-        composite_traits=GetPixelChannelMapTraits(composite_image,channel);
+        channel=GetPixelChannelChannel(image,i);
+        traits=GetPixelChannelTraits(image,channel);
+        composite_traits=GetPixelChannelTraits(composite_image,channel);
         if (traits == UndefinedPixelTrait)
           continue;
         if ((compose != IntensityCompositeOp) &&
@@ -1597,7 +1614,7 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
               case CopyAlphaCompositeOp:
               {
                 pixel=QuantumRange*Sa;
-                if (composite_image->matte == MagickFalse)
+                if (composite_image->alpha_trait != BlendPixelTrait)
                   pixel=GetPixelIntensity(composite_image,p);
                 break;
               }
@@ -2384,8 +2401,8 @@ MagickExport MagickBooleanType TextureImage(Image *image,const Image *texture,
     exception);
   status=MagickTrue;
   if ((image->compose != CopyCompositeOp) &&
-      ((image->compose != OverCompositeOp) || (image->matte != MagickFalse) ||
-       (texture_image->matte != MagickFalse)))
+      ((image->compose != OverCompositeOp) || (image->alpha_trait == BlendPixelTrait) ||
+       (texture_image->alpha_trait == BlendPixelTrait)))
     {
       /*
         Tile texture onto the image background.
@@ -2502,9 +2519,9 @@ MagickExport MagickBooleanType TextureImage(Image *image,const Image *texture,
             texture_traits,
             traits;
 
-          channel=GetPixelChannelMapChannel(texture_image,i);
-          texture_traits=GetPixelChannelMapTraits(texture_image,channel);
-          traits=GetPixelChannelMapTraits(image,channel);
+          channel=GetPixelChannelChannel(texture_image,i);
+          texture_traits=GetPixelChannelTraits(texture_image,channel);
+          traits=GetPixelChannelTraits(image,channel);
           if ((traits == UndefinedPixelTrait) ||
               (texture_traits == UndefinedPixelTrait))
             continue;