]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/composite.c
(no commit message)
[imagemagick] / MagickCore / composite.c
index d205f4e95b537f40ab08d70e9ad5b639e195d644..d4dd47e5a65ea88412b9b46566cc4c69fce5d5b0 100644 (file)
@@ -294,7 +294,11 @@ static MagickBooleanType CompositeOverImage(Image *image,
     *source_view,
     *image_view;
 
+  const char
+     *value;
+
   MagickBooleanType
+    clamp,
     status;
 
   MagickOffsetType
@@ -308,6 +312,10 @@ static MagickBooleanType CompositeOverImage(Image *image,
   */
   status=MagickTrue;
   progress=0;
+  clamp=MagickTrue;
+  value=GetImageArtifact(image,"compose:clamp");
+  if (value != (const char *) NULL)
+    clamp=IsStringTrue(value);
   source_view=AcquireVirtualCacheView(source_image,exception);
   image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
@@ -457,7 +465,9 @@ static MagickBooleanType CompositeOverImage(Image *image,
             /*
               Set alpha channel.
             */
-            q[i]=ClampToQuantum(QuantumRange*(Sa+Da-Sa*Da));
+            q[i]=clamp != MagickFalse ?
+              ClampPixel(QuantumRange*(Sa+Da-Sa*Da)) :
+              ClampToQuantum(QuantumRange*(Sa+Da-Sa*Da));
             continue;
           }
         /*
@@ -468,7 +478,9 @@ static MagickBooleanType CompositeOverImage(Image *image,
         Dc=(MagickRealType) q[i];
         Sca=QuantumScale*Sa*Sc;
         Dca=QuantumScale*Da*Dc;
-        q[i]=ClampToQuantum(QuantumRange*(Sca+Dca*(1.0-Sa)));
+        q[i]=clamp != MagickFalse ?
+          ClampPixel(QuantumRange*(Sca+Dca*(1.0-Sa))) :
+          ClampToQuantum(QuantumRange*(Sca+Dca*(1.0-Sa)));
       }
       p+=GetPixelChannels(source_image);
       channels=GetPixelChannels(source_image);
@@ -508,6 +520,9 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
     *source_view,
     *image_view;
 
+  const char
+    *value;
+
   GeometryInfo
     geometry_info;
 
@@ -516,6 +531,7 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
     *source_image;
 
   MagickBooleanType
+    clamp,
     status;
 
   MagickOffsetType
@@ -553,7 +569,6 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
   if ((image->alpha_trait != UndefinedPixelTrait) &&
       (source_image->alpha_trait == UndefinedPixelTrait))
     (void) SetImageAlphaChannel(source_image,SetAlphaChannel,exception);
-if (0)
   if ((compose == OverCompositeOp) || (compose == SrcOverCompositeOp))
     {
       status=CompositeOverImage(image,source_image,clip_to_self,x_offset,
@@ -561,9 +576,13 @@ if (0)
       source_image=DestroyImage(source_image);
       return(status);
     }
-  canvas_image=(Image *) NULL;
   amount=0.5;
+  canvas_image=(Image *) NULL;
   canvas_dissolve=1.0;
+  clamp=MagickTrue;
+  value=GetImageArtifact(image,"compose:clamp");
+  if (value != (const char *) NULL)
+    clamp=IsStringTrue(value);
   percent_luma=100.0;
   percent_chroma=100.0;
   source_dissolve=1.0;
@@ -601,8 +620,8 @@ if (0)
 
         if (status == MagickFalse)
           continue;
-        p=GetCacheViewVirtualPixels(source_view,0,y,source_image->columns,
-          1,exception);
+        p=GetCacheViewVirtualPixels(source_view,0,y,source_image->columns,1,
+          exception);
         q=GetCacheViewAuthenticPixels(image_view,x_offset,y+y_offset,
           source_image->columns,1,exception);
         if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
@@ -688,8 +707,8 @@ if (0)
 
         if (status == MagickFalse)
           continue;
-        p=GetCacheViewVirtualPixels(source_view,0,y,source_image->columns,
-          1,exception);
+        p=GetCacheViewVirtualPixels(source_view,0,y,source_image->columns,1,
+          exception);
         q=GetCacheViewAuthenticPixels(image_view,x_offset,y+y_offset,
           source_image->columns,1,exception);
         if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
@@ -705,8 +724,9 @@ if (0)
               q+=GetPixelChannels(image);
               continue;
             }
-          SetPixelAlpha(image,ClampToQuantum(GetPixelIntensity(source_image,
-            p)),q);
+          SetPixelAlpha(image,clamp != MagickFalse ?
+            ClampPixel(GetPixelIntensity(source_image,p)) :
+            ClampToQuantum(GetPixelIntensity(source_image,p)),q);
           p+=GetPixelChannels(source_image);
           q+=GetPixelChannels(image);
         }
@@ -865,10 +885,10 @@ if (0)
 
         if (((y+y_offset) < 0) || ((y+y_offset) >= (ssize_t) image->rows))
           continue;
-        p=GetCacheViewVirtualPixels(source_view,0,y,source_image->columns,
-          1,exception);
-        q=QueueCacheViewAuthenticPixels(canvas_view,0,y,
-          canvas_image->columns,1,exception);
+        p=GetCacheViewVirtualPixels(source_view,0,y,source_image->columns,1,
+          exception);
+        q=QueueCacheViewAuthenticPixels(canvas_view,0,y,canvas_image->columns,1,
+          exception);
         if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
           break;
         for (x=0; x < (ssize_t) source_image->columns; x++)
@@ -958,7 +978,7 @@ if (0)
       value=GetImageArtifact(image,"compose:args");
       if (value != (char *) NULL)
         flags=ParseGeometry(value,&geometry_info);
-      if ((flags & (WidthValue|HeightValue)) == 0 )
+      if ((flags & (WidthValue | HeightValue)) == 0 )
         {
           if ((flags & AspectValue) == 0)
             {
@@ -1004,26 +1024,26 @@ if (0)
       if (compose == DistortCompositeOp)
         {
           if ((flags & XValue) == 0)
-            if ((flags & AspectValue) == 0)
+            if ((flags & AspectValue) != 0)
+              center.x=(MagickRealType) ((image->columns-1)/2.0);
+            else
               center.x=(MagickRealType) (x_offset+(source_image->columns-1)/
                 2.0);
-            else
-              center.x=(MagickRealType) ((image->columns-1)/2.0);
           else
-            if ((flags & AspectValue) == 0)
-              center.x=(MagickRealType) x_offset+geometry_info.xi;
-            else
+            if ((flags & AspectValue) != 0)
               center.x=geometry_info.xi;
-          if ((flags & YValue) == 0)
-            if ((flags & AspectValue) == 0)
-              center.y=(MagickRealType) (y_offset+(source_image->rows-1)/2.0);
             else
+              center.x=(MagickRealType) (x_offset+geometry_info.xi);
+          if ((flags & YValue) == 0)
+            if ((flags & AspectValue) != 0)
               center.y=(MagickRealType) ((image->rows-1)/2.0);
-          else
-            if ((flags & AspectValue) == 0)
-              center.y=(MagickRealType) y_offset+geometry_info.psi;
             else
+              center.y=(MagickRealType) (y_offset+(source_image->rows-1)/2.0);
+          else
+            if ((flags & AspectValue) != 0)
               center.y=geometry_info.psi;
+            else
+              center.y=(MagickRealType) (y_offset+geometry_info.psi);
         }
       /*
         Shift the pixel offset point as defined by the provided,
@@ -1219,11 +1239,11 @@ if (0)
 
     MagickRealType
       blue,
-      luma,
+      chroma,
       green,
       hue,
-      red,
-      chroma;
+      luma,
+      red;
 
     PixelInfo
       canvas_pixel,
@@ -1317,8 +1337,8 @@ if (0)
               Sc: source color.
               Dc: canvas color.
           */
-          (void) GetOneVirtualPixel(source_image,x-x_offset,y-y_offset,
-            source,exception);
+          (void) GetOneVirtualPixel(source_image,x-x_offset,y-y_offset,source,
+            exception);
           if (GetPixelReadMask(image,q) == 0)
             {
               q+=GetPixelChannels(image);
@@ -1369,8 +1389,7 @@ if (0)
               case DissolveCompositeOp:
               {
                 if (channel == AlphaPixelChannel)
-                  pixel=canvas_dissolve*GetPixelAlpha(source_image,
-                    source);
+                  pixel=canvas_dissolve*GetPixelAlpha(source_image,source);
                 else
                   pixel=(MagickRealType) source[channel];
                 break;
@@ -1381,7 +1400,8 @@ if (0)
                 break;
               }
             }
-            q[i]=ClampToQuantum(pixel);
+            q[i]=clamp != MagickFalse ? ClampPixel(pixel) :
+              ClampToQuantum(pixel);
           }
           q+=GetPixelChannels(image);
           continue;
@@ -1439,8 +1459,8 @@ if (0)
         }
         case DissolveCompositeOp:
         {
-          alpha=source_dissolve*Sa*(-canvas_dissolve*Da)+source_dissolve*
-            Sa+canvas_dissolve*Da;
+          alpha=source_dissolve*Sa*(-canvas_dissolve*Da)+source_dissolve*Sa+
+            canvas_dissolve*Da;
           break;
         }
         case DstOverCompositeOp:
