diff --git a/ChangeLog b/ChangeLog index fc9ff2a6c0..070ec9d825 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,7 @@ 2019-12-18 7.0.9-10 Cristy * Some clang releases do not support _aligned_alloc(). * Support -kmeans command-line option. + * The -layers optimize option requires a fully transparent previous image. 2019-12-07 7.0.9-9 Cristy * Release ImageMagick version 7.0.9-9, GIT revision 16513:8ec82f4:20191215. @@ -21,7 +22,6 @@ https://github.com/ImageMagick/ImageMagick/pull/1798). * Introduce HeapOverflowSanityCheckGetExtent() method (reference https://github.com/ImageMagick/ImageMagick/pull/1798). - * The -layers optimize option requires a fully transparent previous image. 2019-12-01 7.0.9-8 Cristy * Release ImageMagick version 7.0.9-8, GIT revision 16474:0bc0e95:20191207. diff --git a/MagickCore/image.c b/MagickCore/image.c index 105a3998a9..df05aba509 100644 --- a/MagickCore/image.c +++ b/MagickCore/image.c @@ -2433,7 +2433,7 @@ MagickExport MagickBooleanType SetImageBackgroundColor(Image *image, assert(image->signature == MagickCoreSignature); if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) return(MagickFalse); - if ((image->background_color.alpha != OpaqueAlpha) && + if ((image->background_color.alpha_trait != UndefinedPixelTrait) && (image->alpha_trait == UndefinedPixelTrait)) (void) SetImageAlphaChannel(image,OnAlphaChannel,exception); ConformPixelInfo(image,&image->background_color,&background,exception); diff --git a/MagickCore/layer.c b/MagickCore/layer.c index 3e74060c9a..57a9f39e89 100644 --- a/MagickCore/layer.c +++ b/MagickCore/layer.c @@ -268,6 +268,7 @@ MagickExport Image *CoalesceImages(const Image *image,ExceptionInfo *exception) exception); if (coalesce_image == (Image *) NULL) return((Image *) NULL); + coalesce_image->background_color.alpha_trait=BlendPixelTrait; coalesce_image->background_color.alpha=(MagickRealType) TransparentAlpha; (void) SetImageBackgroundColor(coalesce_image,exception); coalesce_image->alpha_trait=next->alpha_trait; @@ -277,6 +278,12 @@ MagickExport Image *CoalesceImages(const Image *image,ExceptionInfo *exception) Coalesce rest of the images. */ dispose_image=CloneImage(coalesce_image,0,0,MagickTrue,exception); + if (dispose_image == (Image *) NULL) + { + coalesce_image=DestroyImage(coalesce_image); + return((Image *) NULL); + } + dispose_image->background_color.alpha_trait=BlendPixelTrait; (void) CompositeImage(coalesce_image,next,CopyCompositeOp,MagickTrue, next->page.x,next->page.y,exception); next=GetNextImageInList(next); @@ -315,6 +322,7 @@ MagickExport Image *CoalesceImages(const Image *image,ExceptionInfo *exception) coalesce_image=DestroyImageList(coalesce_image); return((Image *) NULL); } + dispose_image->background_color.alpha_trait=BlendPixelTrait; } /* Clear the overlaid area of the coalesced bounds for background disposal @@ -328,6 +336,7 @@ MagickExport Image *CoalesceImages(const Image *image,ExceptionInfo *exception) coalesce_image->next->previous=coalesce_image; previous=coalesce_image; coalesce_image=GetNextImageInList(coalesce_image); + coalesce_image->background_color.alpha_trait=BlendPixelTrait; (void) CompositeImage(coalesce_image,next, next->alpha_trait != UndefinedPixelTrait ? OverCompositeOp : CopyCompositeOp, MagickTrue,next->page.x,next->page.y,exception); @@ -405,6 +414,7 @@ MagickExport Image *DisposeImages(const Image *images,ExceptionInfo *exception) dispose_image->page.x=0; dispose_image->page.y=0; dispose_image->dispose=NoneDispose; + dispose_image->background_color.alpha_trait=BlendPixelTrait; dispose_image->background_color.alpha=(MagickRealType) TransparentAlpha; (void) SetImageBackgroundColor(dispose_image,exception); dispose_images=NewImageList(); @@ -423,6 +433,7 @@ MagickExport Image *DisposeImages(const Image *images,ExceptionInfo *exception) dispose_image=DestroyImage(dispose_image); return((Image *) NULL); } + current_image->background_color.alpha_trait=BlendPixelTrait; (void) CompositeImage(current_image,next, next->alpha_trait != UndefinedPixelTrait ? OverCompositeOp : CopyCompositeOp, MagickTrue,next->page.x,next->page.y,exception); @@ -475,6 +486,7 @@ MagickExport Image *DisposeImages(const Image *images,ExceptionInfo *exception) dispose_image=DestroyImage(dispose_image); return((Image *) NULL); } + dispose_image->background_color.alpha_trait=BlendPixelTrait; (void) CloneImageProfiles(dispose,next); (void) CloneImageProperties(dispose,next); (void) CloneImageArtifacts(dispose,next); @@ -784,6 +796,7 @@ MagickExport Image *CompareImagesLayers(const Image *image, bounds=(RectangleInfo *) RelinquishMagickMemory(bounds); return((Image *) NULL); } + image_a->background_color.alpha_trait=BlendPixelTrait; image_a->background_color.alpha=(MagickRealType) TransparentAlpha; (void) SetImageBackgroundColor(image_a,exception); image_a->page=next->page; @@ -805,6 +818,7 @@ MagickExport Image *CompareImagesLayers(const Image *image, bounds=(RectangleInfo *) RelinquishMagickMemory(bounds); return((Image *) NULL); } + image_b->background_color.alpha_trait=BlendPixelTrait; (void) CompositeImage(image_a,next,CopyCompositeOp,MagickTrue,next->page.x, next->page.y,exception); bounds[i]=CompareImagesBounds(image_b,image_a,method,exception); @@ -822,6 +836,7 @@ MagickExport Image *CompareImagesLayers(const Image *image, bounds=(RectangleInfo *) RelinquishMagickMemory(bounds); return((Image *) NULL); } + layers->background_color.alpha_trait=BlendPixelTrait; /* Deconstruct the image sequence. */ @@ -842,6 +857,7 @@ MagickExport Image *CompareImagesLayers(const Image *image, image_a=CloneImage(next,0,0,MagickTrue,exception); if (image_a == (Image *) NULL) break; + image_a->background_color.alpha_trait=BlendPixelTrait; image_b=CropImage(image_a,&bounds[i],exception); image_a=DestroyImage(image_a); if (image_b == (Image *) NULL) @@ -999,7 +1015,6 @@ static Image *OptimizeLayerFrames(const Image *image,const LayerMethod method, prev_image->page.x=0; prev_image->page.y=0; prev_image->dispose=NoneDispose; - prev_image->alpha_trait=BlendPixelTrait; prev_image->background_color.alpha_trait=BlendPixelTrait; prev_image->background_color.alpha=(MagickRealType) TransparentAlpha; (void) SetImageBackgroundColor(prev_image,exception); @@ -1105,6 +1120,7 @@ static Image *OptimizeLayerFrames(const Image *image,const LayerMethod method, prev_image=DestroyImage(prev_image); return((Image *) NULL); } + dup_image->background_color.alpha_trait=BlendPixelTrait; dup_bounds=CompareImagesBounds(dup_image,curr,CompareClearLayer,exception); ClearBounds(dup_image,&dup_bounds,exception); try_bounds=CompareImagesBounds(dup_image,curr,CompareAnyLayer,exception); @@ -1134,6 +1150,7 @@ static Image *OptimizeLayerFrames(const Image *image,const LayerMethod method, dup_image=DestroyImage(dup_image); return((Image *) NULL); } + bgnd_image->background_color.alpha_trait=BlendPixelTrait; bgnd_bounds=bounds[i-1]; /* interum bounds of the previous image */ ClearBounds(bgnd_image,&bgnd_bounds,exception); try_bounds=CompareImagesBounds(bgnd_image,curr,CompareAnyLayer,exception); @@ -1321,8 +1338,7 @@ static Image *OptimizeLayerFrames(const Image *image,const LayerMethod method, prev_image=CloneImage(curr,0,0,MagickTrue,exception); if (prev_image == (Image *) NULL) break; - if (prev_image->alpha_trait == UndefinedPixelTrait) - (void) SetImageAlphaChannel(prev_image,OpaqueAlphaChannel,exception); + prev_image->background_color.alpha_trait=BlendPixelTrait; if ( disposals[i] == DelDispose ) { size_t time = 0; while ( disposals[i] == DelDispose ) { @@ -1502,6 +1518,7 @@ MagickExport void OptimizeImageTransparency(const Image *image, dispose_image=DestroyImage(dispose_image); return; } + current_image->background_color.alpha_trait=BlendPixelTrait; (void) CompositeImage(current_image,next,next->alpha_trait != UndefinedPixelTrait ? OverCompositeOp : CopyCompositeOp,MagickTrue,next->page.x,next->page.y, exception); @@ -1809,29 +1826,32 @@ MagickExport void CompositeLayers(Image *destination, { Image *dest = CloneImage(destination,0,0,MagickTrue,exception); - CompositeCanvas(destination, compose, source, x_offset, y_offset, - exception); - /* copy source image attributes ? */ - if ( source->next != (Image *) NULL ) + if (dest != (Image *) NULL) { - destination->delay = source->delay; - destination->iterations = source->iterations; + dest->background_color.alpha_trait=BlendPixelTrait; + CompositeCanvas(destination, compose, source, x_offset, y_offset, + exception); + /* copy source image attributes ? */ + if ( source->next != (Image *) NULL ) + { + destination->delay=source->delay; + destination->iterations=source->iterations; + } + source=GetNextImageInList(source); + while (source != (Image *) NULL) + { + AppendImageToList(&destination, + CloneImage(dest,0,0,MagickTrue,exception)); + destination->background_color.alpha_trait=BlendPixelTrait; + destination=GetLastImageInList(destination); + CompositeCanvas(destination,compose,source,x_offset,y_offset, + exception); + destination->delay=source->delay; + destination->iterations=source->iterations; + source=GetNextImageInList(source); + } + dest=DestroyImage(dest); } - source=GetNextImageInList(source); - - while ( source != (Image *) NULL ) - { - AppendImageToList(&destination, - CloneImage(dest,0,0,MagickTrue,exception)); - destination=GetLastImageInList(destination); - - CompositeCanvas(destination, compose, source, x_offset, y_offset, - exception); - destination->delay = source->delay; - destination->iterations = source->iterations; - source=GetNextImageInList(source); - } - dest=DestroyImage(dest); } /* @@ -2034,6 +2054,7 @@ MagickExport Image *MergeImageLayers(Image *image,const LayerMethod method, canvas=CloneImage(image,width,height,MagickTrue,exception); if (canvas == (Image *) NULL) return((Image *) NULL); + canvas->background_color.alpha_trait=BlendPixelTrait; (void) SetImageBackgroundColor(canvas,exception); canvas->page=page; canvas->dispose=UndefinedDispose;