Animated GIFs again?

I keep having an ongoing desire to display animated GIFs - but it is interesting how many libraries do not support them. Right now, my best animated GIF player actually runs in Javascript (here) but of course I can’t integrate that into Juce.

JUCE itself only looks at the first frame - Jules (very reasonably) opted to do that and concentrate his efforts on more generally useful things.

Does anyone have a solution for animated GIF decoding and playback that works in JUCE?

1 Like

Yearly up ;)

can we bring this topic back up please? I also want to extract the individual frames from gif files and put it into a vectorjuce::Image or a vectorjuce::ImageCache

my method currently looks like this:

typedef juce::File::SpecialLocationType Loc;
    auto title = "load a JIF-File, bro";
    juce::FileChooser fileChooser(title,
        juce::File::getSpecialLocation(Loc::userDocumentsDirectory), "*.gif", true, true, nullptr);

    if (fileChooser.browseForFileToOpen()) {
        auto file = fileChooser.getResult();
        
        gifImage = juce::GIFImageFormat::loadFrom(file);
    }

gifImage is a juce::Image object. ofc that won’t give me an animation since it’s just one image, but loadFrom(file) doesn’t ask for an index or something, it just loads. So i suppose if i wanted to get all frames I’d have to find out how juce::File works when loading a gif and override something to make it give back a vector of images instead of just one image or so?

I just tried what happens when I manually read the input stream and i get the following output:

GIF89aa

with this code:

auto stream = file.createInputStream();
        if (stream->openedOk()) {
            juce::String test;
            while(true) {
                auto byte = stream->readByte();
                if (byte == 0)
                    break;
                test += byte;
            }
            DBG(test);
        }

i guess i must have misunderstood something. i expected the input stream to resemble all the data from the gif file

The file probably contains a zero byte close the beginning and you then can’t examine it further as a string. (Since strings are traditionally zero terminated.)

the method “readByte” says “if the stream is exhausted it will return 0” which made me think that 0 must be the break condition.

now i tried this instead:

auto stream = file.createInputStream();
        if (stream->openedOk()) {
            juce::String test;
            for(auto i = 0; i < file.getSize(); ++i){
                auto byte = stream->readByte();
                test += byte;
            }
            DBG(test);
        }

and the programm hang itself saying some “RPC-Server is not available”.

same happens when i try this:

juce::MemoryBlock memoryBlock;
        file.loadFileAsData(memoryBlock);
        
        juce::String test;
        for (auto i = 0; i < memoryBlock.getSize(); ++i) {
            test += memoryBlock[i];
        }
        DBG(test);

EDIT:
now instead of saving all bytes to String test I directly put the DBG() into the loop and noticed that it indeed spits out all the individual little pieces of data… whatever they mean. so if i’m correct then I could learn what it means now and interpret it in a way that will give me the individual images, right? can anyone confirm if this is a good idea or not? because i actually only need this whole gif-stuff for a very small fun idea. if it’s too time consuming to get it running i’d probably wait for the actual juce team to add proper gif support

edit 2:
ok seems to have been a bad idea. apparently a gif file is not just a bunch of pixel information but also encoded in some clever way so i’d have to dive really deep to figure it out now, which i don’t have the time for unfortunately. however i could imagine that the juce-implementation is already pretty close to what would actually be needed here. i mean it already gets the first frame. if i was so far, i would totally finish it :> :wink: