diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-01-30 08:20:58 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-01-30 08:20:58 +0400 |
commit | e1492151fb0c1ad2a9efbb2f2413b60113208b61 (patch) | |
tree | e4852fd092e2b2346c21e87d8b69987b2b4c2a68 /libavcodec/pngdec.c | |
parent | 90bf7c7b41c9e78663ef3da00480f70854072932 (diff) | |
parent | 20a7d3178f2370ebd1f548c144bc90d1e1bcd81a (diff) |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
png: add missing #if HAVE_SSSE3 around function pointer assignment.
imdct36: mark SSE functions as using all 16 XMM registers.
png: move DSP functions to their own DSP context.
sunrast: Add a sample request for TIFF, IFF, and Experimental Rastfile formats.
sunrast: Cosmetics
sunrast: Remove if (unsigned int < 0) check.
sunrast: Replace magic number by a macro.
Conflicts:
libavcodec/dsputil.c
libavcodec/dsputil.h
libavcodec/pngdec.c
libavcodec/sunrast.c
libavcodec/x86/Makefile
libavcodec/x86/dsputil_mmx.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/pngdec.c')
-rw-r--r-- | libavcodec/pngdec.c | 72 |
1 files changed, 43 insertions, 29 deletions
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index c016a62d50..392395aac7 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -25,6 +25,7 @@ #include "avcodec.h" #include "bytestream.h" #include "png.h" +#include "pngdsp.h" /* TODO: * - add 16 bit depth support @@ -32,6 +33,42 @@ #include <zlib.h> +//#define DEBUG + +typedef struct PNGDecContext { + PNGDSPContext dsp; + + const uint8_t *bytestream; + const uint8_t *bytestream_start; + const uint8_t *bytestream_end; + AVFrame picture1, picture2; + AVFrame *current_picture, *last_picture; + + int state; + int width, height; + int bit_depth; + int color_type; + int compression_type; + int interlace_type; + int filter_type; + int channels; + int bits_per_pixel; + int bpp; + + uint8_t *image_buf; + int image_linesize; + uint32_t palette[256]; + uint8_t *crow_buf; + uint8_t *last_row; + uint8_t *tmp_row; + int pass; + int crow_size; /* compressed row size (include filter type) */ + int row_size; /* decompressed row size */ + int pass_row_size; /* decompress row size of the current pass */ + int y; + z_stream zstream; +} PNGDecContext; + /* Mask to determine which y pixels can be written in a pass */ static const uint8_t png_pass_dsp_ymask[NB_PASSES] = { 0xff, 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, @@ -114,23 +151,7 @@ static void png_put_interlaced_row(uint8_t *dst, int width, } } -// 0x7f7f7f7f or 0x7f7f7f7f7f7f7f7f or whatever, depending on the cpu's native arithmetic size -#define pb_7f (~0UL/255 * 0x7f) -#define pb_80 (~0UL/255 * 0x80) - -static void add_bytes_l2_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w) -{ - long i; - for(i=0; i<=w-sizeof(long); i+=sizeof(long)){ - long a = *(long*)(src1+i); - long b = *(long*)(src2+i); - *(long*)(dst+i) = ((a&pb_7f) + (b&pb_7f)) ^ ((a^b)&pb_80); - } - for(; i<w; i++) - dst[i] = src1[i]+src2[i]; -} - -static void add_paeth_prediction_c(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp) +void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp) { int i; for(i = 0; i < w; i++) { @@ -187,7 +208,7 @@ static void add_paeth_prediction_c(uint8_t *dst, uint8_t *src, uint8_t *top, int } /* NOTE: 'dst' can be equal to 'last' */ -static void png_filter_row(PNGDecContext *s, uint8_t *dst, int filter_type, +static void png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type, uint8_t *src, uint8_t *last, int size, int bpp) { int i, p, r, g, b, a; @@ -213,7 +234,7 @@ static void png_filter_row(PNGDecContext *s, uint8_t *dst, int filter_type, } break; case PNG_FILTER_VALUE_UP: - s->add_bytes_l2(dst, src, last, size); + dsp->add_bytes_l2(dst, src, last, size); break; case PNG_FILTER_VALUE_AVG: for(i = 0; i < bpp; i++) { @@ -231,10 +252,10 @@ static void png_filter_row(PNGDecContext *s, uint8_t *dst, int filter_type, if(bpp > 2 && size > 4) { // would write off the end of the array if we let it process the last pixel with bpp=3 int w = bpp==4 ? size : size-3; - s->add_paeth_prediction(dst+i, src+i, last+i, w-i, bpp); + dsp->add_paeth_prediction(dst+i, src+i, last+i, w-i, bpp); i = w; } - add_paeth_prediction_c(dst+i, src+i, last+i, size-i, bpp); + ff_add_png_paeth_prediction(dst+i, src+i, last+i, size-i, bpp); break; } } @@ -704,14 +725,7 @@ static av_cold int png_dec_init(AVCodecContext *avctx) avcodec_get_frame_defaults(&s->picture1); avcodec_get_frame_defaults(&s->picture2); -#if HAVE_MMX - ff_png_init_mmx(s); -#endif - - if (!s->add_paeth_prediction) - s->add_paeth_prediction = add_paeth_prediction_c; - if (!s->add_bytes_l2) - s->add_bytes_l2 = add_bytes_l2_c; + ff_pngdsp_init(&s->dsp); return 0; } |