@@ -1511,8 +1531,7 @@ if (0)
 
         PixelChannel channel=GetPixelChannelChannel(image,i);
         PixelTrait traits=GetPixelChannelTraits(image,channel);
-        PixelTrait source_traits=GetPixelChannelTraits(source_image,
-          channel);
+        PixelTrait source_traits=GetPixelChannelTraits(source_image,channel);
         if (traits == UndefinedPixelTrait)
           continue;
         if ((source_traits == UndefinedPixelTrait) &&
@@ -1531,7 +1550,7 @@ if (0)
             /*
               Copy channel.
             */
-            q[i]=ClampToQuantum(Sc);
+            q[i]=Sc;
             continue;
           }
         if (channel == AlphaPixelChannel)
@@ -1608,7 +1627,7 @@ if (0)
               }
               case CopyAlphaCompositeOp:
               {
-                if (source_traits == UndefinedPixelTrait)
+                if ((source_traits & BlendPixelTrait) == 0)
                   pixel=GetPixelIntensity(source_image,p);
                 else
                   pixel=QuantumRange*Sa;
@@ -1652,7 +1671,8 @@ if (0)
                 break;
               }
             }
-            q[i]=ClampToQuantum(pixel);
+            q[i]=clamp != MagickFalse ? ClampPixel(pixel) :
+              ClampToQuantum(pixel);
             continue;
           }
         /*
@@ -1668,13 +1688,15 @@ if (0)
           case LightenCompositeOp:
           case ModulusSubtractCompositeOp:
           {
-            gamma=1.0-alpha;
+            gamma=PerceptibleReciprocal(1.0-alpha);
             break;
           }
           default:
+          {          
+            gamma=PerceptibleReciprocal(alpha);
             break;
+          }
         }
-        gamma=PerceptibleReciprocal(alpha);
         pixel=Dc;
         switch (compose)
         {
@@ -1695,8 +1717,6 @@ if (0)
             break;
           }
           case BlurCompositeOp:
-          case DisplaceCompositeOp:
-          case DistortCompositeOp:
           case CopyCompositeOp:
           case ReplaceCompositeOp:
           case SrcCompositeOp:
@@ -1704,6 +1724,12 @@ if (0)
             pixel=QuantumRange*Sca;
             break;
           }
+          case DisplaceCompositeOp:
+          case DistortCompositeOp:
+          {
+            pixel=Sc;
+            break;
+          }
           case BumpmapCompositeOp:
           {
             if (fabs((double) (QuantumRange*Sa-TransparentAlpha)) < MagickEpsilon)
@@ -1767,8 +1793,8 @@ if (0)
                 pixel=Sc;
                 break;
               }
-            CompositeHCL(canvas_pixel.red,canvas_pixel.green,
-              canvas_pixel.blue,&sans,&sans,&luma);
+            CompositeHCL(canvas_pixel.red,canvas_pixel.green,canvas_pixel.blue,
+              &sans,&sans,&luma);
             CompositeHCL(source_pixel.red,source_pixel.green,source_pixel.blue,
               &hue,&chroma,&sans);
             HCLComposite(hue,chroma,luma,&red,&green,&blue);
@@ -1945,8 +1971,8 @@ if (0)
                 pixel=Sc;
                 break;
               }
-            CompositeHCL(canvas_pixel.red,canvas_pixel.green,
-              canvas_pixel.blue,&hue,&chroma,&luma);
+            CompositeHCL(canvas_pixel.red,canvas_pixel.green,canvas_pixel.blue,
+              &hue,&chroma,&luma);
             CompositeHCL(source_pixel.red,source_pixel.green,source_pixel.blue,
               &hue,&sans,&sans);
             HCLComposite(hue,chroma,luma,&red,&green,&blue);
@@ -2025,8 +2051,8 @@ if (0)
                 pixel=Sc;
                 break;
               }
-            CompositeHCL(canvas_pixel.red,canvas_pixel.green,
-              canvas_pixel.blue,&hue,&chroma,&luma);
+            CompositeHCL(canvas_pixel.red,canvas_pixel.green,canvas_pixel.blue,
+              &hue,&chroma,&luma);
             CompositeHCL(source_pixel.red,source_pixel.green,source_pixel.blue,
               &sans,&sans,&luma);
             HCLComposite(hue,chroma,luma,&red,&green,&blue);
@@ -2060,9 +2086,9 @@ if (0)
                Dca' = A*Sca*Dca + B*Sca*Da + C*Dca*Sa + D*Sa*Da + Sca*(1.0-Da) +
                  Dca*(1.0-Sa)
             */
