imagemagickmagick++

Why does getConstPixels() from Magick::Image return nullptr?


I use the following code to convert Magick::Image to QImage:

QImage
convert( const Magick::Image & img )
{
    QImage qimg( static_cast< int > ( img.columns() ),
        static_cast< int > ( img.rows() ), QImage::Format_RGB888 );
    const Magick::PixelPacket * pixels;
    Magick::ColorRGB rgb;

    for( int y = 0; y < qimg.height(); ++y)
    {
        pixels = img.getConstPixels( 0, y, static_cast< std::size_t > ( qimg.width() ), 1 );

        for( int x = 0; x < qimg.width(); ++x )
        {
            rgb = ( *( pixels + x ) );

            qimg.setPixel( x, y, QColor( static_cast< int> ( 255 * rgb.red() ),
                static_cast< int > ( 255 * rgb.green() ),
                static_cast< int > ( 255 * rgb.blue() ) ).rgb());
        }
    }

    return qimg;
}

This code works, but with one test image with 8000x6000 resolution I've got nullptr at the first line of Magick::Image. img.getConstPixels( 0, 0, 8000, 1 ) just returns nullptr. How can it be possible? Maybe do I do something wrong here? Thanks.

ImageMagick version is 6.9.11.60 on Kubuntu 22.04.

I actually open GIF with Magick::readImages( ... ), then Magick::coalesceImages(), and then convert each frame of the GIF into QImage. I downloaded test GIF, that brokes ImageMagick, and this GIF is here.

Reproducible example:

#include <Magick++.h>

#include <QImage>
#include <QDebug>


int main()
{
    Magick::InitializeMagick( nullptr );

    std::vector< Magick::Image > imgs;

    Magick::readImages( &imgs, "sample-gif-file-for-Testing.gif" );

    std::vector< Magick::Image > cimgs;

    Magick::coalesceImages( &cimgs, imgs.begin(), imgs.end() );

    int i = 0;

    for( auto it = cimgs.cbegin(), last = cimgs.cend(); it != last; ++it )
    {
        qDebug() << QString( "frame #%1" ).arg( i );

        QImage qimg( static_cast< int > ( it->columns() ),
            static_cast< int > ( it->rows() ), QImage::Format_RGB888 );
        const Magick::PixelPacket * pixels;
        Magick::ColorRGB rgb;

        for( int y = 0; y < qimg.height(); ++y)
        {
            pixels = it->getConstPixels( 0, y, static_cast< std::size_t > ( qimg.width() ), 1 );

            qDebug() << QString( "pixels from line %1" ).arg( y ) << pixels;

            for( int x = 0; x < qimg.width(); ++x )
            {
                rgb = ( *( pixels + x ) );

                qimg.setPixel( x, y, QColor( static_cast< int> ( 255 * rgb.red() ),
                    static_cast< int > ( 255 * rgb.green() ),
                    static_cast< int > ( 255 * rgb.blue() ) ).rgb());
            }
        }

        ++i;
    }

    return 0;
}

Solution

  • The problem is that if GIF image has one frame, then

    Magick::coalesceImages( &cimgs, imgs.begin(), imgs.end() );
    

    can break that frame, so do coalesceImages() only if imgs.size() > 1.