Commit 49e5a1114 for imagemagick.org

commit 49e5a11140d4b837475d4d21ce993d33f3558f12
Author: Cristy <urban-warrior@imagemagick.org>
Date:   Sat Feb 28 09:34:56 2026 -0500

    https://github.com/ImageMagick/ImageMagick/issues/8579

diff --git a/MagickCore/composite.c b/MagickCore/composite.c
index 5039fdb7c..54296c2e5 100644
--- a/MagickCore/composite.c
+++ b/MagickCore/composite.c
@@ -71,6 +71,8 @@
 #include "MagickCore/pixel-accessor.h"
 #include "MagickCore/property.h"
 #include "MagickCore/quantum.h"
+#include "MagickCore/random_.h"
+#include "MagickCore/random-private.h"
 #include "MagickCore/resample.h"
 #include "MagickCore/resource_.h"
 #include "MagickCore/string_.h"
@@ -1459,6 +1461,9 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
   MagickStatusType
     flags;

+  RandomInfo
+    *random_info;
+
   ssize_t
     y;

@@ -2087,7 +2092,7 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
         residual_threshold = 0.0002,
         iterations = 400.0;

-     size_t
+      size_t
         tick = 100;

       artifact=GetImageArtifact(image,"compose:args");
@@ -2191,6 +2196,7 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
   status=MagickTrue;
   progress=0;
   midpoint=((MagickRealType) QuantumRange+1.0)/2;
+  random_info=AcquireRandomInfo();
   source_view=AcquireVirtualCacheView(source_image,exception);
   image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
@@ -2200,6 +2206,7 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
   for (y=0; y < (ssize_t) image->rows; y++)
   {
     const Quantum
+      *magick_restrict p,
       *pixels;

     MagickRealType
@@ -2214,9 +2221,6 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
       canvas_pixel,
       source_pixel;

-    const Quantum
-      *magick_restrict p;
-
     Quantum
       *magick_restrict q;

@@ -2268,13 +2272,14 @@ MagickExport MagickBooleanType CompositeImage(Image *image,

       MagickRealType
         alpha = 0.0,
+        blend = 0.0,
+        D = 0.0,
         Da = 0.0,
         Dc = 0.0,
         Dca = 0.0,
-        DcaDa = 0.0,
         Di = 0.0,
+        S = 0.0,
         Sa = 0.0,
-        SaSca = 0.0,
         Sc = 0.0,
         Sca = 0.0,
         Si = 0.0;
@@ -2593,10 +2598,7 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
               }
               case CopyAlphaCompositeOp:
               {
-                if (source_image->alpha_trait == UndefinedPixelTrait)
-                  pixel=Si;
-                else
-                  pixel=(double) QuantumRange*Sa;
+                pixel=Si;
                 break;
               }
               case BlurCompositeOp:
@@ -2614,7 +2616,7 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
               {
                 if (compose_sync == MagickFalse)
                   {
-                    pixel=Si < Di? Sa : Da;
+                    pixel=Si < Di ? Sa : Da;
                     break;
                   }
                 pixel=Sa*Si < Da*Di ? Sa : Da;
@@ -2720,8 +2722,6 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
         */
         Sca=QuantumScale*Sa*Sc;
         Dca=QuantumScale*Da*Dc;
-        SaSca=Sa*MagickSafeReciprocal(Sca);
-        DcaDa=Dca*MagickSafeReciprocal(Da);
         switch (compose)
         {
           case DarkenCompositeOp:
@@ -2777,7 +2777,7 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
                 pixel=Dc;
                 break;
               }
-            pixel=(double) QuantumScale*Si*Dc;
+            pixel=Dc+(QuantumScale*Si-0.5)*Dc;
             break;
           }
           case ChangeMaskCompositeOp:
@@ -2792,28 +2792,40 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
           }
           case ColorBurnCompositeOp:
           {
-            if ((Sca == 0.0) && (Dca == Da))
-              {
-                pixel=(double) QuantumRange*gamma*(Sa*Da+Dca*(1.0-Sa));
-                break;
-              }
-            if (Sca == 0.0)
-              {
-                pixel=(double) QuantumRange*gamma*(Dca*(1.0-Sa));
-                break;
-              }
-            pixel=(double) QuantumRange*gamma*(Sa*Da-Sa*Da*MagickMin(1.0,
-              (1.0-DcaDa)*SaSca)+Sca*(1.0-Da)+Dca*(1.0-Sa));
+            D=(Da > 0.0) ? RoundToUnity(Dca/Da) : 0.0;
+            S=(Sa > 0.0) ? RoundToUnity(Sca/Sa) : 0.0;
+            if (S <= 0.0)
+              blend=0.0;
+            else
+              blend=1.0-(1.0-D)/S;
+            pixel=(double) QuantumRange*gamma*RoundToUnity(Sa*Da*
+              RoundToUnity(blend)+Sa*(1.0-Da)*S+Da*(1.0-Sa)*D);
             break;
           }
           case ColorDodgeCompositeOp:
           {
-            if ((Sca*Da+Dca*Sa) >= Sa*Da)
-              pixel=(double) QuantumRange*gamma*(Sa*Da+Sca*(1.0-Da)+Dca*
-                (1.0-Sa));
+            if (Sa > 0.0)
+              S=RoundToUnity(Sca/Sa);
+            else
+              S=0.0;
+            if (Da > 0.0)
+              D=RoundToUnity(Dca/Da);
+            else
+              D=0.0;
+            if (S >= 1.0)
+              blend=1.0;
             else
-              pixel=(double) QuantumRange*gamma*(Dca*Sa*Sa*
-                MagickSafeReciprocal(Sa-Sca)+Sca*(1.0-Da)+Dca*(1.0-Sa));
+              if (D <= 0.0)
+                blend=0.0;
+              else
+                {
+                  if ((1.0-S) <= 0.0)
+                    blend=1.0;
+                  else
+                    blend=MagickMin(1.0,D/(1.0-S));
+                }
+            pixel=(double) QuantumRange*gamma*(Sa*Da*blend+Sca*(1.0-Da)+Dca*
+              (1.0-Sa));
             break;
           }
           case ColorizeCompositeOp:
