Skip to content

Commit

Permalink
Adds Pic.openGIFDocumentFromData() (#657)
Browse files Browse the repository at this point in the history
This will allow using giflib to render GIF images, which
is better than MuPDF for rendering the first frame of an
animated GIF, and will allow getting all its frames.
Also fix alpha value when combining animated GIF frames.
  • Loading branch information
poire-z authored and Frenzie committed Apr 22, 2018
1 parent b7f30fb commit f741453
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
2 changes: 2 additions & 0 deletions ffi/giflib_h.lua
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,6 @@ static const int DISPOSE_DO_NOT = 1;
static const int DISPOSE_BACKGROUND = 2;
static const int DISPOSE_PREVIOUS = 3;
static const int NO_TRANSPARENT_COLOR = -1;
typedef int (*GifInputFunc) (GifFileType *, GifByteType *, int);
GifFileType *DGifOpen(void *, GifInputFunc, int *);
]]
33 changes: 32 additions & 1 deletion ffi/pic.lua
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ function GifDocument:openPage(number)
local palette={}
for c=0, cmap.ColorCount-1 do
local color = cmap.Colors[c]
palette[c] = BB.ColorRGB32(color.Red, color.Green, color.Blue, 0)
palette[c] = BB.ColorRGB32(color.Red, color.Green, color.Blue, 0xFF)
end

-- Draw current frame on our bb
Expand Down Expand Up @@ -221,6 +221,37 @@ function Pic.openGIFDocument(filename)
return GifDocument:new{giffile = giffile}
end

function Pic.openGIFDocumentFromData(data, size)
-- Create GIF from data pointer (from https://github.com/luapower/giflib)
local function data_reader(r_data, r_size)
r_data = ffi.cast('unsigned char*', r_data)
return function(_, buf, sz)
if sz < 1 or r_size < 1 then error('eof') end
sz = math.min(r_size, sz)
ffi.copy(buf, r_data, sz)
r_data = r_data + sz
r_size = r_size - sz
return sz
end
end
local read_cb = ffi.cast('GifInputFunc', data_reader(data, size))
local err = ffi.new("int[1]")
local giffile = giflib.DGifOpen(nil, read_cb, err)
if giffile == nil then
read_cb:free()
error(string.format("Cannot read GIF file: %s",
ffi.string(giflib.GifErrorString(err[0]))))
end
if giflib.DGifSlurp(giffile) ~= giflib.GIF_OK then
giflib.DGifCloseFile(giffile, err)
read_cb:free()
error(string.format("Cannot parse GIF file: %s",
ffi.string(giflib.GifErrorString(giffile.Error))))
end
read_cb:free()
return GifDocument:new{giffile = giffile}
end

function Pic.openPNGDocument(filename)
local ok, re = Png.decodeFromFile(filename)
if not ok then error(re) end
Expand Down

0 comments on commit f741453

Please sign in to comment.