-
Notifications
You must be signed in to change notification settings - Fork 2
/
decode.jl
73 lines (55 loc) · 2.87 KB
/
decode.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
"""
gif_decode(filepath::AbstractString; use_localpalette=false)
Decode the GIF image as colorant matrix. The source data needs to be a filename.
#### Arguments
- `filepath::AbstractString` : Path to the gif file
- `use_localpalette::Bool=false` : While decoding, using this argument use of local colormap or global colormap for a particular slice can be specified. Gif files are palette based and have a global colormap(max `256 colors`) but slices/images in gif can have their own local colormap specific to a particular slice/image.
#### Examples
```jl
julia> using GIFImages, Downloads
julia> path = "test/data/fire.gif"
"test/data/fire.gif"
julia> img = gif_decode(path)
60×30×33 Array{RGB{N0f8},3} with eltype RGB{N0f8}
"""
function gif_decode(filepath::AbstractString; use_localpalette=false)
error1 = Cint(0)
gif = LibGif.DGifOpenFileName(filepath, Ref(error1))
try
gif == C_NULL && error("failed to open the gif file: null pointer")
slurp_return = LibGif.DGifSlurp(gif)
if (slurp_return == LibGif.GIF_ERROR)
error("failed to read .gif file")
end
loaded_gif = unsafe_load(gif)
img_count = loaded_gif.ImageCount
components = unsafe_wrap(Array, loaded_gif.SavedImages, loaded_gif.ImageCount)
# Gif's are palette based and can have upto 256 colors in a image
colormap = unsafe_load(loaded_gif.SColorMap) # global colormap
palette = unsafe_wrap(Array, colormap.Colors, colormap.ColorCount)
final = zeros(RGB{N0f8}, loaded_gif.SHeight, loaded_gif.SWidth, loaded_gif.ImageCount)
# read the images
for i = 1:img_count
img = unsafe_wrap(Array, components[i].RasterBits, loaded_gif.SWidth * loaded_gif.SHeight)
desc = components[i].ImageDesc
@debug "Image $i at [$(desc.Left), $(desc.Top)] and size [$(desc.Width), $(desc.Height)]" * ((desc.ColorMap !=C_NULL) ? " and has a local colormap.\n" : " and doesn't have a local colormap.\n")
# support for using local colormaps
if desc.ColorMap !=C_NULL && use_localpalette == true
localcolormap = unsafe_load(desc.ColorMap)
@debug "Image $i : using Local ColorMap with $(localcolormap.ColorCount) colors."
lpalette = unsafe_wrap(Array, localcolormap.Colors, localcolormap.ColorCount)
colortypes = map(x -> lpalette[x+1], img)
else
colortypes = map(x -> palette[x+1], img)
end
res = map(x -> RGB{N0f8}(x.Red / 255, x.Green / 255, x.Blue / 255), colortypes)
res = reshape(res, Int(loaded_gif.SWidth), Int(loaded_gif.SHeight))
res = res'
final[:, :, i] = res
end
# return the final matrix
return final
finally
LibGif.DGifCloseFile(gif, Ref(error1))
end
end