@@ -2880,95 +2892,71 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
           }
           case DarkenCompositeOp:
           {
-            /*
-              Darken is equivalent to a 'Minimum' method
-                OR a greyscale version of a binary 'Or'
-                OR the 'Intersection' of pixel sets.
-            */
             if (compose_sync == MagickFalse)
               {
-                pixel=MagickMin(Sc,Dc);
-                break;
-              }
-            if ((Sca*Da) < (Dca*Sa))
-              {
-                pixel=(double) QuantumRange*(Sca+Dca*(1.0-Sa));
+                pixel=RoundToUnity(MagickMin(Sca,Dca)+Sca*(1.0-Da)+Dca*
+                  (1.0-Sa));
                 break;
               }
-            pixel=(double) QuantumRange*(Dca+Sca*(1.0-Da));
+            pixel=(double) QuantumRange*RoundToUnity(MagickMin(Sca,Dca)+Sca*
+              (1.0-Da)+Dca*(1.0-Sa));
             break;
           }
           case DarkenIntensityCompositeOp:
           {
             if (compose_sync == MagickFalse)
               {
-                pixel=Si < Di ? Sc : Dc;
+                pixel=RoundToUnity(MagickMin(Sca,Dca)+Sca*(1.0-Di)+Dca*
+                  (1.0-Si));
                 break;
               }
-            pixel=Sa*Si < Da*Di ? Sc : Dc;
+            pixel=(double) QuantumRange*RoundToUnity(MagickMin(Sca,Dca)+Sca*
+              (1.0-Di)+Dca*(1.0-Si));
             break;
           }
           case DifferenceCompositeOp:
           {
             if (compose_sync == MagickFalse)
               {
-                pixel=fabs((double) Sc-Dc);
-                break;
+                 pixel=(double) QuantumRange*RoundToUnity(fabs((double) Sc-
+                  (double) Dc));
+                 break;
               }
-            pixel=(double) QuantumRange*gamma*(Sca+Dca-2.0*MagickMin(Sca*Da,
-              Dca*Sa));
+            S=(Sa > 0.0) ? (Sca/Sa) : 0.0;
+            D=(Da > 0.0) ? (Dca/Da) : 0.0;
+            pixel=(double) QuantumRange*RoundToUnity(fabs(S-D));
             break;
           }
           case DissolveCompositeOp:
           {
-            pixel=gamma*(source_dissolve*Sa*Sc-source_dissolve*Sa*
-              canvas_dissolve*Da*Dc+canvas_dissolve*Da*Dc);
+            if (GetPseudoRandomValue(random_info) < (source_dissolve*Sa))
+              pixel=Sc;
+            else
+              pixel=Dc;
             break;
           }
           case DivideDstCompositeOp:
           {
-            if (compose_sync == MagickFalse)
-              {
-                pixel=(double) QuantumRange*(Sc/MagickSafeReciprocal(Dc));
-                break;
-              }
-            if ((fabs((double) Sca) < MagickEpsilon) &&
-                (fabs((double) Dca) < MagickEpsilon))
-              {
-                pixel=(double) QuantumRange*gamma*(Sca*(1.0-Da)+Dca*(1.0-Sa));
-                break;
-              }
-            if (fabs((double) Dca) < MagickEpsilon)
-              {
-                pixel=(double) QuantumRange*gamma*(Sa*Da+Sca*(1.0-Da)+Dca*
-                  (1.0-Sa));
-                break;
-              }
-            pixel=(double) QuantumRange*gamma*(Sca*Da*Da/Dca+Sca*(1.0-Da)+Dca*
-              (1.0-Sa));
+            S=(Sa > 0.0) ? (Sca/Sa) : 0.0;
+            D=(Da > 0.0) ? (Dca/Da) : 0.0;
+            if (S <= 0.0)
+              blend=1.0;
+            else
+              blend=MagickMin(1.0,D/S);
+            pixel=(double) QuantumRange*RoundToUnity(Sca*(1.0-Da)+Dca*(1.0-Sa)+
+              Sa*Da*blend);
             break;
           }
           case DivideSrcCompositeOp:
           {
-            if (compose_sync == MagickFalse)
-              {
-                pixel=(double) QuantumRange*(Dc/MagickSafeReciprocal(Sc));
-                break;
-              }
-            if ((fabs((double) Dca) < MagickEpsilon) &&
-                (fabs((double) Sca) < MagickEpsilon))
-              {
-                pixel=(double) QuantumRange*gamma*(Dca*(1.0-Sa)+Sca*(1.0-Da));
-                break;
-              }
-            if (fabs((double) Sca) < MagickEpsilon)
-              {
-                pixel=(double) QuantumRange*gamma*(Da*Sa+Dca*(1.0-Sa)+Sca*
-                  (1.0-Da));
-                break;
-              }
-            pixel=(double) QuantumRange*gamma*(Dca*Sa*SaSca+Dca*(1.0-Sa)+Sca*
-              (1.0-Da));
+            S=(Sa > 0.0) ? (Sca/Sa) : 0.0;
+            D=(Da > 0.0) ? (Dca/Da) : 0.0;
+            if (D <= 0.0)
+              blend=1.0;
+            else
+              blend=MagickMin(1.0,S/D);
+            pixel=(double) QuantumRange*RoundToUnity(Sca*(1.0-Da)+Dca*(1.0-Sa)+
+              Sa*Da*blend);
             break;
           }
           case DstAtopCompositeOp:
