FLIF
FLIF copied to clipboard
Unable to decode animation
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;
}