-            pixel=gamma*geometry_info.rho*Sa*Sc*Da*Dc+geometry_info.sigma*
-              Sa*Sc*Da+geometry_info.xi*Da*Dc*Sa+geometry_info.psi*Sa*Da+
-              Sa*Sc*(1.0-Da)+Da*Dc*(1.0-Sa);
+            pixel=gamma*QuantumRange*(geometry_info.rho*Sca*Dca+
+              geometry_info.sigma*Sca*Da+geometry_info.xi*Dca*Sa+
+              geometry_info.psi*Sa*Da+Sca*(1.0-Da)+Dca*(1.0-Sa));
             break;
           }
           case MinusDstCompositeOp:
@@ -2096,8 +2122,8 @@ if (0)
                 pixel=Dc;
                 break;
               }
-            CompositeHCL(canvas_pixel.red,canvas_pixel.green,
-              canvas_pixel.blue,&hue,&chroma,&luma);
+            CompositeHCL(canvas_pixel.red,canvas_pixel.green,canvas_pixel.blue,
+              &hue,&chroma,&luma);
             luma+=(0.01*percent_luma*offset)/midpoint;
             chroma*=0.01*percent_chroma;
             HCLComposite(hue,chroma,luma,&red,&green,&blue);
@@ -2211,8 +2237,8 @@ if (0)
                 pixel=Sc;
                 break;
               }