@@ -2993,33 +2981,51 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
           }
           case ExclusionCompositeOp:
           {
-            pixel=(double) QuantumRange*gamma*(Sca*Da+Dca*Sa-2.0*Sca*Dca+Sca*
-              (1.0-Da)+Dca*(1.0-Sa));
+            S=(Sa > 0.0) ? Sca/Sa : 0.0;
+            D=(Da > 0.0) ? Dca/Da : 0.0;
+            blend=RoundToUnity(S+D-2.0*S*D);
+            pixel=(double) QuantumRange*RoundToUnity((blend*Sa+D*(1.0-Sa))*
+              (Sa+Da-Sa*Da));
             break;
           }
           case FreezeCompositeOp:
-          {
-            pixel=(double) QuantumRange*gamma*(1.0-(1.0-Sca)*(1.0-Sca)*
-              MagickSafeReciprocal(Dca));
-            if (pixel < 0.0)
-              pixel=0.0;
+          {
+            if (Dca != 0.0)
+              blend=1.0-(1.0-Sca)*(1.0-Sca)/Dca;
+            else
+              blend=0.0;
+            pixel=(double) QuantumRange*gamma*RoundToUnity(blend);
             break;
           }
           case HardLightCompositeOp:
           {
-            if ((2.0*Sca) < Sa)
-              {
-                pixel=(double) QuantumRange*gamma*(2.0*Sca*Dca+Sca*(1.0-Da)+Dca*
-                  (1.0-Sa));
-                break;
-              }
-            pixel=(double) QuantumRange*gamma*(Sa*Da-2.0*(Da-Dca)*(Sa-Sca)+Sca*
-              (1.0-Da)+Dca*(1.0-Sa));
+            D=(Da > 0.0) ? (Dca/Da) : 0.0;
+            S=(Sa > 0.0) ? (Sca/Sa) : 0.0;
+            if (S <= 0.5)
+              blend=2.0*S*D;
+            else
+              blend=1.0-2.0*(1.0-S)*(1.0-D);
+            pixel=(double) QuantumRange*gamma*RoundToUnity((1.0-Da)*Sca+
+              (1.0-Sa)*Dca+blend*Sa*Da);
             break;
           }
           case HardMixCompositeOp:
           {
-            pixel=gamma*(((Sca+Dca) < 1.0) ? 0.0 : (double) QuantumRange);
+            if (Sca < 0.5)
+              {
+                if ((2.0*Sca) == 0.0)
+                  blend=0.0;
+                else
+                  blend=1.0-(1.0-Dca)/(2.0*Sca);
+              }
+            else
+              {
+                if ((1.0-((2.0*Sca)-1.0)) == 0.0)
+                  blend=1.0;
+                else
+                  blend=Dca/(1.0-(2.0*Sca-1.0));
+              }
+            pixel=gamma*((blend < 0.5) ? 0.0 : (double) QuantumRange);
             break;
           }
           case HueCompositeOp:
@@ -3071,7 +3077,7 @@ MagickExport MagickBooleanType CompositeImage(Image *image,

                 f(Sc,Dc) = Sc + Dc - 1
             */
-            pixel=(double) QuantumRange*gamma*(Sca+Dca-Sa*Da);
+            pixel=(double) QuantumRange*(Sca+Dca-Sa*Da);
             break;
           }
           case LinearDodgeCompositeOp:
@@ -3082,12 +3088,13 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
           case LinearLightCompositeOp:
           {
             /*
-              LinearLight: as defined by Abode Photoshop, according to
-              http://www.simplefilter.de/en/basics/mixmods.html is:
-
-                f(Sc,Dc) = Dc + 2*Sc - 1
+              Linear Light (Adobe standard):
+                f(Sc, Dc) = Dc + 2*Sc - 1
+              Applied in linear (HDRI) space with clamping.
             */
-            pixel=(double) QuantumRange*gamma*((Sca-Sa)*Da+Sca+Dca);
+            D=(Da > 0.0) ? Dca/Da : 0.0,
+            S=(Sa > 0.0) ? Sca/Sa : 0.0;
+            pixel=(double) QuantumRange*gamma*(RoundToUnity(D+2.0*S-1.0)*Da);
             break;
           }
           case LightenCompositeOp:
@@ -3097,27 +3104,15 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
                 pixel=MagickMax(Sc,Dc);
                 break;
               }
