FLIF-hub / FLIF

Free Lossless Image Format
Other
3.72k stars 229 forks source link

Unable to decode animation #471

Open lixo6500 opened 7 years ago

lixo6500 commented 7 years ago

The library fails to decode the animations it creates. The call to flif_decoder_decode_memory fails, and the culprit seems to be this check on unique_frames that happens here:

flif-dec.cpp, function flif_decode<>, around line 1230

if (desc == "Frame_Shape") {
    if (images.size()<2) 
        return false;
    int unique_frames=images.size()-1; // not considering first frame
    for (Image& i : images)
        if (i.seen_before >= 0) 
            unique_frames--;
    if (unique_frames < 1) {
        return false;
    }
    trans->configure(unique_frames*images[0].rows()); 
    trans->configure(images[0].cols()); 
}

For some reason the library requires the number of unique_frames to be >= 1, which, for some reason, it is not on my 3 frame animation.

I have attached a full working reproduction of the bug.

Here is is the code I used to generate the animation

bool EncodeAnimation(std::vector<uint8_t>* stream)
{
    using EncoderUPtr = std::unique_ptr<FLIF_ENCODER, void(*)(FLIF_ENCODER*)>;

    using ImageUPtr = std::unique_ptr<FLIF_IMAGE, void(*)(FLIF_IMAGE*)>;

    EncoderUPtr encoder( flif_create_encoder(), flif_destroy_encoder );

    const size_t width = 5;
    const size_t height = 5;

    uint32_t buffer[width];

    for(size_t x=0; x<width; ++x)
    {
        buffer[x] = 0xFFFF0000;
    }

    for(size_t frame=0; frame<3; ++frame)
    {
        ImageUPtr image(flif_create_image(width, height), flif_destroy_image);

        for(size_t y=0; y<height; ++y)
        {   
            flif_image_write_row_RGBA8(image.get(), y, buffer, sizeof(buffer));
        }

        flif_image_set_frame_delay(image.get(), 500);

        flif_encoder_add_image_move(encoder.get(), image.get());
        image.release();
    }

    void* encodedData;
    size_t encodedDataSize;
    if(flif_encoder_encode_memory(encoder.get(), &encodedData, &encodedDataSize))
    {
        const uint8_t* encodedData8 = (const uint8_t*)encodedData;
        stream->insert(stream->end(), encodedData8, encodedData8 + encodedDataSize);

        delete[] encodedData;

        return true;
    }

    return false;
}

And the code to decode

bool Decode(std::vector<uint8_t>& stream)
{
    using DecoderUPtr = std::unique_ptr<FLIF_DECODER, void(*)(FLIF_DECODER*)>;

    DecoderUPtr decoder( flif_create_decoder(), flif_destroy_decoder );

    if(!flif_decoder_decode_memory(decoder.get(), stream.data(), stream.size()))
        return false;

    return true;

}

AnimationDecodeError.zip