-            CompositeHCL(canvas_pixel.red,canvas_pixel.green,
-              canvas_pixel.blue,&hue,&chroma,&luma);
+            CompositeHCL(canvas_pixel.red,canvas_pixel.green,canvas_pixel.blue,
+              &hue,&chroma,&luma);
             CompositeHCL(source_pixel.red,source_pixel.green,source_pixel.blue,
               &sans,&chroma,&sans);
             HCLComposite(hue,chroma,luma,&red,&green,&blue);
@@ -2303,7 +2329,7 @@ if (0)
             break;
           }
         }
-        q[i]=ClampPixel(pixel);
+        q[i]=clamp != MagickFalse ? ClampPixel(pixel) : ClampToQuantum(pixel);
       }
       p+=GetPixelChannels(source_image);
       channels=GetPixelChannels(source_image);
@@ -2429,8 +2455,8 @@ MagickExport MagickBooleanType TextureImage(Image *image,const Image *texture,
             MagickBooleanType
               proceed;
 
-            proceed=SetImageProgress(image,TextureImageTag,(MagickOffsetType)
-              y,image->rows);
+            proceed=SetImageProgress(image,TextureImageTag,(MagickOffsetType) y,
+              image->rows);
             if (proceed == MagickFalse)
               status=MagickFalse;
           }