Mercurial > libavcodec.hg
annotate gifdec.c @ 6323:e6da66f378c7 libavcodec
mpegvideo.h has two function declarations with the 'inline' specifier
but no definition for those functions. The C standard requires a
definition to appear in the same translation unit for any function
declared with 'inline'. Most of the files including mpegvideo.h do not
define those functions. Fix this by removing the 'inline' specifiers
from the header.
patch by Uoti Urpala
author | diego |
---|---|
date | Sun, 03 Feb 2008 17:54:30 +0000 |
parents | dfdff1ca78a7 |
children | 745a4216b352 |
rev | line source |
---|---|
4054 | 1 /* |
2 * GIF decoder | |
3 * Copyright (c) 2003 Fabrice Bellard. | |
4 * Copyright (c) 2006 Baptiste Coudurier. | |
5 * | |
6 * This file is part of FFmpeg. | |
7 * | |
8 * FFmpeg is free software; you can redistribute it and/or | |
9 * modify it under the terms of the GNU Lesser General Public | |
10 * License as published by the Free Software Foundation; either | |
11 * version 2.1 of the License, or (at your option) any later version. | |
12 * | |
13 * FFmpeg is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 * Lesser General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU Lesser General Public | |
19 * License along with FFmpeg; if not, write to the Free Software | |
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
21 */ | |
22 | |
23 //#define DEBUG | |
24 | |
25 #include "avcodec.h" | |
26 #include "bytestream.h" | |
4080
f426c81afc9e
LZW decoder as separate module plus TIFF LZW support
kostya
parents:
4060
diff
changeset
|
27 #include "lzw.h" |
4054 | 28 |
29 #define GCE_DISPOSAL_NONE 0 | |
30 #define GCE_DISPOSAL_INPLACE 1 | |
31 #define GCE_DISPOSAL_BACKGROUND 2 | |
32 #define GCE_DISPOSAL_RESTORE 3 | |
33 | |
34 typedef struct GifState { | |
4058 | 35 AVFrame picture; |
4054 | 36 int screen_width; |
37 int screen_height; | |
38 int bits_per_pixel; | |
39 int background_color_index; | |
40 int transparent_color_index; | |
41 int color_resolution; | |
4058 | 42 uint32_t *image_palette; |
4054 | 43 |
44 /* after the frame is displayed, the disposal method is used */ | |
45 int gce_disposal; | |
46 /* delay during which the frame is shown */ | |
47 int gce_delay; | |
48 | |
49 /* LZW compatible decoder */ | |
6218 | 50 const uint8_t *bytestream; |
51 const uint8_t *bytestream_end; | |
4080
f426c81afc9e
LZW decoder as separate module plus TIFF LZW support
kostya
parents:
4060
diff
changeset
|
52 LZWState *lzw; |
4054 | 53 |
54 /* aux buffers */ | |
55 uint8_t global_palette[256 * 3]; | |
56 uint8_t local_palette[256 * 3]; | |
4652 | 57 |
58 AVCodecContext* avctx; | |
4054 | 59 } GifState; |
60 | |
61 static const uint8_t gif87a_sig[6] = "GIF87a"; | |
62 static const uint8_t gif89a_sig[6] = "GIF89a"; | |
63 | |
64 static int gif_read_image(GifState *s) | |
65 { | |
66 int left, top, width, height, bits_per_pixel, code_size, flags; | |
4057 | 67 int is_interleaved, has_local_palette, y, pass, y1, linesize, n, i; |
4144 | 68 uint8_t *ptr, *spal, *palette, *ptr1; |
4054 | 69 |
70 left = bytestream_get_le16(&s->bytestream); | |
71 top = bytestream_get_le16(&s->bytestream); | |
72 width = bytestream_get_le16(&s->bytestream); | |
73 height = bytestream_get_le16(&s->bytestream); | |
74 flags = bytestream_get_byte(&s->bytestream); | |
75 is_interleaved = flags & 0x40; | |
76 has_local_palette = flags & 0x80; | |
77 bits_per_pixel = (flags & 0x07) + 1; | |
78 #ifdef DEBUG | |
4652 | 79 dprintf(s->avctx, "gif: image x=%d y=%d w=%d h=%d\n", left, top, width, height); |
4054 | 80 #endif |
81 | |
82 if (has_local_palette) { | |
83 bytestream_get_buffer(&s->bytestream, s->local_palette, 3 * (1 << bits_per_pixel)); | |
84 palette = s->local_palette; | |
85 } else { | |
86 palette = s->global_palette; | |
87 bits_per_pixel = s->bits_per_pixel; | |
88 } | |
89 | |
90 /* verify that all the image is inside the screen dimensions */ | |
91 if (left + width > s->screen_width || | |
92 top + height > s->screen_height) | |
4520
9bf957e669f0
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
4144
diff
changeset
|
93 return AVERROR(EINVAL); |
4054 | 94 |
95 /* build the palette */ | |
4060 | 96 n = (1 << bits_per_pixel); |
97 spal = palette; | |
98 for(i = 0; i < n; i++) { | |
5089 | 99 s->image_palette[i] = (0xff << 24) | AV_RB24(spal); |
4060 | 100 spal += 3; |
101 } | |
102 for(; i < 256; i++) | |
103 s->image_palette[i] = (0xff << 24); | |
104 /* handle transparency */ | |
105 if (s->transparent_color_index >= 0) | |
106 s->image_palette[s->transparent_color_index] = 0; | |
4054 | 107 |
108 /* now get the image data */ | |
109 code_size = bytestream_get_byte(&s->bytestream); | |
4729 | 110 ff_lzw_decode_init(s->lzw, code_size, s->bytestream, |
111 s->bytestream_end - s->bytestream, FF_LZW_GIF); | |
4054 | 112 |
113 /* read all the image */ | |
4058 | 114 linesize = s->picture.linesize[0]; |
4143 | 115 ptr1 = s->picture.data[0] + top * linesize + left; |
4054 | 116 ptr = ptr1; |
117 pass = 0; | |
118 y1 = 0; | |
119 for (y = 0; y < height; y++) { | |
4080
f426c81afc9e
LZW decoder as separate module plus TIFF LZW support
kostya
parents:
4060
diff
changeset
|
120 ff_lzw_decode(s->lzw, ptr, width); |
4054 | 121 if (is_interleaved) { |
122 switch(pass) { | |
123 default: | |
124 case 0: | |
125 case 1: | |
126 y1 += 8; | |
127 ptr += linesize * 8; | |
128 if (y1 >= height) { | |
129 y1 = 4; | |
130 if (pass == 0) | |
131 ptr = ptr1 + linesize * 4; | |
132 else | |
133 ptr = ptr1 + linesize * 2; | |
134 pass++; | |
135 } | |
136 break; | |
137 case 2: | |
138 y1 += 4; | |
139 ptr += linesize * 4; | |
140 if (y1 >= height) { | |
141 y1 = 1; | |
142 ptr = ptr1 + linesize; | |
143 pass++; | |
144 } | |
145 break; | |
146 case 3: | |
147 y1 += 2; | |
148 ptr += linesize * 2; | |
149 break; | |
150 } | |
151 } else { | |
152 ptr += linesize; | |
153 } | |
154 } | |
155 /* read the garbage data until end marker is found */ | |
4080
f426c81afc9e
LZW decoder as separate module plus TIFF LZW support
kostya
parents:
4060
diff
changeset
|
156 ff_lzw_decode_tail(s->lzw); |
f426c81afc9e
LZW decoder as separate module plus TIFF LZW support
kostya
parents:
4060
diff
changeset
|
157 s->bytestream = ff_lzw_cur_ptr(s->lzw); |
4054 | 158 return 0; |
159 } | |
160 | |
161 static int gif_read_extension(GifState *s) | |
162 { | |
163 int ext_code, ext_len, i, gce_flags, gce_transparent_index; | |
164 | |
165 /* extension */ | |
166 ext_code = bytestream_get_byte(&s->bytestream); | |
167 ext_len = bytestream_get_byte(&s->bytestream); | |
168 #ifdef DEBUG | |
4652 | 169 dprintf(s->avctx, "gif: ext_code=0x%x len=%d\n", ext_code, ext_len); |
4054 | 170 #endif |
171 switch(ext_code) { | |
172 case 0xf9: | |
173 if (ext_len != 4) | |
174 goto discard_ext; | |
175 s->transparent_color_index = -1; | |
176 gce_flags = bytestream_get_byte(&s->bytestream); | |
177 s->gce_delay = bytestream_get_le16(&s->bytestream); | |
178 gce_transparent_index = bytestream_get_byte(&s->bytestream); | |
179 if (gce_flags & 0x01) | |
180 s->transparent_color_index = gce_transparent_index; | |
181 else | |
182 s->transparent_color_index = -1; | |
183 s->gce_disposal = (gce_flags >> 2) & 0x7; | |
184 #ifdef DEBUG | |
4652 | 185 dprintf(s->avctx, "gif: gce_flags=%x delay=%d tcolor=%d disposal=%d\n", |
4054 | 186 gce_flags, s->gce_delay, |
187 s->transparent_color_index, s->gce_disposal); | |
188 #endif | |
189 ext_len = bytestream_get_byte(&s->bytestream); | |
190 break; | |
191 } | |
192 | |
193 /* NOTE: many extension blocks can come after */ | |
194 discard_ext: | |
195 while (ext_len != 0) { | |
196 for (i = 0; i < ext_len; i++) | |
197 bytestream_get_byte(&s->bytestream); | |
198 ext_len = bytestream_get_byte(&s->bytestream); | |
199 #ifdef DEBUG | |
4652 | 200 dprintf(s->avctx, "gif: ext_len1=%d\n", ext_len); |
4054 | 201 #endif |
202 } | |
203 return 0; | |
204 } | |
205 | |
206 static int gif_read_header1(GifState *s) | |
207 { | |
208 uint8_t sig[6]; | |
4057 | 209 int v, n; |
4054 | 210 int has_global_palette; |
211 | |
4718 | 212 if (s->bytestream_end < s->bytestream + 13) |
213 return -1; | |
214 | |
4054 | 215 /* read gif signature */ |
216 bytestream_get_buffer(&s->bytestream, sig, 6); | |
217 if (memcmp(sig, gif87a_sig, 6) != 0 && | |
218 memcmp(sig, gif89a_sig, 6) != 0) | |
219 return -1; | |
220 | |
221 /* read screen header */ | |
222 s->transparent_color_index = -1; | |
223 s->screen_width = bytestream_get_le16(&s->bytestream); | |
224 s->screen_height = bytestream_get_le16(&s->bytestream); | |
225 if( (unsigned)s->screen_width > 32767 | |
226 || (unsigned)s->screen_height > 32767){ | |
227 av_log(NULL, AV_LOG_ERROR, "picture size too large\n"); | |
228 return -1; | |
229 } | |
230 | |
231 v = bytestream_get_byte(&s->bytestream); | |
232 s->color_resolution = ((v & 0x70) >> 4) + 1; | |
233 has_global_palette = (v & 0x80); | |
234 s->bits_per_pixel = (v & 0x07) + 1; | |
235 s->background_color_index = bytestream_get_byte(&s->bytestream); | |
236 bytestream_get_byte(&s->bytestream); /* ignored */ | |
237 #ifdef DEBUG | |
4652 | 238 dprintf(s->avctx, "gif: screen_w=%d screen_h=%d bpp=%d global_palette=%d\n", |
4054 | 239 s->screen_width, s->screen_height, s->bits_per_pixel, |
240 has_global_palette); | |
241 #endif | |
242 if (has_global_palette) { | |
243 n = 1 << s->bits_per_pixel; | |
4718 | 244 if (s->bytestream_end < s->bytestream + n * 3) |
245 return -1; | |
4054 | 246 bytestream_get_buffer(&s->bytestream, s->global_palette, n * 3); |
247 } | |
248 return 0; | |
249 } | |
250 | |
251 static int gif_parse_next_image(GifState *s) | |
252 { | |
4718 | 253 while (s->bytestream < s->bytestream_end) { |
4717 | 254 int code = bytestream_get_byte(&s->bytestream); |
4054 | 255 #ifdef DEBUG |
4652 | 256 dprintf(s->avctx, "gif: code=%02x '%c'\n", code, code); |
4054 | 257 #endif |
258 switch (code) { | |
259 case ',': | |
4874
f06463413858
simplify, patch by Mark Cox, melbournemark plus ffmpeg minus devel gmail com
bcoudurier
parents:
4868
diff
changeset
|
260 return gif_read_image(s); |
4054 | 261 case '!': |
262 if (gif_read_extension(s) < 0) | |
263 return -1; | |
264 break; | |
4874
f06463413858
simplify, patch by Mark Cox, melbournemark plus ffmpeg minus devel gmail com
bcoudurier
parents:
4868
diff
changeset
|
265 case ';': |
f06463413858
simplify, patch by Mark Cox, melbournemark plus ffmpeg minus devel gmail com
bcoudurier
parents:
4868
diff
changeset
|
266 /* end of image */ |
4054 | 267 default: |
4868 | 268 /* error or erroneous EOF */ |
4717 | 269 return -1; |
4054 | 270 } |
271 } | |
4720
7775ba23c931
return error if loop has ended before decoding image
bcoudurier
parents:
4719
diff
changeset
|
272 return -1; |
4054 | 273 } |
274 | |
275 static int gif_decode_init(AVCodecContext *avctx) | |
276 { | |
277 GifState *s = avctx->priv_data; | |
278 | |
4652 | 279 s->avctx = avctx; |
280 | |
4058 | 281 avcodec_get_frame_defaults(&s->picture); |
282 avctx->coded_frame= &s->picture; | |
283 s->picture.data[0] = NULL; | |
4080
f426c81afc9e
LZW decoder as separate module plus TIFF LZW support
kostya
parents:
4060
diff
changeset
|
284 ff_lzw_decode_open(&s->lzw); |
4054 | 285 return 0; |
286 } | |
287 | |
6218 | 288 static int gif_decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) |
4054 | 289 { |
290 GifState *s = avctx->priv_data; | |
291 AVFrame *picture = data; | |
292 int ret; | |
293 | |
294 s->bytestream = buf; | |
4718 | 295 s->bytestream_end = buf + buf_size; |
4054 | 296 if (gif_read_header1(s) < 0) |
297 return -1; | |
298 | |
299 avctx->pix_fmt = PIX_FMT_PAL8; | |
4058 | 300 if (avcodec_check_dimensions(avctx, s->screen_width, s->screen_height)) |
301 return -1; | |
302 avcodec_set_dimensions(avctx, s->screen_width, s->screen_height); | |
4054 | 303 |
4058 | 304 if (s->picture.data[0]) |
305 avctx->release_buffer(avctx, &s->picture); | |
306 if (avctx->get_buffer(avctx, &s->picture) < 0) { | |
307 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
308 return -1; | |
309 } | |
310 s->image_palette = (uint32_t *)s->picture.data[1]; | |
4054 | 311 ret = gif_parse_next_image(s); |
312 if (ret < 0) | |
313 return ret; | |
314 | |
4058 | 315 *picture = s->picture; |
316 *data_size = sizeof(AVPicture); | |
4719 | 317 return s->bytestream - buf; |
4058 | 318 } |
4054 | 319 |
4058 | 320 static int gif_decode_close(AVCodecContext *avctx) |
321 { | |
322 GifState *s = avctx->priv_data; | |
323 | |
4080
f426c81afc9e
LZW decoder as separate module plus TIFF LZW support
kostya
parents:
4060
diff
changeset
|
324 ff_lzw_decode_close(&s->lzw); |
4058 | 325 if(s->picture.data[0]) |
326 avctx->release_buffer(avctx, &s->picture); | |
4054 | 327 return 0; |
328 } | |
329 | |
330 AVCodec gif_decoder = { | |
331 "gif", | |
332 CODEC_TYPE_VIDEO, | |
333 CODEC_ID_GIF, | |
334 sizeof(GifState), | |
335 gif_decode_init, | |
336 NULL, | |
4058 | 337 gif_decode_close, |
4054 | 338 gif_decode_frame, |
339 }; |