comparison gifdec.c @ 887:d70e50f1495f libavformat

COSMETICS: tabs --> spaces, some prettyprinting
author diego
date Thu, 22 Dec 2005 01:10:11 +0000
parents da1d5db0ce5c
children edbe5c3717f9
comparison
equal deleted inserted replaced
886:7ed1351f8c7e 887:d70e50f1495f
20 20
21 int gif_write(ByteIOContext *pb, AVImageInfo *info); 21 int gif_write(ByteIOContext *pb, AVImageInfo *info);
22 22
23 //#define DEBUG 23 //#define DEBUG
24 24
25 #define MAXBITS 12 25 #define MAXBITS 12
26 #define SIZTABLE (1<<MAXBITS) 26 #define SIZTABLE (1<<MAXBITS)
27 27
28 #define GCE_DISPOSAL_NONE 0 28 #define GCE_DISPOSAL_NONE 0
29 #define GCE_DISPOSAL_INPLACE 1 29 #define GCE_DISPOSAL_INPLACE 1
30 #define GCE_DISPOSAL_BACKGROUND 2 30 #define GCE_DISPOSAL_BACKGROUND 2
31 #define GCE_DISPOSAL_RESTORE 3 31 #define GCE_DISPOSAL_RESTORE 3
52 int eob_reached; 52 int eob_reached;
53 uint8_t *pbuf, *ebuf; 53 uint8_t *pbuf, *ebuf;
54 int bbits; 54 int bbits;
55 unsigned int bbuf; 55 unsigned int bbuf;
56 56
57 int cursize; /* The current code size */ 57 int cursize; /* The current code size */
58 int curmask; 58 int curmask;
59 int codesize; 59 int codesize;
60 int clear_code; 60 int clear_code;
61 int end_code; 61 int end_code;
62 int newcodes; /* First available code */ 62 int newcodes; /* First available code */
63 int top_slot; /* Highest code for current size */ 63 int top_slot; /* Highest code for current size */
64 int slot; /* Last read code */ 64 int slot; /* Last read code */
65 int fc, oc; 65 int fc, oc;
66 uint8_t *sp; 66 uint8_t *sp;
67 uint8_t stack[SIZTABLE]; 67 uint8_t stack[SIZTABLE];
68 uint8_t suffix[SIZTABLE]; 68 uint8_t suffix[SIZTABLE];
69 uint16_t prefix[SIZTABLE]; 69 uint16_t prefix[SIZTABLE];
95 const uint8_t *p, *p_end; 95 const uint8_t *p, *p_end;
96 int bits_per_pixel, has_global_palette, ext_code, ext_len; 96 int bits_per_pixel, has_global_palette, ext_code, ext_len;
97 int gce_flags, gce_disposal; 97 int gce_flags, gce_disposal;
98 98
99 if (pd->buf_size < 24 || 99 if (pd->buf_size < 24 ||
100 memcmp(pd->buf, gif89a_sig, 6) != 0) 100 memcmp(pd->buf, gif89a_sig, 6) != 0)
101 return 0; 101 return 0;
102 p_end = pd->buf + pd->buf_size; 102 p_end = pd->buf + pd->buf_size;
103 p = pd->buf + 6; 103 p = pd->buf + 6;
104 bits_per_pixel = (p[4] & 0x07) + 1; 104 bits_per_pixel = (p[4] & 0x07) + 1;
105 has_global_palette = (p[4] & 0x80); 105 has_global_palette = (p[4] & 0x80);
143 } 143 }
144 144
145 static int gif_image_probe(AVProbeData * pd) 145 static int gif_image_probe(AVProbeData * pd)
146 { 146 {
147 if (pd->buf_size >= 24 && 147 if (pd->buf_size >= 24 &&
148 (memcmp(pd->buf, gif87a_sig, 6) == 0 || 148 (memcmp(pd->buf, gif87a_sig, 6) == 0 ||
149 memcmp(pd->buf, gif89a_sig, 6) == 0)) 149 memcmp(pd->buf, gif89a_sig, 6) == 0))
150 return AVPROBE_SCORE_MAX - 1; 150 return AVPROBE_SCORE_MAX - 1;
151 else 151 else
152 return 0; 152 return 0;
153 } 153 }
154 154
155 155
156 static void GLZWDecodeInit(GifState * s, int csize) 156 static void GLZWDecodeInit(GifState * s, int csize)
157 { 157 {
196 ptr = s->pbuf; 196 ptr = s->pbuf;
197 } 197 }
198 s->bbuf |= ptr[0] << s->bbits; 198 s->bbuf |= ptr[0] << s->bbits;
199 ptr++; 199 ptr++;
200 s->pbuf = ptr; 200 s->pbuf = ptr;
201 s->bbits += 8; 201 s->bbits += 8;
202 } 202 }
203 c = s->bbuf & s->curmask; 203 c = s->bbuf & s->curmask;
204 s->bbuf >>= s->cursize; 204 s->bbuf >>= s->cursize;
205 s->bbits -= s->cursize; 205 s->bbits -= s->cursize;
206 return c; 206 return c;
221 sp = s->sp; 221 sp = s->sp;
222 oc = s->oc; 222 oc = s->oc;
223 fc = s->fc; 223 fc = s->fc;
224 224
225 while (sp > s->stack) { 225 while (sp > s->stack) {
226 *buf++ = *(--sp); 226 *buf++ = *(--sp);
227 if ((--l) == 0) 227 if ((--l) == 0)
228 goto the_end; 228 goto the_end;
229 } 229 }
230 230
231 for (;;) { 231 for (;;) {
232 c = GetCode(s); 232 c = GetCode(s);
233 if (c == s->end_code) { 233 if (c == s->end_code) {
234 s->end_code = -1; 234 s->end_code = -1;
235 break; 235 break;
236 } else if (c == s->clear_code) { 236 } else if (c == s->clear_code) {
237 s->cursize = s->codesize + 1; 237 s->cursize = s->codesize + 1;
238 s->curmask = mask[s->cursize]; 238 s->curmask = mask[s->cursize];
239 s->slot = s->newcodes; 239 s->slot = s->newcodes;
240 s->top_slot = 1 << s->cursize; 240 s->top_slot = 1 << s->cursize;
241 while ((c = GetCode(s)) == s->clear_code); 241 while ((c = GetCode(s)) == s->clear_code);
242 if (c == s->end_code) { 242 if (c == s->end_code) {
243 s->end_code = -1; 243 s->end_code = -1;
244 break; 244 break;
245 } 245 }
246 /* test error */ 246 /* test error */
247 if (c >= s->slot) 247 if (c >= s->slot)
248 c = 0; 248 c = 0;
249 fc = oc = c; 249 fc = oc = c;
250 *buf++ = c; 250 *buf++ = c;
251 if ((--l) == 0) 251 if ((--l) == 0)
252 break; 252 break;
253 } else { 253 } else {
254 code = c; 254 code = c;
255 if (code >= s->slot) { 255 if (code >= s->slot) {
256 *sp++ = fc; 256 *sp++ = fc;
257 code = oc; 257 code = oc;
258 } 258 }
259 while (code >= s->newcodes) { 259 while (code >= s->newcodes) {
260 *sp++ = s->suffix[code]; 260 *sp++ = s->suffix[code];
261 code = s->prefix[code]; 261 code = s->prefix[code];
262 } 262 }
263 *sp++ = code; 263 *sp++ = code;
264 if (s->slot < s->top_slot) { 264 if (s->slot < s->top_slot) {
265 s->suffix[s->slot] = fc = code; 265 s->suffix[s->slot] = fc = code;
266 s->prefix[s->slot++] = oc; 266 s->prefix[s->slot++] = oc;
267 oc = c; 267 oc = c;
268 } 268 }
269 if (s->slot >= s->top_slot) { 269 if (s->slot >= s->top_slot) {
270 if (s->cursize < MAXBITS) { 270 if (s->cursize < MAXBITS) {
271 s->top_slot <<= 1; 271 s->top_slot <<= 1;
272 s->curmask = mask[++s->cursize]; 272 s->curmask = mask[++s->cursize];
273 } 273 }
274 } 274 }
275 while (sp > s->stack) { 275 while (sp > s->stack) {
276 *buf++ = *(--sp); 276 *buf++ = *(--sp);
277 if ((--l) == 0) 277 if ((--l) == 0)
278 goto the_end; 278 goto the_end;
279 } 279 }
280 } 280 }
281 } 281 }
282 the_end: 282 the_end:
283 s->sp = sp; 283 s->sp = sp;
284 s->oc = oc; 284 s->oc = oc;
285 s->fc = fc; 285 s->fc = fc;
304 #ifdef DEBUG 304 #ifdef DEBUG
305 printf("gif: image x=%d y=%d w=%d h=%d\n", left, top, width, height); 305 printf("gif: image x=%d y=%d w=%d h=%d\n", left, top, width, height);
306 #endif 306 #endif
307 307
308 if (has_local_palette) { 308 if (has_local_palette) {
309 get_buffer(f, s->local_palette, 3 * (1 << bits_per_pixel)); 309 get_buffer(f, s->local_palette, 3 * (1 << bits_per_pixel));
310 palette = s->local_palette; 310 palette = s->local_palette;
311 } else { 311 } else {
312 palette = s->global_palette; 312 palette = s->global_palette;
313 bits_per_pixel = s->bits_per_pixel; 313 bits_per_pixel = s->bits_per_pixel;
314 } 314 }
463 int has_global_palette; 463 int has_global_palette;
464 464
465 /* read gif signature */ 465 /* read gif signature */
466 ret = get_buffer(f, sig, 6); 466 ret = get_buffer(f, sig, 6);
467 if (ret != 6) 467 if (ret != 6)
468 return -1; 468 return -1;
469 if (memcmp(sig, gif87a_sig, 6) != 0 && 469 if (memcmp(sig, gif87a_sig, 6) != 0 &&
470 memcmp(sig, gif89a_sig, 6) != 0) 470 memcmp(sig, gif89a_sig, 6) != 0)
471 return -1; 471 return -1;
472 472
473 /* read screen header */ 473 /* read screen header */
474 s->transparent_color_index = -1; 474 s->transparent_color_index = -1;
475 s->screen_width = get_le16(f); 475 s->screen_width = get_le16(f);
476 s->screen_height = get_le16(f); 476 s->screen_height = get_le16(f);
483 v = get_byte(f); 483 v = get_byte(f);
484 s->color_resolution = ((v & 0x70) >> 4) + 1; 484 s->color_resolution = ((v & 0x70) >> 4) + 1;
485 has_global_palette = (v & 0x80); 485 has_global_palette = (v & 0x80);
486 s->bits_per_pixel = (v & 0x07) + 1; 486 s->bits_per_pixel = (v & 0x07) + 1;
487 s->background_color_index = get_byte(f); 487 s->background_color_index = get_byte(f);
488 get_byte(f); /* ignored */ 488 get_byte(f); /* ignored */
489 #ifdef DEBUG 489 #ifdef DEBUG
490 printf("gif: screen_w=%d screen_h=%d bpp=%d global_palette=%d\n", 490 printf("gif: screen_w=%d screen_h=%d bpp=%d global_palette=%d\n",
491 s->screen_width, s->screen_height, s->bits_per_pixel, 491 s->screen_width, s->screen_height, s->bits_per_pixel,
492 has_global_palette); 492 has_global_palette);
493 #endif 493 #endif
494 if (has_global_palette) { 494 if (has_global_palette) {
495 n = 1 << s->bits_per_pixel; 495 n = 1 << s->bits_per_pixel;
496 get_buffer(f, s->global_palette, n * 3); 496 get_buffer(f, s->global_palette, n * 3);
497 } 497 }
498 return 0; 498 return 0;
499 } 499 }
500 500
501 static int gif_parse_next_image(GifState *s) 501 static int gif_parse_next_image(GifState *s)
502 { 502 {
503 ByteIOContext *f = s->f; 503 ByteIOContext *f = s->f;
504 int ret, code; 504 int ret, code;
505 505
506 for (;;) { 506 for (;;) {
507 code = url_fgetc(f); 507 code = url_fgetc(f);
508 #ifdef DEBUG 508 #ifdef DEBUG
509 printf("gif: code=%02x '%c'\n", code, code); 509 printf("gif: code=%02x '%c'\n", code, code);
510 #endif 510 #endif
511 switch (code) { 511 switch (code) {
512 case ',': 512 case ',':
513 if (gif_read_image(s) < 0) 513 if (gif_read_image(s) < 0)
514 return AVERROR_IO; 514 return AVERROR_IO;
515 ret = 0; 515 ret = 0;
516 goto the_end; 516 goto the_end;
517 case ';': 517 case ';':
518 /* end of image */ 518 /* end of image */
519 ret = AVERROR_IO; 519 ret = AVERROR_IO;
520 goto the_end; 520 goto the_end;
521 case '!': 521 case '!':
522 if (gif_read_extension(s) < 0) 522 if (gif_read_extension(s) < 0)
523 return AVERROR_IO; 523 return AVERROR_IO;
524 break; 524 break;
525 case EOF: 525 case EOF:
526 default: 526 default:
527 /* error or errneous EOF */ 527 /* error or errneous EOF */
528 ret = AVERROR_IO; 528 ret = AVERROR_IO;
529 goto the_end; 529 goto the_end;
530 } 530 }
531 } 531 }
532 the_end: 532 the_end:
533 return ret; 533 return ret;
534 } 534 }
535 535
536 static int gif_read_header(AVFormatContext * s1, 536 static int gif_read_header(AVFormatContext * s1,
537 AVFormatParameters * ap) 537 AVFormatParameters * ap)
538 { 538 {
539 GifState *s = s1->priv_data; 539 GifState *s = s1->priv_data;
540 ByteIOContext *f = &s1->pb; 540 ByteIOContext *f = &s1->pb;
541 AVStream *st; 541 AVStream *st;
542 542
551 return -ENOMEM; 551 return -ENOMEM;
552 s->pix_fmt = PIX_FMT_RGB24; 552 s->pix_fmt = PIX_FMT_RGB24;
553 /* now we are ready: build format streams */ 553 /* now we are ready: build format streams */
554 st = av_new_stream(s1, 0); 554 st = av_new_stream(s1, 0);
555 if (!st) 555 if (!st)
556 return -1; 556 return -1;
557 557
558 st->codec->codec_type = CODEC_TYPE_VIDEO; 558 st->codec->codec_type = CODEC_TYPE_VIDEO;
559 st->codec->codec_id = CODEC_ID_RAWVIDEO; 559 st->codec->codec_id = CODEC_ID_RAWVIDEO;
560 st->codec->time_base.den = 5; 560 st->codec->time_base.den = 5;
561 st->codec->time_base.num = 1; 561 st->codec->time_base.num = 1;
565 st->codec->pix_fmt = PIX_FMT_RGB24; 565 st->codec->pix_fmt = PIX_FMT_RGB24;
566 return 0; 566 return 0;
567 } 567 }
568 568
569 static int gif_read_packet(AVFormatContext * s1, 569 static int gif_read_packet(AVFormatContext * s1,
570 AVPacket * pkt) 570 AVPacket * pkt)
571 { 571 {
572 GifState *s = s1->priv_data; 572 GifState *s = s1->priv_data;
573 int ret; 573 int ret;
574 574
575 ret = gif_parse_next_image(s); 575 ret = gif_parse_next_image(s);
576 if (ret < 0) 576 if (ret < 0)
577 return ret; 577 return ret;
578 578
579 /* XXX: avoid copying */ 579 /* XXX: avoid copying */
580 if (av_new_packet(pkt, s->screen_width * s->screen_height * 3)) { 580 if (av_new_packet(pkt, s->screen_width * s->screen_height * 3)) {
581 return AVERROR_IO; 581 return AVERROR_IO;
582 } 582 }
583 pkt->stream_index = 0; 583 pkt->stream_index = 0;
584 memcpy(pkt->data, s->image_buf, s->screen_width * s->screen_height * 3); 584 memcpy(pkt->data, s->image_buf, s->screen_width * s->screen_height * 3);
585 return 0; 585 return 0;
586 } 586 }