Mercurial > mplayer.hg
annotate libmpdemux/demux_gif.c @ 37160:bb15cab6c059
Add ZLIB_CONST to make the zlib API const-correct.
author | reimar |
---|---|
date | Sat, 23 Aug 2014 13:59:32 +0000 |
parents | 92dd1764392a |
children |
rev | line source |
---|---|
9133 | 1 /* |
29238
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
2 * GIF file parser |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
3 * Copyright (C) 2003 Joey Parrish |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
4 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
5 * This file is part of MPlayer. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
6 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
7 * MPlayer is free software; you can redistribute it and/or modify |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
8 * it under the terms of the GNU General Public License as published by |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
9 * the Free Software Foundation; either version 2 of the License, or |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
10 * (at your option) any later version. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
11 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
12 * MPlayer is distributed in the hope that it will be useful, |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
15 * GNU General Public License for more details. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
16 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
17 * You should have received a copy of the GNU General Public License along |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
18 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27385
diff
changeset
|
20 */ |
9133 | 21 |
22 #include <stdio.h> | |
23 #include <stdlib.h> | |
24 #include <unistd.h> | |
25 | |
26 #include "config.h" | |
27 | |
28 #include "mp_msg.h" | |
29 #include "help_mp.h" | |
30 | |
22605
4d81dbdf46b9
Add explicit location for headers from the stream/ directory.
diego
parents:
22377
diff
changeset
|
31 #include "stream/stream.h" |
9133 | 32 #include "demuxer.h" |
33 #include "stheader.h" | |
34 | |
35 #include <gif_lib.h> | |
21885 | 36 #include "libvo/fastmemcpy.h" |
21880
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
37 typedef struct { |
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
38 int current_pts; |
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
39 unsigned char *palette; |
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
40 GifFileType *gif; |
21882
68ebac1f2b8d
Fix crash for gif images that have Top or Left set
reimar
parents:
21881
diff
changeset
|
41 int w, h; |
21891 | 42 int useref; |
21921 | 43 uint8_t *refimg; |
21880
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
44 } gif_priv_t; |
9133 | 45 |
46 #define GIF_SIGNATURE (('G' << 16) | ('I' << 8) | 'F') | |
47 | |
36271 | 48 #if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 |
49 #define DGifOpen(a, b) DGifOpen(a, b, NULL) | |
50 #define DGifOpenFileHandle(a) DGifOpenFileHandle(a, NULL) | |
51 #define GifError() (gif ? gif->Error : 0) | |
52 #define GifErrorString() GifErrorString(gif->Error) | |
53 #endif | |
54 | |
55 /* >= 4.2 prior GIFLIB did not have MAJOR/MINOR defines */ | |
56 #if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 4 | |
57 static void print_gif_error(GifFileType *gif) | |
58 { | |
59 int err = GifError(); | |
60 char *err_str = GifErrorString(); | |
61 | |
62 if (err_str) | |
63 mp_msg(MSGT_DEMUX, MSGL_ERR, "\n[gif] GIF-LIB error: %s.\n", err_str); | |
64 else | |
65 mp_msg(MSGT_DEMUX, MSGL_ERR, "\n[gif] GIF-LIB undefined error %d.\n", err); | |
66 } | |
67 #else | |
68 static void print_gif_error(GifFileType *gif) | |
69 { | |
70 PrintGifError(); | |
71 } | |
72 #endif | |
73 | |
27385
2113bd9c6bd9
Rename preprocessor directives related to image libraries.
diego
parents:
25707
diff
changeset
|
74 #ifndef CONFIG_GIF_TVT_HACK |
9463
93375ee56629
gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents:
9345
diff
changeset
|
75 // not supported by certain versions of the library |
30570
98dc6ae7ede2
libmpdemux: Mark functions not used outside of their files as static.
diego
parents:
29263
diff
changeset
|
76 static int my_read_gif(GifFileType *gif, uint8_t *buf, int len) |
98dc6ae7ede2
libmpdemux: Mark functions not used outside of their files as static.
diego
parents:
29263
diff
changeset
|
77 { |
9344
bd7b5078475e
1) codecs.conf changed recently and demux_gif no longer needs to spit
arpi
parents:
9133
diff
changeset
|
78 return stream_read(gif->UserData, buf, len); |
bd7b5078475e
1) codecs.conf changed recently and demux_gif no longer needs to spit
arpi
parents:
9133
diff
changeset
|
79 } |
9463
93375ee56629
gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents:
9345
diff
changeset
|
80 #endif |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
81 |
16175 | 82 static int gif_check_file(demuxer_t *demuxer) |
9133 | 83 { |
84 if (stream_read_int24(demuxer->stream) == GIF_SIGNATURE) | |
16175 | 85 return DEMUXER_TYPE_GIF; |
9133 | 86 return 0; |
87 } | |
88 | |
21920
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
89 static void memcpy_transp_pic(uint8_t *dst, uint8_t *src, int w, int h, |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
90 int dstride, int sstride, int transp, uint8_t trans_col) { |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
91 if (transp) { |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
92 dstride -= w; |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
93 sstride -= w; |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
94 while (h-- > 0) { |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
95 int wleft = w; |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
96 while (wleft-- > 0) { |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
97 if (*src != trans_col) |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
98 *dst = *src; |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
99 dst++; src++; |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
100 } |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
101 dst += dstride; |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
102 src += sstride; |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
103 } |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
104 } else |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
105 memcpy_pic(dst, src, w, h, dstride, sstride); |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
106 } |
65b2a9b3bd35
"Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents:
21896
diff
changeset
|
107 |
16175 | 108 static int demux_gif_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) |
9133 | 109 { |
21880
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
110 gif_priv_t *priv = demuxer->priv; |
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
111 GifFileType *gif = priv->gif; |
9133 | 112 GifRecordType type = UNDEFINED_RECORD_TYPE; |
113 int len = 0; | |
114 demux_packet_t *dp = NULL; | |
115 ColorMapObject *effective_map = NULL; | |
21921 | 116 uint8_t *buf = NULL; |
21891 | 117 int refmode = 0; |
21895 | 118 int transparency = 0; |
119 uint8_t transparent_col; | |
9133 | 120 |
121 while (type != IMAGE_DESC_RECORD_TYPE) { | |
122 if (DGifGetRecordType(gif, &type) == GIF_ERROR) { | |
36271 | 123 print_gif_error(priv->gif); |
9133 | 124 return 0; // oops |
125 } | |
126 if (type == TERMINATE_RECORD_TYPE) | |
127 return 0; // eof | |
128 if (type == SCREEN_DESC_RECORD_TYPE) { | |
129 if (DGifGetScreenDesc(gif) == GIF_ERROR) { | |
36271 | 130 print_gif_error(priv->gif); |
9133 | 131 return 0; // oops |
132 } | |
133 } | |
134 if (type == EXTENSION_RECORD_TYPE) { | |
135 int code; | |
136 unsigned char *p = NULL; | |
137 if (DGifGetExtension(gif, &code, &p) == GIF_ERROR) { | |
36271 | 138 print_gif_error(priv->gif); |
9133 | 139 return 0; // oops |
140 } | |
141 if (code == 0xF9) { | |
142 int frametime = 0; | |
143 if (p[0] == 4) // is the length correct? | |
21891 | 144 { |
21895 | 145 transparency = p[1] & 1; |
21896 | 146 refmode = (p[1] >> 2) & 3; |
22020
a40f222a31df
Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents:
22019
diff
changeset
|
147 // HACK: specification says |
a40f222a31df
Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents:
22019
diff
changeset
|
148 // > 0 - No disposal specified. The decoder is not required to take any action. |
a40f222a31df
Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents:
22019
diff
changeset
|
149 // but browsers treat it the same way as |
a40f222a31df
Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents:
22019
diff
changeset
|
150 // > 1 - Do not dispose. The graphic is to be left in place. |
a40f222a31df
Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents:
22019
diff
changeset
|
151 // Some broken files rely on this, e.g. |
a40f222a31df
Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents:
22019
diff
changeset
|
152 // http://samples.mplayerhq.hu/GIF/broken-gif/CLAIRE.GIF |
a40f222a31df
Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents:
22019
diff
changeset
|
153 if (refmode == 0) refmode = 1; |
21875
d81cf0be50f0
Frametime was being read from the wrong offset, compare
diego
parents:
18958
diff
changeset
|
154 frametime = (p[3] << 8) | p[2]; // set the time, centiseconds |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
155 transparent_col = p[4]; |
21891 | 156 } |
21880
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
157 priv->current_pts += frametime; |
9133 | 158 } else if ((code == 0xFE) && (verbose)) { // comment extension |
159 // print iff verbose | |
160 printf("GIF comment: "); | |
161 while (p != NULL) { | |
162 int length = p[0]; | |
163 char *comments = p + 1; | |
164 comments[length] = 0; | |
165 printf("%s", comments); | |
166 if (DGifGetExtensionNext(gif, &p) == GIF_ERROR) { | |
36271 | 167 print_gif_error(priv->gif); |
9133 | 168 return 0; // oops |
169 } | |
170 } | |
171 printf("\n"); | |
172 } | |
173 while (p != NULL) { | |
174 if (DGifGetExtensionNext(gif, &p) == GIF_ERROR) { | |
36271 | 175 print_gif_error(priv->gif); |
9133 | 176 return 0; // oops |
177 } | |
178 } | |
179 } | |
180 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
181 |
9133 | 182 if (DGifGetImageDesc(gif) == GIF_ERROR) { |
36271 | 183 print_gif_error(priv->gif); |
9133 | 184 return 0; // oops |
185 } | |
186 | |
187 len = gif->Image.Width * gif->Image.Height; | |
21882
68ebac1f2b8d
Fix crash for gif images that have Top or Left set
reimar
parents:
21881
diff
changeset
|
188 dp = new_demux_packet(priv->w * priv->h); |
21890 | 189 buf = calloc(gif->Image.Width, gif->Image.Height); |
21891 | 190 if (priv->useref) |
23457
a124f3abc1ec
Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents:
22605
diff
changeset
|
191 fast_memcpy(dp->buffer, priv->refimg, priv->w * priv->h); |
21891 | 192 else |
193 memset(dp->buffer, gif->SBackGroundColor, priv->w * priv->h); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
194 |
9133 | 195 if (DGifGetLine(gif, buf, len) == GIF_ERROR) { |
36271 | 196 print_gif_error(priv->gif); |
32614 | 197 free(buf); |
35346 | 198 free_demux_packet(dp); |
9133 | 199 return 0; // oops |
200 } | |
201 | |
202 effective_map = gif->Image.ColorMap; | |
203 if (effective_map == NULL) effective_map = gif->SColorMap; | |
204 | |
205 { | |
206 int y; | |
21883 | 207 int cnt = FFMIN(effective_map->ColorCount, 256); |
22377
fd54975f9135
Use libavutil's av_clip* instead of unreadable MIN/MAX chaos.
reimar
parents:
22024
diff
changeset
|
208 int l = av_clip(gif->Image.Left, 0, priv->w); |
fd54975f9135
Use libavutil's av_clip* instead of unreadable MIN/MAX chaos.
reimar
parents:
22024
diff
changeset
|
209 int t = av_clip(gif->Image.Top, 0, priv->h); |
fd54975f9135
Use libavutil's av_clip* instead of unreadable MIN/MAX chaos.
reimar
parents:
22024
diff
changeset
|
210 int w = av_clip(gif->Image.Width, 0, priv->w - l); |
fd54975f9135
Use libavutil's av_clip* instead of unreadable MIN/MAX chaos.
reimar
parents:
22024
diff
changeset
|
211 int h = av_clip(gif->Image.Height, 0, priv->h - t); |
21885 | 212 unsigned char *dest = dp->buffer + priv->w * t + l; |
9133 | 213 |
21876 | 214 // copy the palette |
21881
a10888bc9758
Fix invalid read for gifs with a palette for less than 256 colors
reimar
parents:
21880
diff
changeset
|
215 for (y = 0; y < cnt; y++) { |
21893 | 216 priv->palette[(y * 4) + 0] = effective_map->Colors[y].Blue; |
217 priv->palette[(y * 4) + 1] = effective_map->Colors[y].Green; | |
218 priv->palette[(y * 4) + 2] = effective_map->Colors[y].Red; | |
219 priv->palette[(y * 4) + 3] = 0; | |
9133 | 220 } |
221 | |
21922 | 222 if (gif->Image.Interlace) { |
223 uint8_t *s = buf; | |
22024 | 224 int ih = (h - 0 + 7) >> 3; |
225 memcpy_transp_pic(dest, s, w, ih, | |
21922 | 226 priv->w << 3, gif->Image.Width, |
227 transparency, transparent_col); | |
22024 | 228 s += ih * w; |
229 ih = (h - 4 + 7) >> 3; | |
230 memcpy_transp_pic(dest + (priv->w << 2), s, w, ih, | |
21922 | 231 priv->w << 3, gif->Image.Width, |
232 transparency, transparent_col); | |
22024 | 233 s += ih * w; |
234 ih = (h - 2 + 3) >> 2; | |
235 memcpy_transp_pic(dest + (priv->w << 1), s, w, ih, | |
21922 | 236 priv->w << 2, gif->Image.Width, |
237 transparency, transparent_col); | |
22024 | 238 s += ih * w; |
239 ih = (h - 1 + 1) >> 1; | |
240 memcpy_transp_pic(dest + priv->w, s, w, ih, | |
21922 | 241 priv->w << 1, gif->Image.Width, |
242 transparency, transparent_col); | |
243 } else | |
244 memcpy_transp_pic(dest, buf, w, h, priv->w, gif->Image.Width, | |
245 transparency, transparent_col); | |
21892 | 246 |
23457
a124f3abc1ec
Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents:
22605
diff
changeset
|
247 if (refmode == 1) fast_memcpy(priv->refimg, dp->buffer, priv->w * priv->h); |
21892 | 248 if (refmode == 2 && priv->useref) { |
249 dest = priv->refimg + priv->w * t + l; | |
250 memset(buf, gif->SBackGroundColor, len); | |
251 memcpy_pic(dest, buf, w, h, priv->w, gif->Image.Width); | |
252 } | |
21894 | 253 if (!(refmode & 2)) priv->useref = refmode & 1; |
9133 | 254 } |
255 | |
256 free(buf); | |
257 | |
258 demuxer->video->dpos++; | |
21880
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
259 dp->pts = ((float)priv->current_pts) / 100; |
9133 | 260 dp->pos = stream_tell(demuxer->stream); |
261 ds_add_packet(demuxer->video, dp); | |
262 | |
263 return 1; | |
264 } | |
265 | |
16175 | 266 static demuxer_t* demux_open_gif(demuxer_t* demuxer) |
9133 | 267 { |
21880
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
268 gif_priv_t *priv = calloc(1, sizeof(gif_priv_t)); |
9133 | 269 sh_video_t *sh_video = NULL; |
270 GifFileType *gif = NULL; | |
271 | |
21880
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
272 priv->current_pts = 0; |
9133 | 273 demuxer->seekable = 0; // FIXME |
274 | |
275 // go back to the beginning | |
9345 | 276 stream_seek(demuxer->stream,demuxer->stream->start_pos); |
9133 | 277 |
27385
2113bd9c6bd9
Rename preprocessor directives related to image libraries.
diego
parents:
25707
diff
changeset
|
278 #ifdef CONFIG_GIF_TVT_HACK |
9463
93375ee56629
gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents:
9345
diff
changeset
|
279 // without the TVT functionality of libungif, a hard seek must be |
93375ee56629
gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents:
9345
diff
changeset
|
280 // done to the beginning of the file. this is because libgif is |
93375ee56629
gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents:
9345
diff
changeset
|
281 // unable to use mplayer's cache, and without this lseek libgif will |
93375ee56629
gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents:
9345
diff
changeset
|
282 // not read from the beginning of the file and the command will fail. |
93375ee56629
gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents:
9345
diff
changeset
|
283 // with this hack enabled, you will lose the ability to stream a GIF. |
93375ee56629
gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents:
9345
diff
changeset
|
284 lseek(demuxer->stream->fd, 0, SEEK_SET); |
93375ee56629
gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents:
9345
diff
changeset
|
285 gif = DGifOpenFileHandle(demuxer->stream->fd); |
93375ee56629
gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents:
9345
diff
changeset
|
286 #else |
9344
bd7b5078475e
1) codecs.conf changed recently and demux_gif no longer needs to spit
arpi
parents:
9133
diff
changeset
|
287 gif = DGifOpen(demuxer->stream, my_read_gif); |
9463
93375ee56629
gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents:
9345
diff
changeset
|
288 #endif |
9133 | 289 if (!gif) { |
36271 | 290 print_gif_error(NULL); |
32614 | 291 free(priv); |
9133 | 292 return NULL; |
293 } | |
294 | |
295 // create a new video stream header | |
296 sh_video = new_sh_video(demuxer, 0); | |
297 | |
298 // make sure the demuxer knows about the new video stream header | |
299 // (even though new_sh_video() ought to take care of it) | |
36800
f3c835ddce85
demuxers: ensure that stream ids are correctly initialized.
reimar
parents:
36271
diff
changeset
|
300 demuxer->video->id = 0; |
9133 | 301 demuxer->video->sh = sh_video; |
302 | |
303 sh_video->format = mmioFOURCC(8, 'R', 'G', 'B'); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
304 |
9133 | 305 sh_video->fps = 5.0f; |
306 sh_video->frametime = 1.0f / sh_video->fps; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
307 |
32123 | 308 sh_video->bih = malloc(sizeof(*sh_video->bih) + (256 * 4)); |
9133 | 309 sh_video->bih->biCompression = sh_video->format; |
22019
f43d02e9b58b
Set sh_video->bih->biWidth properly, fixes decoding after latest dec_video.c change
reimar
parents:
21922
diff
changeset
|
310 sh_video->bih->biWidth = priv->w = (uint16_t)gif->SWidth; |
f43d02e9b58b
Set sh_video->bih->biWidth properly, fixes decoding after latest dec_video.c change
reimar
parents:
21922
diff
changeset
|
311 sh_video->bih->biHeight = priv->h = (uint16_t)gif->SHeight; |
9133 | 312 sh_video->bih->biBitCount = 8; |
313 sh_video->bih->biPlanes = 2; | |
21880
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
314 priv->palette = (unsigned char *)(sh_video->bih + 1); |
21891 | 315 priv->refimg = malloc(priv->w * priv->h); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
316 |
21880
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
317 priv->gif = gif; |
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
318 demuxer->priv = priv; |
9133 | 319 |
320 return demuxer; | |
321 } | |
322 | |
16175 | 323 static void demux_close_gif(demuxer_t* demuxer) |
9133 | 324 { |
21880
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
325 gif_priv_t *priv = demuxer->priv; |
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
326 if (!priv) return; |
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
327 if (priv->gif && DGifCloseFile(priv->gif) == GIF_ERROR) |
36271 | 328 print_gif_error(priv->gif); |
21891 | 329 free(priv->refimg); |
21880
4e22e06485c6
Move global variables in gif demuxer into priv struct
reimar
parents:
21876
diff
changeset
|
330 free(priv); |
9133 | 331 } |
16175 | 332 |
333 | |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
23457
diff
changeset
|
334 const demuxer_desc_t demuxer_desc_gif = { |
16175 | 335 "GIF demuxer", |
336 "gif", | |
337 "GIF", | |
338 "Joey Parrish", | |
339 "", | |
340 DEMUXER_TYPE_GIF, | |
341 0, // unsafe autodetect | |
342 gif_check_file, | |
343 demux_gif_fill_buffer, | |
344 demux_open_gif, | |
345 demux_close_gif, | |
346 NULL, | |
347 NULL | |
348 }; |