Page 1 of 1

Lost frames after clonning

Posted: 2015-10-05T11:50:08-07:00
by opilarium
I've found some wierd logic in clonning function of image:

Code: Select all

Image *CloneImage(...)
{
...
  if (detach == MagickFalse)
    clone_image->blob=ReferenceBlob(image->blob);
  else
    {
      clone_image->next=NewImageList();
      clone_image->previous=NewImageList();
      clone_image->blob=CloneBlobInfo((BlobInfo *) NULL);
    }
That means if an image has multiple pages they will be lost.
I think it's serious bug.

Re: Lost frames after clonning

Posted: 2015-10-05T15:40:32-07:00
by magick
Images are typically in a list and maintains its position in the list with the next and previous pointers. CloneImage() is behaving properly in that it typically makes a copy that is standalone to remove it from the list (i.e. an orphan), while leaving the original image in the list. You can set the detach parameter to ensure the clone maintains its position in list. Given that, what exactly is the bug you are reporting?

Re: Lost frames after clonning

Posted: 2015-10-06T01:22:32-07:00
by opilarium
I serialize an image using write method.

Code: Select all

// Write image to in-memory BLOB
void Magick::Image::write ( Blob *blob_ )
{
  modifyImage();
As listed above write invokes modifyImage.

Code: Select all

void Magick::Image::modifyImage( void )
{
  ...
  replaceImage( CloneImage( image(),
                            0, // columns
                            0, // rows
                            MagickTrue, // orphan
                            &exceptionInfo) );
  ...
}
If the image has it's copy previous and next pages will be lost.

Code: Select all

Magick::Image img1; // has 2 pages
Magick::Image img2( img1 ); // has 2 pages. img2 has ImageRef of img1

Magick::Blob blob;
img2.write( &blob ); // img2 has been detached and now has 1 page!

Re: Lost frames after clonning

Posted: 2015-10-06T03:55:34-07:00
by dlemstra
Magick::Image is always a single image. Take a look at the code that reads the image.

Code: Select all

void Magick::Image::read(MagickCore::Image *image,
  MagickCore::ExceptionInfo *exceptionInfo)
{
  ...
  // Destroy any extra image frames
  next=image->next;
  image->next=(MagickCore::Image *) NULL;
  next->previous=(MagickCore::Image *) NULL;
  DestroyImageList(next);
}
You should use the readImages method from STL.h if you want to read more than one frame.

Re: Lost frames after clonning

Posted: 2015-10-06T10:59:40-07:00
by opilarium
Magick::Image is always a single image.
Well. Than how does it work with multipage tiff file?

Code: Select all

Magick::Blob blob( buffer.get(), file_size );
img.read( blob );
img has multiple pages.

Re: Lost frames after clonning

Posted: 2015-10-06T12:57:34-07:00
by dlemstra
What do you mean by 'img has multiple pages?'. It will only contain the first page.

Re: Lost frames after clonning

Posted: 2015-10-07T07:02:01-07:00
by opilarium
I mean img has properly working img.next image. But I only have one.

Re: Lost frames after clonning

Posted: 2015-10-07T07:15:36-07:00
by dlemstra
Are you using the latest version of ImageMagick?

Re: Lost frames after clonning

Posted: 2015-10-07T08:46:43-07:00
by opilarium
No. 6.8.3. Is that an issue?

Re: Lost frames after clonning

Posted: 2015-10-07T12:13:40-07:00
by dlemstra
I am asking that because this might be something that was fixed in a later version. The image() property of an img should be NULL.

Code: Select all

Magick::Blob blob( buffer.get(), file_size );
img.read( blob );
if (img.image()->next == NULL) // This should be true...  
A Magick:Image instance should always contain a single image. It should be considered a bug if it contains more then one image.