gifload, a GIF image loader in pure LuaJIT+FFI

Showcase your libraries, tools and other projects that help your fellow love users.
Post Reply
User avatar
pgimeno
Party member
Posts: 1176
Joined: Sun Oct 18, 2015 2:58 pm

gifload, a GIF image loader in pure LuaJIT+FFI

Post by pgimeno » Mon Aug 01, 2016 3:11 pm

Inspired by this thread, I've decided to create a GIF decoder in pure LuaJIT+FFI.

It comes with a demo .love file that displays a (possibly animated) GIF. The demo is designed to be used from the command line.

Command-line freaks like me may wish to create a fused executable and modify the for loop in the getopts function so that it starts in 1 rather than 2 [Edit: since version 1.0.2, this is now done automatically by reading love.filesystem.isFused()]

The project:

https://notabug.org/pgimeno/gifload

The releases page contains a download of the demo.

I've tested it as much as I could, but if you find any problems, please report them in the issue tracker at https://notabug.org/pgimeno/gifload/issues
Last edited by pgimeno on Thu Jun 07, 2018 4:52 pm, edited 2 times in total.
Thrust II Reloaded - GifLoad for Löve - GSpöt GUI - My NotABug.org repositories
The Microsoft Github repositories I had have been closed after the acquisition announcement and will be removed in the near future.

User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: gifload, a GIF image loader in pure LuaJIT+FFI

Post by airstruck » Mon Aug 01, 2016 4:11 pm

Whoa, you really went for it there! :shock:

Do you plan to include some kind of mid- or high-level API, like some convenience functions to wrap all the stuff that looks like gif.imgs[prevframe*5-1] and gif.imgs[nframe*5-2], or something like DoFrame from the example? The example code in main.lua pretty much made my head spin the whole way through. It seems like a lot of it could be moved off into the library somehow, though.

User avatar
zorg
Party member
Posts: 2323
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: gifload, a GIF image loader in pure LuaJIT+FFI

Post by zorg » Mon Aug 01, 2016 5:22 pm

Exactly what i thought at first, something like a gif:draw() to be used in love.draw (or even lg.draw), but since this is mostly a loader lib, from what i can tell, seems like the users can do whatever they want to with the information it loaded in. :D
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.

User avatar
pgimeno
Party member
Posts: 1176
Joined: Sun Oct 18, 2015 2:58 pm

Re: gifload, a GIF image loader in pure LuaJIT+FFI

Post by pgimeno » Mon Aug 01, 2016 8:07 pm

Yes, it's intended to be a loader library. It's true that the gif.imgs[ ] format is somewhat inconvenient. I'm going to include a method to simplify obtaining the frame data, along the lines of:

Code: Select all

function gif:frame(n)
  n = (n-1) % self.nframes + 1
  return self.imgs[n*5-2], self.imgs[n*5-1], self.imgs[n*5], self.imgs[n*5-3], self.imgs[n*5-4]
end
so you can do:

Code: Select all

  local img, x, y, delay, disposal = gif:frame(n)
I'm also pondering on whether to add a flag to "flatten" the images on load. By that I mean to apply the disposal method to each image, generating the actual frames that can be drawn directly without needing to handle disposal (all frames would have disposal=0).

The problem is that it's going to be slow. I can use canvases and obtain the data with [wiki]Canvas:newImageData[/wiki] (slow), adding another dependency, or I can operate on ImageData directly, having a "hidden" screen to handle certain disposal methods.

It makes the most sense to have the GIF images flattened rather than having to handle disposal, but I'm concerned about performance.
Thrust II Reloaded - GifLoad for Löve - GSpöt GUI - My NotABug.org repositories
The Microsoft Github repositories I had have been closed after the acquisition announcement and will be removed in the near future.

User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: gifload, a GIF image loader in pure LuaJIT+FFI

Post by airstruck » Mon Aug 01, 2016 8:23 pm

I'm definitely in favor of the gif:frame(n) thing, it will improve readability. Even if it's "just" a loader (maybe especially if it's just a loader), I think the accessibility and understandability of the format is important. After all, if getting it into a convenient format weren't important, you could just load the raw data, maybe uncompress it, and call that a GIF loader.
I'm also pondering on whether to add a flag to "flatten" the images on load. By that I mean to apply the disposal method to each image, generating the actual frames that can be drawn directly without needing to handle disposal (all frames would have disposal=0).
What about a separate companion module for drawing gifs in your format? Leave them "un-flat" and have a "gifdraw" module with a few methods that draw things loaded by the "gifload" module. I think ideally your main.lua example could mostly just use those two modules and be pretty simple, to the point where someone who comes across the library because they just want to slap a dancing banana into a cutscene or something will think "hey, this looks easy" instead of fleeing in terror ;)

I'm imagining it looking something like this:

Code: Select all

local GifLoad = require 'gifload'
local GifDraw = require 'gifdraw'

-- GifLoad.read is a wrapper for everything under "Example: loading a GIF file"
-- or maybe it's part of GifDraw so you don't need to require 'gifload' at all in user code.
local bananaGif = GifLoad.read('assets/banana.gif')
local banana = GifDraw(bananaGif)

function love.update (dt)
    banana:update(dt) -- this just lets the GifDraw instance figure out what frame it's on.
end

function love.draw ()
    local x = 400 - bananaGif.width * 0.5 -- or maybe copy width and height to the GifDraw instance
    local y = 300 - bananaGif.height * 0.5
    banana:draw(x, y)
end
All the low-level stuff would still be there, this would just make it more approachable for the most common use cases. GifDraw instances could have more methods for stuff like changing the time scale or resetting the animation.

bobbyjones
Party member
Posts: 683
Joined: Sat Apr 26, 2014 7:46 pm

Re: gifload, a GIF image loader in pure LuaJIT+FFI

Post by bobbyjones » Tue Aug 02, 2016 2:05 pm

Do you have a gif of love playing a gif? Maybe you can use gifcat to record a gif of love playing a gif.

User avatar
pgimeno
Party member
Posts: 1176
Joined: Sun Oct 18, 2015 2:58 pm

Re: gifload, a GIF image loader in pure LuaJIT+FFI

Post by pgimeno » Tue Aug 02, 2016 11:06 pm

airstruck wrote:What about a separate companion module for drawing gifs in your format? Leave them "un-flat" and have a "gifdraw" module with a few methods that draw things loaded by the "gifload" module. I think ideally your main.lua example could mostly just use those two modules and be pretty simple, to the point where someone who comes across the library because they just want to slap a dancing banana into a cutscene or something will think "hey, this looks easy" instead of fleeing in terror ;)
Hm, food for thought.

In my mind, the main uses of this library are (1) an HTML browser, in which case the complications of rendering the GIF pale in comparison to rendering the HTML, and (2) an animation loader for animated sprites, in which case typically the coder will have control over the GIF and will be able to flatten it (e.g. using "Unoptimize" in GIMP), making everything but the images themselves irrelevant. A possible third use would be to load single-frame GIFs for whatever purpose, like in the thread that inspired me. It was not really intended as a video player; that's what LÖVE's Theora support is for.

With these two main use cases in mind, I thought that it would be enough to provide the loader and just in case, the frame information, and let implementers deal with what the timing/disposal issues.

But given that it shouldn't be too time-consuming to create a companion animation rendering library, I might just do that. The only problem is that I already want to move on to other projects... attention span and all that, you know. This project had a bunch of unforeseen hurdles to jump that caused me some burnout.
Thrust II Reloaded - GifLoad for Löve - GSpöt GUI - My NotABug.org repositories
The Microsoft Github repositories I had have been closed after the acquisition announcement and will be removed in the near future.

User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: gifload, a GIF image loader in pure LuaJIT+FFI

Post by airstruck » Wed Aug 03, 2016 1:01 am

Yeah, it's definitely not worth the burnout! I might actually take a crack at it just for fun. You pretty much did all the work already, so I'd just be wrapping that up in another module. If I fork that repo some time this weekend, you'll know why. :)

User avatar
ReFreezed
Citizen
Posts: 53
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: gifload, a GIF image loader in pure LuaJIT+FFI

Post by ReFreezed » Tue Jan 02, 2018 9:23 pm

Thanks for making this! It's been useful in one of my utility programs.
Momento Temporis: Light from the Deep (metroidvania, wip)
Momento Temporis: Arena (multiplayer pvp arena, wip)
Energize! (puzzle, completed!)
"If each mistake being made is a new one, then progress is being made."

User avatar
pgimeno
Party member
Posts: 1176
Joined: Sun Oct 18, 2015 2:58 pm

Re: gifload, a GIF image loader in pure LuaJIT+FFI

Post by pgimeno » Sat Apr 07, 2018 10:53 pm

There's been a minor fix to the demo program, to make the command line work correctly with 11.0 when not fused. The library itself is already compatible with 11.0 and needs no changes.
Thrust II Reloaded - GifLoad for Löve - GSpöt GUI - My NotABug.org repositories
The Microsoft Github repositories I had have been closed after the acquisition announcement and will be removed in the near future.

Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 7 guests