Mercurial > libavcodec.hg
comparison png.c @ 2967:ef2149182f1c libavcodec
COSMETICS: Remove all trailing whitespace.
author | diego |
---|---|
date | Sat, 17 Dec 2005 18:14:38 +0000 |
parents | b2846918585c |
children | 0b546eab515d |
comparison
equal
deleted
inserted
replaced
2966:564788471dd4 | 2967:ef2149182f1c |
---|---|
67 int interlace_type; | 67 int interlace_type; |
68 int filter_type; | 68 int filter_type; |
69 int channels; | 69 int channels; |
70 int bits_per_pixel; | 70 int bits_per_pixel; |
71 int bpp; | 71 int bpp; |
72 | 72 |
73 uint8_t *image_buf; | 73 uint8_t *image_buf; |
74 int image_linesize; | 74 int image_linesize; |
75 uint32_t palette[256]; | 75 uint32_t palette[256]; |
76 uint8_t *crow_buf; | 76 uint8_t *crow_buf; |
77 uint8_t *last_row; | 77 uint8_t *last_row; |
123 static const uint8_t png_pass_mask[NB_PASSES] = { | 123 static const uint8_t png_pass_mask[NB_PASSES] = { |
124 0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff | 124 0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff |
125 }; | 125 }; |
126 | 126 |
127 /* Mask to determine which pixels to overwrite while displaying */ | 127 /* Mask to determine which pixels to overwrite while displaying */ |
128 static const uint8_t png_pass_dsp_mask[NB_PASSES] = { | 128 static const uint8_t png_pass_dsp_mask[NB_PASSES] = { |
129 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff | 129 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff |
130 }; | 130 }; |
131 #if 0 | 131 #if 0 |
132 static int png_probe(AVProbeData *pd) | 132 static int png_probe(AVProbeData *pd) |
133 { | 133 { |
176 } | 176 } |
177 | 177 |
178 /* NOTE: we try to construct a good looking image at each pass. width | 178 /* NOTE: we try to construct a good looking image at each pass. width |
179 is the original image width. We also do pixel format convertion at | 179 is the original image width. We also do pixel format convertion at |
180 this stage */ | 180 this stage */ |
181 static void png_put_interlaced_row(uint8_t *dst, int width, | 181 static void png_put_interlaced_row(uint8_t *dst, int width, |
182 int bits_per_pixel, int pass, | 182 int bits_per_pixel, int pass, |
183 int color_type, const uint8_t *src) | 183 int color_type, const uint8_t *src) |
184 { | 184 { |
185 int x, mask, dsp_mask, j, src_x, b, bpp; | 185 int x, mask, dsp_mask, j, src_x, b, bpp; |
186 uint8_t *d; | 186 uint8_t *d; |
187 const uint8_t *s; | 187 const uint8_t *s; |
188 | 188 |
189 mask = png_pass_mask[pass]; | 189 mask = png_pass_mask[pass]; |
190 dsp_mask = png_pass_dsp_mask[pass]; | 190 dsp_mask = png_pass_dsp_mask[pass]; |
191 switch(bits_per_pixel) { | 191 switch(bits_per_pixel) { |
192 case 1: | 192 case 1: |
193 /* we must intialize the line to zero before writing to it */ | 193 /* we must intialize the line to zero before writing to it */ |
231 } | 231 } |
232 break; | 232 break; |
233 } | 233 } |
234 } | 234 } |
235 | 235 |
236 static void png_get_interlaced_row(uint8_t *dst, int row_size, | 236 static void png_get_interlaced_row(uint8_t *dst, int row_size, |
237 int bits_per_pixel, int pass, | 237 int bits_per_pixel, int pass, |
238 const uint8_t *src, int width) | 238 const uint8_t *src, int width) |
239 { | 239 { |
240 int x, mask, dst_x, j, b, bpp; | 240 int x, mask, dst_x, j, b, bpp; |
241 uint8_t *d; | 241 uint8_t *d; |
242 const uint8_t *s; | 242 const uint8_t *s; |
271 } | 271 } |
272 } | 272 } |
273 | 273 |
274 /* XXX: optimize */ | 274 /* XXX: optimize */ |
275 /* NOTE: 'dst' can be equal to 'last' */ | 275 /* NOTE: 'dst' can be equal to 'last' */ |
276 static void png_filter_row(uint8_t *dst, int filter_type, | 276 static void png_filter_row(uint8_t *dst, int filter_type, |
277 uint8_t *src, uint8_t *last, int size, int bpp) | 277 uint8_t *src, uint8_t *last, int size, int bpp) |
278 { | 278 { |
279 int i, p; | 279 int i, p; |
280 | 280 |
281 switch(filter_type) { | 281 switch(filter_type) { |
341 static void convert_from_rgba32(uint8_t *dst, const uint8_t *src, int width) | 341 static void convert_from_rgba32(uint8_t *dst, const uint8_t *src, int width) |
342 { | 342 { |
343 uint8_t *d; | 343 uint8_t *d; |
344 int j; | 344 int j; |
345 unsigned int v; | 345 unsigned int v; |
346 | 346 |
347 d = dst; | 347 d = dst; |
348 for(j = 0; j < width; j++) { | 348 for(j = 0; j < width; j++) { |
349 v = ((uint32_t *)src)[j]; | 349 v = ((uint32_t *)src)[j]; |
350 d[0] = v >> 16; | 350 d[0] = v >> 16; |
351 d[1] = v >> 8; | 351 d[1] = v >> 8; |
374 /* process exactly one decompressed row */ | 374 /* process exactly one decompressed row */ |
375 static void png_handle_row(PNGContext *s) | 375 static void png_handle_row(PNGContext *s) |
376 { | 376 { |
377 uint8_t *ptr, *last_row; | 377 uint8_t *ptr, *last_row; |
378 int got_line; | 378 int got_line; |
379 | 379 |
380 if (!s->interlace_type) { | 380 if (!s->interlace_type) { |
381 ptr = s->image_buf + s->image_linesize * s->y; | 381 ptr = s->image_buf + s->image_linesize * s->y; |
382 /* need to swap bytes correctly for RGB_ALPHA */ | 382 /* need to swap bytes correctly for RGB_ALPHA */ |
383 if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { | 383 if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { |
384 png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1, | 384 png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1, |
385 s->last_row, s->row_size, s->bpp); | 385 s->last_row, s->row_size, s->bpp); |
386 memcpy(s->last_row, s->tmp_row, s->row_size); | 386 memcpy(s->last_row, s->tmp_row, s->row_size); |
387 convert_to_rgba32(ptr, s->tmp_row, s->width); | 387 convert_to_rgba32(ptr, s->tmp_row, s->width); |
388 } else { | 388 } else { |
389 /* in normal case, we avoid one copy */ | 389 /* in normal case, we avoid one copy */ |
390 if (s->y == 0) | 390 if (s->y == 0) |
391 last_row = s->last_row; | 391 last_row = s->last_row; |
392 else | 392 else |
393 last_row = ptr - s->image_linesize; | 393 last_row = ptr - s->image_linesize; |
394 | 394 |
395 png_filter_row(ptr, s->crow_buf[0], s->crow_buf + 1, | 395 png_filter_row(ptr, s->crow_buf[0], s->crow_buf + 1, |
396 last_row, s->row_size, s->bpp); | 396 last_row, s->row_size, s->bpp); |
397 } | 397 } |
398 s->y++; | 398 s->y++; |
399 if (s->y == s->height) { | 399 if (s->y == s->height) { |
400 s->state |= PNG_ALLIMAGE; | 400 s->state |= PNG_ALLIMAGE; |
406 if ((png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) { | 406 if ((png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) { |
407 /* if we already read one row, it is time to stop to | 407 /* if we already read one row, it is time to stop to |
408 wait for the next one */ | 408 wait for the next one */ |
409 if (got_line) | 409 if (got_line) |
410 break; | 410 break; |
411 png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1, | 411 png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1, |
412 s->last_row, s->pass_row_size, s->bpp); | 412 s->last_row, s->pass_row_size, s->bpp); |
413 memcpy(s->last_row, s->tmp_row, s->pass_row_size); | 413 memcpy(s->last_row, s->tmp_row, s->pass_row_size); |
414 got_line = 1; | 414 got_line = 1; |
415 } | 415 } |
416 if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) { | 416 if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) { |
417 /* NOTE: rgba32 is handled directly in png_put_interlaced_row */ | 417 /* NOTE: rgba32 is handled directly in png_put_interlaced_row */ |
418 png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass, | 418 png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass, |
419 s->color_type, s->last_row); | 419 s->color_type, s->last_row); |
420 } | 420 } |
421 s->y++; | 421 s->y++; |
422 if (s->y == s->height) { | 422 if (s->y == s->height) { |
423 for(;;) { | 423 for(;;) { |
425 s->state |= PNG_ALLIMAGE; | 425 s->state |= PNG_ALLIMAGE; |
426 goto the_end; | 426 goto the_end; |
427 } else { | 427 } else { |
428 s->pass++; | 428 s->pass++; |
429 s->y = 0; | 429 s->y = 0; |
430 s->pass_row_size = png_pass_row_size(s->pass, | 430 s->pass_row_size = png_pass_row_size(s->pass, |
431 s->bits_per_pixel, | 431 s->bits_per_pixel, |
432 s->width); | 432 s->width); |
433 s->crow_size = s->pass_row_size + 1; | 433 s->crow_size = s->pass_row_size + 1; |
434 if (s->pass_row_size != 0) | 434 if (s->pass_row_size != 0) |
435 break; | 435 break; |
436 /* skip pass if empty row */ | 436 /* skip pass if empty row */ |
446 { | 446 { |
447 int ret; | 447 int ret; |
448 s->zstream.avail_in = length; | 448 s->zstream.avail_in = length; |
449 s->zstream.next_in = s->bytestream; | 449 s->zstream.next_in = s->bytestream; |
450 s->bytestream += length; | 450 s->bytestream += length; |
451 | 451 |
452 if(s->bytestream > s->bytestream_end) | 452 if(s->bytestream > s->bytestream_end) |
453 return -1; | 453 return -1; |
454 | 454 |
455 /* decode one line if possible */ | 455 /* decode one line if possible */ |
456 while (s->zstream.avail_in > 0) { | 456 while (s->zstream.avail_in > 0) { |
467 } | 467 } |
468 } | 468 } |
469 return 0; | 469 return 0; |
470 } | 470 } |
471 | 471 |
472 static int decode_frame(AVCodecContext *avctx, | 472 static int decode_frame(AVCodecContext *avctx, |
473 void *data, int *data_size, | 473 void *data, int *data_size, |
474 uint8_t *buf, int buf_size) | 474 uint8_t *buf, int buf_size) |
475 { | 475 { |
476 PNGContext * const s = avctx->priv_data; | 476 PNGContext * const s = avctx->priv_data; |
477 AVFrame *picture = data; | 477 AVFrame *picture = data; |
505 if (length > 0x7fffffff) | 505 if (length > 0x7fffffff) |
506 goto fail; | 506 goto fail; |
507 tag32 = get32(&s->bytestream); | 507 tag32 = get32(&s->bytestream); |
508 tag = bswap_32(tag32); | 508 tag = bswap_32(tag32); |
509 #ifdef DEBUG | 509 #ifdef DEBUG |
510 printf("png: tag=%c%c%c%c length=%u\n", | 510 printf("png: tag=%c%c%c%c length=%u\n", |
511 (tag & 0xff), | 511 (tag & 0xff), |
512 ((tag >> 8) & 0xff), | 512 ((tag >> 8) & 0xff), |
513 ((tag >> 16) & 0xff), | 513 ((tag >> 16) & 0xff), |
514 ((tag >> 24) & 0xff), length); | 514 ((tag >> 24) & 0xff), length); |
515 #endif | 515 #endif |
529 s->filter_type = *s->bytestream++; | 529 s->filter_type = *s->bytestream++; |
530 s->interlace_type = *s->bytestream++; | 530 s->interlace_type = *s->bytestream++; |
531 crc = get32(&s->bytestream); | 531 crc = get32(&s->bytestream); |
532 s->state |= PNG_IHDR; | 532 s->state |= PNG_IHDR; |
533 #ifdef DEBUG | 533 #ifdef DEBUG |
534 printf("width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n", | 534 printf("width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n", |
535 s->width, s->height, s->bit_depth, s->color_type, | 535 s->width, s->height, s->bit_depth, s->color_type, |
536 s->compression_type, s->filter_type, s->interlace_type); | 536 s->compression_type, s->filter_type, s->interlace_type); |
537 #endif | 537 #endif |
538 break; | 538 break; |
539 case MKTAG('I', 'D', 'A', 'T'): | 539 case MKTAG('I', 'D', 'A', 'T'): |
540 if (!(s->state & PNG_IHDR)) | 540 if (!(s->state & PNG_IHDR)) |
547 s->channels = png_get_nb_channels(s->color_type); | 547 s->channels = png_get_nb_channels(s->color_type); |
548 s->bits_per_pixel = s->bit_depth * s->channels; | 548 s->bits_per_pixel = s->bit_depth * s->channels; |
549 s->bpp = (s->bits_per_pixel + 7) >> 3; | 549 s->bpp = (s->bits_per_pixel + 7) >> 3; |
550 s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3; | 550 s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3; |
551 | 551 |
552 if (s->bit_depth == 8 && | 552 if (s->bit_depth == 8 && |
553 s->color_type == PNG_COLOR_TYPE_RGB) { | 553 s->color_type == PNG_COLOR_TYPE_RGB) { |
554 avctx->pix_fmt = PIX_FMT_RGB24; | 554 avctx->pix_fmt = PIX_FMT_RGB24; |
555 } else if (s->bit_depth == 8 && | 555 } else if (s->bit_depth == 8 && |
556 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { | 556 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { |
557 avctx->pix_fmt = PIX_FMT_RGBA32; | 557 avctx->pix_fmt = PIX_FMT_RGBA32; |
558 } else if (s->bit_depth == 8 && | 558 } else if (s->bit_depth == 8 && |
559 s->color_type == PNG_COLOR_TYPE_GRAY) { | 559 s->color_type == PNG_COLOR_TYPE_GRAY) { |
560 avctx->pix_fmt = PIX_FMT_GRAY8; | 560 avctx->pix_fmt = PIX_FMT_GRAY8; |
561 } else if (s->bit_depth == 1 && | 561 } else if (s->bit_depth == 1 && |
562 s->color_type == PNG_COLOR_TYPE_GRAY) { | 562 s->color_type == PNG_COLOR_TYPE_GRAY) { |
563 avctx->pix_fmt = PIX_FMT_MONOBLACK; | 563 avctx->pix_fmt = PIX_FMT_MONOBLACK; |
564 } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) { | 564 } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) { |
565 avctx->pix_fmt = PIX_FMT_PAL8; | 565 avctx->pix_fmt = PIX_FMT_PAL8; |
566 } else { | 566 } else { |
567 goto fail; | 567 goto fail; |
568 } | 568 } |
569 if(p->data[0]) | 569 if(p->data[0]) |
570 avctx->release_buffer(avctx, p); | 570 avctx->release_buffer(avctx, p); |
571 | 571 |
572 p->reference= 0; | 572 p->reference= 0; |
573 if(avctx->get_buffer(avctx, p) < 0){ | 573 if(avctx->get_buffer(avctx, p) < 0){ |
574 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | 574 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
575 goto fail; | 575 goto fail; |
576 } | 576 } |
581 /* compute the compressed row size */ | 581 /* compute the compressed row size */ |
582 if (!s->interlace_type) { | 582 if (!s->interlace_type) { |
583 s->crow_size = s->row_size + 1; | 583 s->crow_size = s->row_size + 1; |
584 } else { | 584 } else { |
585 s->pass = 0; | 585 s->pass = 0; |
586 s->pass_row_size = png_pass_row_size(s->pass, | 586 s->pass_row_size = png_pass_row_size(s->pass, |
587 s->bits_per_pixel, | 587 s->bits_per_pixel, |
588 s->width); | 588 s->width); |
589 s->crow_size = s->pass_row_size + 1; | 589 s->crow_size = s->pass_row_size + 1; |
590 } | 590 } |
591 #ifdef DEBUG | 591 #ifdef DEBUG |
592 printf("row_size=%d crow_size =%d\n", | 592 printf("row_size=%d crow_size =%d\n", |
593 s->row_size, s->crow_size); | 593 s->row_size, s->crow_size); |
594 #endif | 594 #endif |
595 s->image_buf = p->data[0]; | 595 s->image_buf = p->data[0]; |
596 s->image_linesize = p->linesize[0]; | 596 s->image_linesize = p->linesize[0]; |
597 /* copy the palette if needed */ | 597 /* copy the palette if needed */ |
621 crc = get32(&s->bytestream); | 621 crc = get32(&s->bytestream); |
622 break; | 622 break; |
623 case MKTAG('P', 'L', 'T', 'E'): | 623 case MKTAG('P', 'L', 'T', 'E'): |
624 { | 624 { |
625 int n, i, r, g, b; | 625 int n, i, r, g, b; |
626 | 626 |
627 if ((length % 3) != 0 || length > 256 * 3) | 627 if ((length % 3) != 0 || length > 256 * 3) |
628 goto skip_tag; | 628 goto skip_tag; |
629 /* read the palette */ | 629 /* read the palette */ |
630 n = length / 3; | 630 n = length / 3; |
631 for(i=0;i<n;i++) { | 631 for(i=0;i<n;i++) { |
758 uint8_t *tmp_buf = NULL; | 758 uint8_t *tmp_buf = NULL; |
759 | 759 |
760 *p = *pict; | 760 *p = *pict; |
761 p->pict_type= FF_I_TYPE; | 761 p->pict_type= FF_I_TYPE; |
762 p->key_frame= 1; | 762 p->key_frame= 1; |
763 | 763 |
764 s->bytestream_start= | 764 s->bytestream_start= |
765 s->bytestream= buf; | 765 s->bytestream= buf; |
766 s->bytestream_end= buf+buf_size; | 766 s->bytestream_end= buf+buf_size; |
767 | 767 |
768 is_progressive = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT); | 768 is_progressive = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT); |
810 } | 810 } |
811 | 811 |
812 /* write png header */ | 812 /* write png header */ |
813 memcpy(s->bytestream, pngsig, 8); | 813 memcpy(s->bytestream, pngsig, 8); |
814 s->bytestream += 8; | 814 s->bytestream += 8; |
815 | 815 |
816 to_be32(s->buf, avctx->width); | 816 to_be32(s->buf, avctx->width); |
817 to_be32(s->buf + 4, avctx->height); | 817 to_be32(s->buf + 4, avctx->height); |
818 s->buf[8] = bit_depth; | 818 s->buf[8] = bit_depth; |
819 s->buf[9] = color_type; | 819 s->buf[9] = color_type; |
820 s->buf[10] = 0; /* compression type */ | 820 s->buf[10] = 0; /* compression type */ |
821 s->buf[11] = 0; /* filter type */ | 821 s->buf[11] = 0; /* filter type */ |
822 s->buf[12] = is_progressive; /* interlace type */ | 822 s->buf[12] = is_progressive; /* interlace type */ |
823 | 823 |
824 png_write_chunk(&s->bytestream, MKTAG('I', 'H', 'D', 'R'), s->buf, 13); | 824 png_write_chunk(&s->bytestream, MKTAG('I', 'H', 'D', 'R'), s->buf, 13); |
825 | 825 |
826 /* put the palette if needed */ | 826 /* put the palette if needed */ |
827 if (color_type == PNG_COLOR_TYPE_PALETTE) { | 827 if (color_type == PNG_COLOR_TYPE_PALETTE) { |
828 int has_alpha, alpha, i; | 828 int has_alpha, alpha, i; |
829 unsigned int v; | 829 unsigned int v; |
830 uint32_t *palette; | 830 uint32_t *palette; |
831 uint8_t *alpha_ptr; | 831 uint8_t *alpha_ptr; |
832 | 832 |
833 palette = (uint32_t *)p->data[1]; | 833 palette = (uint32_t *)p->data[1]; |
834 ptr = s->buf; | 834 ptr = s->buf; |
835 alpha_ptr = s->buf + 256 * 3; | 835 alpha_ptr = s->buf + 256 * 3; |
836 has_alpha = 0; | 836 has_alpha = 0; |
837 for(i = 0; i < 256; i++) { | 837 for(i = 0; i < 256; i++) { |
870 convert_from_rgba32(tmp_buf, ptr, avctx->width); | 870 convert_from_rgba32(tmp_buf, ptr, avctx->width); |
871 ptr1 = tmp_buf; | 871 ptr1 = tmp_buf; |
872 } else { | 872 } else { |
873 ptr1 = ptr; | 873 ptr1 = ptr; |
874 } | 874 } |
875 png_get_interlaced_row(crow_buf + 1, pass_row_size, | 875 png_get_interlaced_row(crow_buf + 1, pass_row_size, |
876 bits_per_pixel, pass, | 876 bits_per_pixel, pass, |
877 ptr1, avctx->width); | 877 ptr1, avctx->width); |
878 crow_buf[0] = PNG_FILTER_VALUE_NONE; | 878 crow_buf[0] = PNG_FILTER_VALUE_NONE; |
879 png_write_row(s, crow_buf, pass_row_size + 1); | 879 png_write_row(s, crow_buf, pass_row_size + 1); |
880 } | 880 } |
881 } | 881 } |