MagickCore / CloneImage & Animated GIFs

Post any defects you find in the released or beta versions of the ImageMagick software here. Include the ImageMagick version, OS, and any command-line required to reproduce the problem. Got a patch for a bug? Post it here.
Post Reply
tc33
Posts: 40
Joined: 2012-10-21T22:10:21-07:00
Authentication code: 67789

MagickCore / CloneImage & Animated GIFs

Post by tc33 »

Hi,

I can't seem to be able to fully/deep clone an image that contains multiple images (eg animated GIFs). Looking at MagickCore/Image.c/CloneImage, I see that if the 'detach' parameter is true, it simply drops the additional images in the sequence ( clone_image->next=NewImageList(); ). If the 'detach' parameter is false, it provides a reference to the original image's 'next' property ( clone_image->next=image->next; ). If the original image is disposed at a later time, and then the clone image is used/modified, an access exception is generated (or something along those lines...)

Other code which relies on CloneImage, like Magick++ Image.modifyImage() method, results in dropping the sequential images. For example, the following Magick++ code would corrupt an animated gif (not tested):
Magick::Image img("animated.gif");
img.modifyImage();
img.write("animated.2.gif");

Here is my Magick++ workaround, hopefully something like this can be built into the core methods:

Code: Select all

Magick::Image clone_magickimg( const Magick::Image& img )
	{
		MagickCore::ExceptionInfo ex;
		GetExceptionInfo( &ex );
		MagickCore::Image* cpy = CloneImage( img.constImage(), 0, 0, to_magickbool( true ), &ex );
		

		if ( cpy == NULL )
		{
			assert( false );
			DestroyExceptionInfo( &ex );
			return Magick::Image();
		}

		// multi-page/animated gif support
		MagickCore::Image *next = img.constImage()->next,
			*parent = cpy;

		while ( next != NULL )
		{
			parent->next = CloneImage( next, 0, 0, to_magickbool( true ), &ex );

			if ( parent->next == NULL )	// error on clone
			{
				assert( false );
				DestroyImage( cpy );
				DestroyExceptionInfo( &ex );
				return Magick::Image();
			}

			parent = parent->next;
			next = next->next;

		};	// while
		
		DestroyExceptionInfo( &ex );

		return std::move( Magick::Image( cpy ) );
	}	// clone_magickimg
Finally, it would be nice if there was a const-friendly Image.write method; I have to jump through hoops to maintain const-correctness when I use IM -- done via unnecessary cloning

Thanks!
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: MagickCore / CloneImage & Animated GIFs

Post by magick »

Magick++ provides a set of Standard Template Libary (STL ) algorithms for operating across ranges of image frames in a container. See http://www.imagemagick.org/Magick++/STL.html.
tc33
Posts: 40
Joined: 2012-10-21T22:10:21-07:00
Authentication code: 67789

Re: MagickCore / CloneImage & Animated GIFs

Post by tc33 »

Thanks, using the STL wrapper appears to be a more elegant solution for my workaround.

Is the MagickCore CloneImage behavior, as implemented, the intended behavior? Perhaps I'm wrongly assuming that CloneImage should result in a deep clone of the image (including all of the sub-images in the container). Thanks again!
Post Reply