-            if ((Sca*Da) > (Dca*Sa))
-              {
-                pixel=(double) QuantumRange*(Sca+Dca*(1.0-Sa));
-                break;
-              }
-            pixel=(double) QuantumRange*(Dca+Sca*(1.0-Da));
+            S=(Sa > 0.0) ? (Sca/Sa) : 0.0;
+            D=(Da > 0.0) ? (Dca/Da) : 0.0;
+            pixel=(double) QuantumRange*RoundToUnity(Sca*(1.0-Da)+Dca*(1.0-Sa)+
+              MagickMax(S,D)*Sa*Da);
             break;
           }
           case LightenIntensityCompositeOp:
           {
-            /*
-              Lighten is equivalent to a 'Maximum' method
-                OR a greyscale version of a binary 'And'
-                OR the 'Union' of pixel sets.
-            */
-            if (compose_sync == MagickFalse)
-              {
-                pixel=Si > Di ? Sc : Dc;
-                break;
-              }
-            pixel=Sa*Si > Da*Di ? Sc : Dc;
+            pixel=Si > Di ? Sc : Dc;
             break;
           }
           case LuminizeCompositeOp:
@@ -3188,22 +3183,12 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
                 pixel=Dc-Sc;
                 break;
               }
-            pixel=gamma*(Sa*Sc+Da*Dc-2.0*Da*Dc*Sa);
+            pixel=gamma*(Da*Dc-Sa*Sc);
             break;
           }
           case MinusSrcCompositeOp:
           {
-            /*
-              Minus source from canvas.
-
-                f(Sc,Dc) = Sc - Dc
-            */
-            if (compose_sync == MagickFalse)
-              {
-                pixel=Sc-Dc;
-                break;
-              }
-            pixel=gamma*(Da*Dc+Sa*Sc-2.0*Sa*Sc*Da);
+            pixel=Sc-Dc;
             break;
           }
           case ModulateCompositeOp:
@@ -3240,48 +3225,39 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
           }
           case ModulusAddCompositeOp:
           {
-            if (compose_sync == MagickFalse)
-              {
-                pixel=(Sc+Dc);
-                break;
-              }
-            if ((Sca+Dca) <= 1.0)
-              {
-                pixel=(double) QuantumRange*(Sca+Dca);
-                break;
-              }
-            pixel=(double) QuantumRange*((Sca+Dca)-1.0);
+            pixel=(double) QuantumRange*(Sc+Dc-floor(Sc+Dc));
             break;
           }
           case ModulusSubtractCompositeOp:
           {
+            D=(Da > 0.0) ? (Dc/Da) : 0.0;
+            S=(Sa > 0.0) ? (Sc/Sa) : 0.0;
+            blend=S-D;
+            if (blend < 0.0)
+              blend+=1.0;
             if (compose_sync == MagickFalse)
               {
-                pixel=(Sc-Dc);
-                break;
-              }
-            if ((Sca-Dca) >= 0.0)
-              {
-                pixel=(double) QuantumRange*(Sca-Dca);
+                pixel=(double) QuantumRange*(blend*Sa);
                 break;
               }
-            pixel=(double) QuantumRange*((Sca-Dca)+1.0);
+            pixel=(double) QuantumRange*(blend*Sa);
             break;
           }
           case MultiplyCompositeOp:
           {
             if (compose_sync == MagickFalse)
               {
-                pixel=(double) QuantumScale*Dc*Sc;
+                pixel=(double) QuantumRange*Sc*Dc;
                 break;
               }
-            pixel=(double) QuantumRange*gamma*(Sca*Dca+Sca*(1.0-Da)+Dca*
-              (1.0-Sa));
+            pixel=(double) QuantumRange*(Sca*Dca+Sca*(1.0-Da)+Dca*(1.0-Sa));
             break;
           }
           case NegateCompositeOp:
           {
-            pixel=(double) QuantumRange*(1.0-fabs(1.0-Sca-Dca));
+            D=(Da > 0.0) ? Dca/Da : 0.0;
+            S=(Sa > 0.0) ? Sca/Sa : 0.0;
+            pixel=(double) QuantumRange*((1.0-fabs(1.0-S-D))*Da);
             break;
           }
           case NoCompositeOp:
@@ -3298,7 +3274,11 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
           case OverCompositeOp:
           case SrcOverCompositeOp:
           {
-            pixel=(double) QuantumRange*gamma*(Sca+Dca*(1.0-Sa));
+            if ((Sa+Da*(1.0-Sa)) <= MagickEpsilon)
+              pixel=0.0;
+            else
+              pixel=(double) QuantumRange*gamma*((Sca+Dca*(1.0-Sa))/
+                (Sa+Da*(1.0-Sa)));
             break;
           }
           case OverlayCompositeOp:
