]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/layer.c
(no commit message)
[imagemagick] / MagickCore / layer.c
index ce9df4008987e35a71e241ec3aea4b9c2fc8c216..4e6ab207fc8b293aa4e9617c704d7fac29cf2fca 100644 (file)
 %                      MagickCore Image Layering Methods                      %
 %                                                                             %
 %                              Software Design                                %
-%                                John Cristy                                  %
+%                                   Cristy                                    %
 %                              Anthony Thyssen                                %
 %                               January 2006                                  %
 %                                                                             %
 %                                                                             %
-%  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  %
@@ -40,6 +40,7 @@
 #include "MagickCore/studio.h"
 #include "MagickCore/artifact.h"
 #include "MagickCore/cache.h"
+#include "MagickCore/channel.h"
 #include "MagickCore/color.h"
 #include "MagickCore/color-private.h"
 #include "MagickCore/composite.h"
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 %  ClearBounds() Clear the area specified by the bounds in an image to
-%  transparency.  This typically used to handle Background Disposal
-%  for the previous frame in an animation sequence.
+%  transparency.  This typically used to handle Background Disposal for the
+%  previous frame in an animation sequence.
 %
-%  WARNING: no bounds checks are performed, except for the null or
-%  missed image, for images that don't change. in all other cases
-%  bound must fall within the image.
+%  Warning: no bounds checks are performed, except for the null or missed
+%  image, for images that don't change. in all other cases bound must fall
+%  within the image.
 %
 %  The format is:
 %
