summaryrefslogtreecommitdiff
path: root/libavcodec/pngdec.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-01-30 05:20:58 +0100
committerMichael Niedermayer <michaelni@gmx.at>2012-01-30 05:20:58 +0100
commite1492151fb0c1ad2a9efbb2f2413b60113208b61 (patch)
treee4852fd092e2b2346c21e87d8b69987b2b4c2a68 /libavcodec/pngdec.c
parent90bf7c7b41c9e78663ef3da00480f70854072932 (diff)
parent20a7d3178f2370ebd1f548c144bc90d1e1bcd81a (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.c72
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;
}