@@ -3315,61 +3295,79 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
           }
           case PegtopLightCompositeOp:
           {
-            /*
-              PegTop: A Soft-Light alternative: A continuous version of the
-              Softlight function, producing very similar results.
-
-                f(Sc,Dc) = Dc^2*(1-2*Sc) + 2*Sc*Dc
-
-              http://www.pegtop.net/delphi/articles/blendmodes/softlight.htm.
-            */
             if (fabs((double) Da) < MagickEpsilon)
               {
                 pixel=(double) QuantumRange*gamma*Sca;
                 break;
               }
-            pixel=(double) QuantumRange*gamma*(Dca*Dca*(Sa-2.0*Sca)/Da+Sca*
-              (2.0*Dca+1.0-Da)+Dca*(1.0-Sa));
+            if (RoundToUnity(Sca) <= 0.5)
+              blend=RoundToUnity(Dca/Da)-(1.0-2.0*RoundToUnity(Sca))*
+                RoundToUnity(Dca/Da)*(1.0-RoundToUnity(Dca/Da));
+            else
+              {
+                if (RoundToUnity(Dca/Da) <= 0.25)
+                  blend=((16.0*RoundToUnity(Dca/Da)-12.0)*RoundToUnity(Dca/Da)+
+                    4.0)*RoundToUnity(Dca/Da);
+                else
+                  blend=sqrt(RoundToUnity(Dca/Da));
+                blend=RoundToUnity(Dca/Da)+(2.0*RoundToUnity(Sca)-1.0)*
+                  (blend-RoundToUnity(Dca/Da));
+              }
+            pixel=(double) QuantumRange*gamma*(RoundToUnity(blend)*Da*Sa+Dca*
+              (1.0-Sa));
             break;
           }
           case PinLightCompositeOp:
           {
             /*
-              PinLight: A Photoshop 7 composition method
-              http://www.simplefilter.de/en/basics/mixmods.html
+              Adobe Pin Light (colors in [0,1]):

-                f(Sc,Dc) = Dc<2*Sc-1 ? 2*Sc-1 : Dc>2*Sc   ? 2*Sc : Dc
+                if (Cs <= 0.5)
+                  f = min(Cd, 2*Cs);
+                else
+                  f = max(Cd, 2*Cs - 1);
             */
-            if ((Dca*Sa) < (Da*(2.0*Sca-Sa)))
-              {
-                pixel=(double) QuantumRange*gamma*(Sca*(Da+1.0)-Sa*Da+Dca*
-                  (1.0-Sa));
-                break;
-              }
-            if ((Dca*Sa) > (2.0*Sca*Da))
-              {
-                pixel=(double) QuantumRange*gamma*(Sca*Da+Sca+Dca*(1.0-Sa));
-                break;
-              }
-            pixel=(double) QuantumRange*gamma*(Sca*(1.0-Da)+Dca);
+            D=(Da > 0.0) ? RoundToUnity(Dca/Da) : 0.0;
+            S=(Sa > 0.0) ? RoundToUnity(Sca/Sa) : 0.0;
+            if (S <= 0.5)
+              blend=MagickMin(D,2.0*S);
+            else
+              blend=MagickMax(D,2.0*S-1.0);
+            pixel=(double) QuantumRange*gamma*(blend*RoundToUnity(Sa+Da-Sa*Da));
             break;
           }
           case PlusCompositeOp:
           {
-            if (compose_sync == MagickFalse)
-              {
-                pixel=(Dc+Sc);
-                break;
-              }
-            pixel=(double) QuantumRange*(Sca+Dca);
+            D=(Da > 0.0) ? Dca/Da : 0.0;
+            S=(Sa > 0.0) ? Sca/Sa : 0.0;
+            pixel=(double) QuantumRange*(RoundToUnity(Sa+Da-Sa*Da)*
+              RoundToUnity(S+D));
             break;
           }
           case ReflectCompositeOp:
           {
-            pixel=(double) QuantumRange*gamma*(Sca*Sca*
-              MagickSafeReciprocal(1.0-Dca));
-            if (pixel > (double) QuantumRange)
-              pixel=(double) QuantumRange;
+            if (compose_sync == MagickFalse)
+              {
+                if (Dc < 1.0)
+                  blend=(Sc*Sc)/(1.0-Dc);
+                else
+                  blend=1.0;
+                pixel=(double) QuantumRange*RoundToUnity(blend);
+                break;
+              }
+            if (Sa > 0.0)
+              S=Sca/Sa;
+            else
+              S=0.0;
+            if (Da > 0.0)
+              D=Dca/Da;
+            else
+              D=0.0;
+            if (D < 1.0)
+              blend=(S*S)/(1.0-D);
+            else
+              blend=1.0;
+            pixel=(double) QuantumRange*RoundToUnity((Sa+Da-Sa*Da)*blend);
             break;
           }
           case RMSECompositeOp:
@@ -3434,61 +3432,74 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
           }
           case ScreenCompositeOp:
           {
-            /*
-              Screen:  a negated multiply:
-
-                f(Sc,Dc) = 1.0-(1.0-Sc)*(1.0-Dc)
-            */
             if (compose_sync == MagickFalse)
               {
-                pixel=Sc+Dc-Sc*Dc;
+                pixel=(double) QuantumRange*RoundToUnity(Sc+Dc-Sc*Dc);
                 break;
               }
-            pixel=(double) QuantumRange*gamma*(Sca+Dca-Sca*Dca);
+            if (Sa > 0.0)
+              S=Sca/Sa;
+            else
+              S=0.0;
+            if (Da > 0.0)
+              D=Dca/Da;
+            else
+              D=0.0;
+            if ((Sa+Da-Sa*Da) > 0.0)
+              pixel=(double) QuantumRange*RoundToUnity((Sa+Da-Sa*Da)*(S+D-S*D));
+            else
+              pixel=0.0;
             break;
           }
           case SoftBurnCompositeOp:
           {
-            if ((Sca+Dca) < 1.0)
-              pixel=(double) QuantumRange*gamma*(0.5*Dca*
-                MagickSafeReciprocal(1.0-Sca));
+            if (RoundToUnity(Dca) <= 0.0)
+              blend = 0.0;
             else
-              pixel=(double) QuantumRange*gamma*(1.0-0.5*(1.0-Sca)*
-                MagickSafeReciprocal(Dca));
+              if (RoundToUnity(Sca) >= 1.0)
+                blend = 1.0;
+              else
+                blend=1.0-MagickMin(1.0,(1.0-RoundToUnity(Dca))/
+                  RoundToUnity(Sca));
+            pixel=(double) QuantumRange*gamma*RoundToUnity(blend);
             break;
           }
           case SoftDodgeCompositeOp:
           {
-            if ((Sca+Dca) < 1.0)
-              pixel=(double) QuantumRange*gamma*(0.5*Sca*
-                MagickSafeReciprocal(1.0-Dca));
+            if (RoundToUnity(Sca) <= 0.0)
+              blend=RoundToUnity(Dca);
             else
-              pixel=(double) QuantumRange*gamma*(1.0-0.5*(1.0-Dca)*
-                MagickSafeReciprocal(Sca));
+              if (RoundToUnity(Dca) >= 1.0)
+                blend=1.0;
+              else
+                blend=MagickMin(1.0,RoundToUnity(Dca)/(1.0-RoundToUnity(Sca)));
+            pixel=(double) QuantumRange*gamma*RoundToUnity(blend);
             break;
           }
           case SoftLightCompositeOp:
           {
-            if ((2.0*Sca) < Sa)
-              {
-                pixel=(double) QuantumRange*gamma*(Dca*(Sa+(2.0*Sca-Sa)*
-                  (1.0-DcaDa))+Sca*(1.0-Da)+Dca*(1.0-Sa));
-                break;
-              }
-            if (((2.0*Sca) > Sa) && ((4.0*Dca) <= Da))
+            if (RoundToUnity(Sca) <= 0.5)
               {
-                pixel=(double) QuantumRange*gamma*(Dca*Sa+Da*(2.0*Sca-Sa)*
-                  (4.0*DcaDa*(4.0*DcaDa+1.0)*(DcaDa-1.0)+7.0*DcaDa)+Sca*
-                  (1.0-Da)+Dca*(1.0-Sa));
+                pixel=(double) QuantumRange*gamma*(RoundToUnity(Dca)*Sa+Da*
+                 (RoundToUnity(Dca)-(1.0-2.0*RoundToUnity(Sca))*
+                 RoundToUnity(Dca)*(1.0-RoundToUnity(Dca)))+RoundToUnity(Sca)*
+                 (1.0-Da)+RoundToUnity(Dca)*(1.0-Sa));
                 break;
               }
-            pixel=(double) QuantumRange*gamma*(Dca*Sa+Da*(2.0*Sca-Sa)*
-              (pow(DcaDa,0.5)-DcaDa)+Sca*(1.0-Da)+Dca*(1.0-Sa));
+            if (RoundToUnity(Dca) > 0.25)
+              blend=sqrt(RoundToUnity(Dca));
+            else
+              blend=((16.0*RoundToUnity(Dca)-12.0)*RoundToUnity(Dca)+4.0)*
+                RoundToUnity(Dca);
+            pixel=(double) QuantumRange*gamma*(RoundToUnity(Dca)*Sa+Da*
+              (RoundToUnity(Dca)+(2.0*RoundToUnity(Sca)-1.0)*
+              (RoundToUnity(blend)-RoundToUnity(Dca)))+RoundToUnity(Sca)*
+              (1.0-Da)+RoundToUnity(Dca)*(1.0-Sa));
             break;
           }
           case StampCompositeOp:
           {
-            pixel=(double) QuantumRange*(Sca+Dca*Dca-1.0);
+            pixel=(double) QuantumRange*RoundToUnity(Sca+Dca-1.0);
             break;
           }
           case StereoCompositeOp:
@@ -3499,41 +3510,37 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
           }
           case ThresholdCompositeOp:
           {
-            MagickRealType
-              delta;
-
-            delta=Sc-Dc;
-            if ((MagickRealType) fabs((double) (2.0*delta)) < threshold)
-              {
-                pixel=gamma*Dc;
-                break;
-              }
-            pixel=gamma*(Dc+delta*amount);
+            S=(Sa > 0.0) ? (Sca/Sa) : 0.0;
+            D=(Da > 0.0) ? (Dca/Da) : 0.0;
+            if (fabs(2.0*(S-D)) < threshold)
+              blend=D;
+            else
+              blend=D+(S-D)*amount;
+            pixel=(double) QuantumRange*(Sa*Da*RoundToUnity(blend)+Sca*
+              (1.0-Da)+Dca*(1.0-Sa));
             break;
           }
           case VividLightCompositeOp:
           {
-            /*
-              VividLight: A Photoshop 7 composition method.  See
-              http://www.simplefilter.de/en/basics/mixmods.html.
-
-                f(Sc,Dc) = (2*Sc < 1) ? 1-(1-Dc)/(2*Sc) : Dc/(2*(1-Sc))
-            */
             if ((fabs((double) Sa) < MagickEpsilon) ||
-                (fabs((double) (Sca-Sa)) < MagickEpsilon))
+                (fabs((double) Da) < MagickEpsilon))
               {
                 pixel=(double) QuantumRange*gamma*(Sa*Da+Sca*(1.0-Da)+Dca*
                   (1.0-Sa));
                 break;
               }
-            if ((2.0*Sca) <= Sa)
-              {
-                pixel=(double) QuantumRange*gamma*(Sa*(Da+Sa*(Dca-Da)*
-                  MagickSafeReciprocal(2.0*Sca))+Sca*(1.0-Da)+Dca*(1.0-Sa));
-                break;
-              }
-            pixel=(double) QuantumRange*gamma*(Dca*Sa*Sa*
-              MagickSafeReciprocal(2.0*(Sa-Sca))+Sca*(1.0-Da)+Dca*(1.0-Sa));
+            if (RoundToUnity(Sca/Sa) <= 0.0)
+              blend=0.0;
+            else
+              if (RoundToUnity(Sca/Sa) < 0.5)
+                blend=1.0-(1.0-RoundToUnity(Dca/Da))/(2.0*RoundToUnity(Sca/Sa));
+            else
+              if (RoundToUnity(Sca/Sa) < 1.0)
+                blend=RoundToUnity(Dca/Da)/(2.0*(1.0-RoundToUnity(Sca/Sa)));
+              else
+                blend=1.0;
+            pixel=(double) QuantumRange*gamma*(Sa*Da*RoundToUnity(blend)+Sca*
+              (1.0-Da)+Dca*(1.0-Sa));
             break;
           }
           case XorCompositeOp:
@@ -3573,6 +3580,7 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
   }
   source_view=DestroyCacheView(source_view);
   image_view=DestroyCacheView(image_view);
+  random_info=DestroyRandomInfo(random_info);
   if (canvas_image != (Image * ) NULL)
     canvas_image=DestroyImage(canvas_image);
   else
diff --git a/PerlMagick/Magick.xs b/PerlMagick/Magick.xs
index cb7f8feaf..463bc3479 100644
--- a/PerlMagick/Magick.xs
+++ b/PerlMagick/Magick.xs
@@ -8886,8 +8886,8 @@ Mogrify(ref,...)
                   */
                   mask_image=CloneImage(argument_list[10].image_reference,0,0,
                     MagickTrue,exception);
-                  (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
-                    exception);
+                  (void) CompositeImage(composite_image,mask_image,
+                    CopyAlphaCompositeOp,clip_to_self,0,0,exception);
                   mask_image=DestroyImage(mask_image);
                 }
             }
diff --git a/PerlMagick/quantum/quantum.xs.in b/PerlMagick/quantum/quantum.xs.in
index f6b3352e7..18bcf7251 100644
--- a/PerlMagick/quantum/quantum.xs.in
+++ b/PerlMagick/quantum/quantum.xs.in
@@ -8907,8 +8907,8 @@ Mogrify(ref,...)
                   */
                   mask_image=CloneImage(argument_list[10].image_reference,0,0,
                     MagickTrue,exception);
-                  (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
-                    exception);
+                  (void) CompositeImage(composite_image,mask_image,
+                    CopyAlphaCompositeOp,clip_to_self,0,0,exception);
                   mask_image=DestroyImage(mask_image);
                 }
             }