-%      void ClearBounds(Image *image,RectangleInfo *bounds
+%      void ClearBounds(Image *image,RectangleInfo *bounds,
 %        ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
@@ -104,7 +105,7 @@ static void ClearBounds(Image *image,RectangleInfo *bounds,
 
   if (bounds->x < 0)
     return;
-  if (image->matte == MagickFalse)
+  if (image->alpha_trait != BlendPixelTrait)
     (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
   for (y=0; y < (ssize_t) bounds->height; y++)
   {
@@ -143,6 +144,10 @@ static void ClearBounds(Image *image,RectangleInfo *bounds,
 %  to check if a proposed disposal method will work successfully to generate
 %  the second frame image from the first disposed form of the previous frame.
 %
+%  Warning: no bounds checks are performed, except for the null or missed
+%  image, for images that don't change. in all other cases bound must fall
+%  within the image.
+%
 %  The format is:
 %
 %      MagickBooleanType IsBoundsCleared(const Image *image1,
@@ -156,21 +161,17 @@ static void ClearBounds(Image *image,RectangleInfo *bounds,
 %
 %    o exception: return any errors or warnings in this structure.
 %
-%  WARNING: no bounds checks are performed, except for the null or
-%  missed image, for images that don't change. in all other cases
-%  bound must fall within the image.
-%
 */
 static MagickBooleanType IsBoundsCleared(const Image *image1,
   const Image *image2,RectangleInfo *bounds,ExceptionInfo *exception)
 {
-  register ssize_t
-    x;
-
   register const Quantum
     *p,
     *q;
 
+  register ssize_t
+    x;
+
   ssize_t
     y;
 
@@ -178,10 +179,8 @@ static MagickBooleanType IsBoundsCleared(const Image *image1,
     return(MagickFalse);
   for (y=0; y < (ssize_t) bounds->height; y++)
   {
-    p=GetVirtualPixels(image1,bounds->x,bounds->y+y,bounds->width,1,
-      exception);
-    q=GetVirtualPixels(image2,bounds->x,bounds->y+y,bounds->width,1,
-      exception);
+    p=GetVirtualPixels(image1,bounds->x,bounds->y+y,bounds->width,1,exception);
+    q=GetVirtualPixels(image2,bounds->x,bounds->y+y,bounds->width,1,exception);
     if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
       break;
     for (x=0; x < (ssize_t) bounds->width; x++)
@@ -269,9 +268,10 @@ MagickExport Image *CoalesceImages(const Image *image,ExceptionInfo *exception)
     exception);
   if (coalesce_image == (Image *) NULL)
     return((Image *) NULL);
+  (void) SetImageBackgroundColor(coalesce_image,exception);
+  coalesce_image->alpha_trait=next->alpha_trait;
   coalesce_image->page=bounds;
   coalesce_image->dispose=NoneDispose;
-  (void) SetImageBackgroundColor(coalesce_image,exception);
   /*
     Coalesce rest of the images.
   */
@@ -327,9 +327,9 @@ MagickExport Image *CoalesceImages(const Image *image,ExceptionInfo *exception)
     coalesce_image->next->previous=coalesce_image;
     previous=coalesce_image;
     coalesce_image=GetNextImageInList(coalesce_image);
-    (void) CompositeImage(coalesce_image,next,next->matte != MagickFalse ?
-      OverCompositeOp : CopyCompositeOp,MagickTrue,next->page.x,next->page.y,
-      exception);
+    (void) CompositeImage(coalesce_image,next,
+      next->alpha_trait == BlendPixelTrait ? OverCompositeOp : CopyCompositeOp,
+      MagickTrue,next->page.x,next->page.y,exception);
     (void) CloneImageProfiles(coalesce_image,next);
     (void) CloneImageProperties(coalesce_image,next);
     (void) CloneImageArtifacts(coalesce_image,next);
@@ -337,7 +337,7 @@ MagickExport Image *CoalesceImages(const Image *image,ExceptionInfo *exception)
     /*
       If a pixel goes opaque to transparent, use background dispose.
     */
-    if (IsBoundsCleared(previous,coalesce_image,&bounds,exception))
+    if (IsBoundsCleared(previous,coalesce_image,&bounds,exception) != MagickFalse)
       coalesce_image->dispose=BackgroundDispose;
     else
       coalesce_image->dispose=NoneDispose;
@@ -359,8 +359,8 @@ MagickExport Image *CoalesceImages(const Image *image,ExceptionInfo *exception)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 %  DisposeImages() returns the coalesced frames of a GIF animation as it would
-%  appear after the GIF dispose method of that frame has been applied.  That
-%  is it returned the appearance of each frame before the next is overlaid.
+%  appear after the GIF dispose method of that frame has been applied.  That is
+%  it returned the appearance of each frame before the next is overlaid.
 %
 %  The format of the DisposeImages method is:
 %
@@ -379,13 +379,13 @@ MagickExport Image *DisposeImages(const Image *images,ExceptionInfo *exception)
     *dispose_image,
     *dispose_images;
 
+  RectangleInfo
+    bounds;
+
   register Image
     *image,
     *next;
 
-  RectangleInfo
-    bounds;
-
   /*
     Run the image through the animation sequence
   */
@@ -422,9 +422,9 @@ MagickExport Image *DisposeImages(const Image *images,ExceptionInfo *exception)
         dispose_image=DestroyImage(dispose_image);
         return((Image *) NULL);
       }
-    (void) CompositeImage(current_image,next,next->matte != MagickFalse ?
-      OverCompositeOp : CopyCompositeOp,MagickTrue,next->page.x,next->page.y,
-      exception);
+    (void) CompositeImage(current_image,next,
+      next->alpha_trait == BlendPixelTrait ? OverCompositeOp : CopyCompositeOp,
+      MagickTrue,next->page.x,next->page.y,exception);
     /*
       Handle Background dispose: image is displayed for the delay period.
     */
@@ -458,7 +458,7 @@ MagickExport Image *DisposeImages(const Image *images,ExceptionInfo *exception)
       {
         dispose_image=DestroyImage(dispose_image);
         dispose_image=current_image;
-        current_image=(Image *)NULL;
+        current_image=(Image *) NULL;
       }
     /*
       Save the dispose image just calculated for return.
@@ -506,7 +506,7 @@ MagickExport Image *DisposeImages(const Image *images,ExceptionInfo *exception)
 %
 %  The format of the ComparePixels method is:
 %
-%      MagickBooleanType *ComparePixels(const ImageLayerMethod method,
+%      MagickBooleanType *ComparePixels(const LayerMethod method,
 %        const PixelInfo *p,const PixelInfo *q)
 %
 %  A description of each parameter follows:
@@ -518,10 +518,10 @@ MagickExport Image *DisposeImages(const Image *images,ExceptionInfo *exception)
 %
 */
 
-static MagickBooleanType ComparePixels(const ImageLayerMethod method,
+static MagickBooleanType ComparePixels(const LayerMethod method,
   const PixelInfo *p,const PixelInfo *q)
 {
-  MagickRealType
+  double
     o1,
     o2;
 
@@ -531,22 +531,20 @@ static MagickBooleanType ComparePixels(const ImageLayerMethod method,
   if (method == CompareAnyLayer)
     return((MagickBooleanType)(IsFuzzyEquivalencePixelInfo(p,q) == MagickFalse));
 
-  o1 = (p->matte != MagickFalse) ? p->alpha : OpaqueAlpha;
-  o2 = (q->matte != MagickFalse) ? q->alpha : OpaqueAlpha;
-
+  o1 = (p->alpha_trait == BlendPixelTrait) ? p->alpha : OpaqueAlpha;
+  o2 = (q->alpha_trait == BlendPixelTrait) ? q->alpha : OpaqueAlpha;
   /*
-    Pixel goes from opaque to transprency
+    Pixel goes from opaque to transprency.
   */
   if (method == CompareClearLayer)
-    return((MagickBooleanType) ( (o1 <= ((MagickRealType) QuantumRange/2.0)) &&
-      (o2 > ((MagickRealType) QuantumRange/2.0)) ) );
-
+    return((MagickBooleanType) ( (o1 <= ((double) QuantumRange/2.0)) &&
+      (o2 > ((double) QuantumRange/2.0)) ) );
   /*
-    overlay would change first pixel by second
+    Overlay would change first pixel by second.
   */
   if (method == CompareOverlayLayer)
     {
-      if (o2 > ((MagickRealType) QuantumRange/2.0))
+      if (o2 > ((double) QuantumRange/2.0))
         return MagickFalse;
       return((MagickBooleanType) (IsFuzzyEquivalencePixelInfo(p,q) == MagickFalse));
     }
@@ -574,7 +572,7 @@ static MagickBooleanType ComparePixels(const ImageLayerMethod method,
 %
 %  The format of the CompareImagesBounds method is:
 %
-%      RectangleInfo *CompareImagesBounds(const ImageLayerMethod method,
+%      RectangleInfo *CompareImagesBounds(const LayerMethod method,
 %        const Image *image1, const Image *image2, ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
@@ -588,8 +586,8 @@ static MagickBooleanType ComparePixels(const ImageLayerMethod method,
 %
 */
 
-static RectangleInfo CompareImagesBounds(const Image *image1,const Image *image2,
-  const ImageLayerMethod method,ExceptionInfo *exception)
+static RectangleInfo CompareImagesBounds(const Image *image1,
+  const Image *image2,const LayerMethod method,ExceptionInfo *exception)
 {
   RectangleInfo
     bounds;
@@ -720,7 +718,7 @@ static RectangleInfo CompareImagesBounds(const Image *image1,const Image *image2
 %
 %  CompareImagesLayers() compares each image with the next in a sequence and
 %  returns the minimum bounding region of all the pixel differences (of the
-%  ImageLayerMethod specified) it discovers.
+%  LayerMethod specified) it discovers.
 %
 %  Images do NOT have to be the same size, though it is best that all the
 %  images are 'coalesced' (images are all the same size, on a flattened
@@ -732,7 +730,7 @@ static RectangleInfo CompareImagesBounds(const Image *image1,const Image *image2
 %  The format of the CompareImagesLayers method is:
 %
 %      Image *CompareImagesLayers(const Image *images,
-%        const ImageLayerMethod method,ExceptionInfo *exception)
+%        const LayerMethod method,ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
@@ -746,7 +744,7 @@ static RectangleInfo CompareImagesBounds(const Image *image1,const Image *image2
 */
 
 MagickExport Image *CompareImagesLayers(const Image *image,
-  const ImageLayerMethod method, ExceptionInfo *exception)
+  const LayerMethod method, ExceptionInfo *exception)
 {
   Image
     *image_a,
@@ -813,7 +811,6 @@ MagickExport Image *CompareImagesLayers(const Image *image,
     (void) CompositeImage(image_a,next,CopyCompositeOp,MagickTrue,next->page.x,
       next->page.y,exception);
     bounds[i]=CompareImagesBounds(image_b,image_a,method,exception);
-
     image_b=DestroyImage(image_b);
     i++;
   }
@@ -877,7 +874,7 @@ MagickExport Image *CompareImagesLayers(const Image *image,
 %  The format of the OptimizeLayerFrames method is:
 %
 %      Image *OptimizeLayerFrames(const Image *image,
-%        const ImageLayerMethod method, ExceptionInfo *exception)
+%        const LayerMethod method, ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
@@ -906,7 +903,7 @@ MagickExport Image *CompareImagesLayers(const Image *image,
 #define DEBUG_OPT_FRAME 0
 
 static Image *OptimizeLayerFrames(const Image *image,
-  const ImageLayerMethod method, ExceptionInfo *exception)
+  const LayerMethod method, ExceptionInfo *exception)
 {
   ExceptionInfo
     *sans_exception;
@@ -946,13 +943,12 @@ static Image *OptimizeLayerFrames(const Image *image,
   assert(method == OptimizeLayer ||
          method == OptimizeImageLayer ||
          method == OptimizePlusLayer);
-
   /*
-    Are we allowed to add/remove frames from animation
+    Are we allowed to add/remove frames from animation?
   */
   add_frames=method == OptimizePlusLayer ? MagickTrue : MagickFalse;
   /*
-    Ensure  all the images are the same size
+    Ensure  all the images are the same size.
   */
   curr=GetFirstImageInList(image);
   for (; curr != (Image *) NULL; curr=GetNextImageInList(curr))
@@ -1498,7 +1494,7 @@ MagickExport void OptimizeImageTransparency(const Image *image,
         dispose_image=DestroyImage(dispose_image);
         return;
       }
-    (void) CompositeImage(current_image,next,next->matte != MagickFalse ?
+    (void) CompositeImage(current_image,next,next->alpha_trait == BlendPixelTrait ?
       OverCompositeOp : CopyCompositeOp,MagickTrue,next->page.x,next->page.y,
       exception);
     /*
@@ -1851,7 +1847,7 @@ MagickExport void CompositeLayers(Image *destination,
 %  MergeImageLayers() composes all the image layers from the current given
 %  image onward to produce a single image of the merged layers.
 %
-%  The inital canvas's size depends on the given ImageLayerMethod, and is
+%  The inital canvas's size depends on the given LayerMethod, and is
 %  initialized using the first images background color.  The images
 %  are then compositied onto that image in sequence using the given
 %  composition that has been assigned to each individual image.
@@ -1859,7 +1855,7 @@ MagickExport void CompositeLayers(Image *destination,
 %  The format of the MergeImageLayers is:
 %
 %      Image *MergeImageLayers(const Image *image,
-%        const ImageLayerMethod method, ExceptionInfo *exception)
+%        const LayerMethod method, ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
@@ -1890,7 +1886,7 @@ MagickExport void CompositeLayers(Image *destination,
 %    o exception: return any errors or warnings in this structure.
 %
 */
-MagickExport Image *MergeImageLayers(Image *image,const ImageLayerMethod method,
+MagickExport Image *MergeImageLayers(Image *image,const LayerMethod method,
   ExceptionInfo *exception)
 {
 #define MergeLayersTag  "Merge/Layers"
@@ -2032,7 +2028,7 @@ MagickExport Image *MergeImageLayers(Image *image,const ImageLayerMethod method,
   number_images=GetImageListLength(image);
   for (scene=0; scene < (ssize_t) number_images; scene++)
   {
-    (void) CompositeImage(canvas,image,image->compose,MagicTrue,image->page.x-
+    (void) CompositeImage(canvas,image,image->compose,MagickTrue,image->page.x-
       canvas->page.x,image->page.y-canvas->page.y,exception);
     proceed=SetImageProgress(image,MergeLayersTag,(MagickOffsetType) scene,
       number_images);