Originally committed as revision 12164 to svn://svn.ffmpeg.org/ffmpeg/trunk
Loren Merritt authored on 2008/02/21 16:10:46... | ... |
@@ -44,6 +44,9 @@ void vorbis_inverse_coupling(float *mag, float *ang, int blocksize); |
44 | 44 |
/* flacenc.c */ |
45 | 45 |
void ff_flac_compute_autocorr(const int32_t *data, int len, int lag, double *autoc); |
46 | 46 |
|
47 |
+/* pngdec.c */ |
|
48 |
+void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp); |
|
49 |
+ |
|
47 | 50 |
uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP] = {0, }; |
48 | 51 |
uint32_t ff_squareTbl[512] = {0, }; |
49 | 52 |
|
... | ... |
@@ -3288,6 +3291,17 @@ static void add_bytes_c(uint8_t *dst, uint8_t *src, int w){ |
3288 | 3288 |
dst[i+0] += src[i+0]; |
3289 | 3289 |
} |
3290 | 3290 |
|
3291 |
+static void add_bytes_l2_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){ |
|
3292 |
+ int i; |
|
3293 |
+ for(i=0; i<=w-sizeof(long); i+=sizeof(long)){ |
|
3294 |
+ long a = *(long*)(src1+i); |
|
3295 |
+ long b = *(long*)(src2+i); |
|
3296 |
+ *(long*)(dst+i) = ((a&0x7f7f7f7f7f7f7f7fL) + (b&0x7f7f7f7f7f7f7f7fL)) ^ ((a^b)&0x8080808080808080L); |
|
3297 |
+ } |
|
3298 |
+ for(; i<w; i++) |
|
3299 |
+ dst[i] = src1[i]+src2[i]; |
|
3300 |
+} |
|
3301 |
+ |
|
3291 | 3302 |
static void diff_bytes_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){ |
3292 | 3303 |
int i; |
3293 | 3304 |
for(i=0; i+7<w; i+=8){ |
... | ... |
@@ -4232,9 +4246,13 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx) |
4232 | 4232 |
c->ssd_int8_vs_int16 = ssd_int8_vs_int16_c; |
4233 | 4233 |
|
4234 | 4234 |
c->add_bytes= add_bytes_c; |
4235 |
+ c->add_bytes_l2= add_bytes_l2_c; |
|
4235 | 4236 |
c->diff_bytes= diff_bytes_c; |
4236 | 4237 |
c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_c; |
4237 | 4238 |
c->bswap_buf= bswap_buf; |
4239 |
+#ifdef CONFIG_PNG_DECODER |
|
4240 |
+ c->add_png_paeth_prediction= ff_add_png_paeth_prediction; |
|
4241 |
+#endif |
|
4238 | 4242 |
|
4239 | 4243 |
c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_c; |
4240 | 4244 |
c->h264_h_loop_filter_luma= h264_h_loop_filter_luma_c; |
... | ... |
@@ -304,12 +304,15 @@ typedef struct DSPContext { |
304 | 304 |
|
305 | 305 |
/* huffyuv specific */ |
306 | 306 |
void (*add_bytes)(uint8_t *dst/*align 16*/, uint8_t *src/*align 16*/, int w); |
307 |
+ void (*add_bytes_l2)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 16*/, int w); |
|
307 | 308 |
void (*diff_bytes)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 1*/,int w); |
308 | 309 |
/** |
309 | 310 |
* subtract huffyuv's variant of median prediction |
310 | 311 |
* note, this might read from src1[-1], src2[-1] |
311 | 312 |
*/ |
312 | 313 |
void (*sub_hfyu_median_prediction)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top); |
314 |
+ /* this might write to dst[w] */ |
|
315 |
+ void (*add_png_paeth_prediction)(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp); |
|
313 | 316 |
void (*bswap_buf)(uint32_t *dst, const uint32_t *src, int w); |
314 | 317 |
|
315 | 318 |
void (*h264_v_loop_filter_luma)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0); |
... | ... |
@@ -59,6 +59,7 @@ DECLARE_ALIGNED_8 (const uint64_t, ff_pw_42 ) = 0x002A002A002A002AULL; |
59 | 59 |
DECLARE_ALIGNED_8 (const uint64_t, ff_pw_64 ) = 0x0040004000400040ULL; |
60 | 60 |
DECLARE_ALIGNED_8 (const uint64_t, ff_pw_96 ) = 0x0060006000600060ULL; |
61 | 61 |
DECLARE_ALIGNED_8 (const uint64_t, ff_pw_128) = 0x0080008000800080ULL; |
62 |
+DECLARE_ALIGNED_8 (const uint64_t, ff_pw_255) = 0x00ff00ff00ff00ffULL; |
|
62 | 63 |
|
63 | 64 |
DECLARE_ALIGNED_8 (const uint64_t, ff_pb_1 ) = 0x0101010101010101ULL; |
64 | 65 |
DECLARE_ALIGNED_8 (const uint64_t, ff_pb_3 ) = 0x0303030303030303ULL; |
... | ... |
@@ -605,6 +606,26 @@ static void add_bytes_mmx(uint8_t *dst, uint8_t *src, int w){ |
605 | 605 |
dst[i+0] += src[i+0]; |
606 | 606 |
} |
607 | 607 |
|
608 |
+static void add_bytes_l2_mmx(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){ |
|
609 |
+ long i=0; |
|
610 |
+ asm volatile( |
|
611 |
+ "1: \n\t" |
|
612 |
+ "movq (%2, %0), %%mm0 \n\t" |
|
613 |
+ "movq 8(%2, %0), %%mm1 \n\t" |
|
614 |
+ "paddb (%3, %0), %%mm0 \n\t" |
|
615 |
+ "paddb 8(%3, %0), %%mm1 \n\t" |
|
616 |
+ "movq %%mm0, (%1, %0) \n\t" |
|
617 |
+ "movq %%mm1, 8(%1, %0) \n\t" |
|
618 |
+ "add $16, %0 \n\t" |
|
619 |
+ "cmp %4, %0 \n\t" |
|
620 |
+ " jb 1b \n\t" |
|
621 |
+ : "+r" (i) |
|
622 |
+ : "r"(dst), "r"(src1), "r"(src2), "r"((long)w-15) |
|
623 |
+ ); |
|
624 |
+ for(; i<w; i++) |
|
625 |
+ dst[i] = src1[i] + src2[i]; |
|
626 |
+} |
|
627 |
+ |
|
608 | 628 |
#define H263_LOOP_FILTER \ |
609 | 629 |
"pxor %%mm7, %%mm7 \n\t"\ |
610 | 630 |
"movq %0, %%mm0 \n\t"\ |
... | ... |
@@ -1564,6 +1585,80 @@ static void sub_hfyu_median_prediction_mmx2(uint8_t *dst, uint8_t *src1, uint8_t |
1564 | 1564 |
*left = src2[w-1]; |
1565 | 1565 |
} |
1566 | 1566 |
|
1567 |
+#define PAETH(cpu, abs3)\ |
|
1568 |
+void add_png_paeth_prediction_##cpu(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp)\ |
|
1569 |
+{\ |
|
1570 |
+ long i = -bpp;\ |
|
1571 |
+ long end = w-3;\ |
|
1572 |
+ asm volatile(\ |
|
1573 |
+ "pxor %%mm7, %%mm7 \n"\ |
|
1574 |
+ "movd (%1,%0), %%mm0 \n"\ |
|
1575 |
+ "movd (%2,%0), %%mm1 \n"\ |
|
1576 |
+ "punpcklbw %%mm7, %%mm0 \n"\ |
|
1577 |
+ "punpcklbw %%mm7, %%mm1 \n"\ |
|
1578 |
+ "add %4, %0 \n"\ |
|
1579 |
+ "1: \n"\ |
|
1580 |
+ "movq %%mm1, %%mm2 \n"\ |
|
1581 |
+ "movd (%2,%0), %%mm1 \n"\ |
|
1582 |
+ "movq %%mm2, %%mm3 \n"\ |
|
1583 |
+ "punpcklbw %%mm7, %%mm1 \n"\ |
|
1584 |
+ "movq %%mm2, %%mm4 \n"\ |
|
1585 |
+ "psubw %%mm1, %%mm3 \n"\ |
|
1586 |
+ "psubw %%mm0, %%mm4 \n"\ |
|
1587 |
+ "movq %%mm3, %%mm5 \n"\ |
|
1588 |
+ "paddw %%mm4, %%mm5 \n"\ |
|
1589 |
+ abs3\ |
|
1590 |
+ "movq %%mm4, %%mm6 \n"\ |
|
1591 |
+ "pminsw %%mm5, %%mm6 \n"\ |
|
1592 |
+ "pcmpgtw %%mm6, %%mm3 \n"\ |
|
1593 |
+ "pcmpgtw %%mm5, %%mm4 \n"\ |
|
1594 |
+ "movq %%mm4, %%mm6 \n"\ |
|
1595 |
+ "pand %%mm3, %%mm4 \n"\ |
|
1596 |
+ "pandn %%mm3, %%mm6 \n"\ |
|
1597 |
+ "pandn %%mm0, %%mm3 \n"\ |
|
1598 |
+ "movd (%3,%0), %%mm0 \n"\ |
|
1599 |
+ "pand %%mm1, %%mm6 \n"\ |
|
1600 |
+ "pand %%mm4, %%mm2 \n"\ |
|
1601 |
+ "punpcklbw %%mm7, %%mm0 \n"\ |
|
1602 |
+ "movq %6, %%mm5 \n"\ |
|
1603 |
+ "paddw %%mm6, %%mm0 \n"\ |
|
1604 |
+ "paddw %%mm2, %%mm3 \n"\ |
|
1605 |
+ "paddw %%mm3, %%mm0 \n"\ |
|
1606 |
+ "pand %%mm5, %%mm0 \n"\ |
|
1607 |
+ "movq %%mm0, %%mm3 \n"\ |
|
1608 |
+ "packuswb %%mm3, %%mm3 \n"\ |
|
1609 |
+ "movd %%mm3, (%1,%0) \n"\ |
|
1610 |
+ "add %4, %0 \n"\ |
|
1611 |
+ "cmp %5, %0 \n"\ |
|
1612 |
+ "jle 1b \n"\ |
|
1613 |
+ :"+r"(i)\ |
|
1614 |
+ :"r"(dst), "r"(top), "r"(src), "r"((long)bpp), "g"(end),\ |
|
1615 |
+ "m"(ff_pw_255)\ |
|
1616 |
+ :"memory"\ |
|
1617 |
+ );\ |
|
1618 |
+} |
|
1619 |
+ |
|
1620 |
+#define ABS3_MMX2\ |
|
1621 |
+ "psubw %%mm5, %%mm7 \n"\ |
|
1622 |
+ "pmaxsw %%mm7, %%mm5 \n"\ |
|
1623 |
+ "pxor %%mm6, %%mm6 \n"\ |
|
1624 |
+ "pxor %%mm7, %%mm7 \n"\ |
|
1625 |
+ "psubw %%mm3, %%mm6 \n"\ |
|
1626 |
+ "psubw %%mm4, %%mm7 \n"\ |
|
1627 |
+ "pmaxsw %%mm6, %%mm3 \n"\ |
|
1628 |
+ "pmaxsw %%mm7, %%mm4 \n"\ |
|
1629 |
+ "pxor %%mm7, %%mm7 \n" |
|
1630 |
+ |
|
1631 |
+#define ABS3_SSSE3\ |
|
1632 |
+ "pabsw %%mm3, %%mm3 \n"\ |
|
1633 |
+ "pabsw %%mm4, %%mm4 \n"\ |
|
1634 |
+ "pabsw %%mm5, %%mm5 \n" |
|
1635 |
+ |
|
1636 |
+PAETH(mmx2, ABS3_MMX2) |
|
1637 |
+#ifdef HAVE_SSSE3 |
|
1638 |
+PAETH(ssse3, ABS3_SSSE3) |
|
1639 |
+#endif |
|
1640 |
+ |
|
1567 | 1641 |
#define DIFF_PIXELS_1(m,a,t,p1,p2)\ |
1568 | 1642 |
"mov"#m" "#p1", "#a" \n\t"\ |
1569 | 1643 |
"mov"#m" "#p2", "#t" \n\t"\ |
... | ... |
@@ -3317,6 +3412,7 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) |
3317 | 3317 |
c->gmc= gmc_mmx; |
3318 | 3318 |
|
3319 | 3319 |
c->add_bytes= add_bytes_mmx; |
3320 |
+ c->add_bytes_l2= add_bytes_l2_mmx; |
|
3320 | 3321 |
#ifdef CONFIG_ENCODERS |
3321 | 3322 |
c->diff_bytes= diff_bytes_mmx; |
3322 | 3323 |
c->sum_abs_dctelem= sum_abs_dctelem_mmx; |
... | ... |
@@ -3471,6 +3567,7 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) |
3471 | 3471 |
if (ENABLE_VC1_DECODER || ENABLE_WMV3_DECODER) |
3472 | 3472 |
ff_vc1dsp_init_mmx(c, avctx); |
3473 | 3473 |
|
3474 |
+ c->add_png_paeth_prediction= add_png_paeth_prediction_mmx2; |
|
3474 | 3475 |
#ifdef CONFIG_ENCODERS |
3475 | 3476 |
c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_mmx2; |
3476 | 3477 |
#endif //CONFIG_ENCODERS |
... | ... |
@@ -3565,6 +3662,7 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) |
3565 | 3565 |
H264_QPEL_FUNCS(3, 1, ssse3); |
3566 | 3566 |
H264_QPEL_FUNCS(3, 2, ssse3); |
3567 | 3567 |
H264_QPEL_FUNCS(3, 3, ssse3); |
3568 |
+ c->add_png_paeth_prediction= add_png_paeth_prediction_ssse3; |
|
3568 | 3569 |
} |
3569 | 3570 |
#endif |
3570 | 3571 |
|
... | ... |
@@ -21,6 +21,7 @@ |
21 | 21 |
#include "avcodec.h" |
22 | 22 |
#include "bytestream.h" |
23 | 23 |
#include "png.h" |
24 |
+#include "dsputil.h" |
|
24 | 25 |
|
25 | 26 |
/* TODO: |
26 | 27 |
* - add 2, 4 and 16 bit depth support |
... | ... |
@@ -31,6 +32,8 @@ |
31 | 31 |
//#define DEBUG |
32 | 32 |
|
33 | 33 |
typedef struct PNGDecContext { |
34 |
+ DSPContext dsp; |
|
35 |
+ |
|
34 | 36 |
const uint8_t *bytestream; |
35 | 37 |
const uint8_t *bytestream_start; |
36 | 38 |
const uint8_t *bytestream_end; |
... | ... |
@@ -129,12 +132,60 @@ static void png_put_interlaced_row(uint8_t *dst, int width, |
129 | 129 |
} |
130 | 130 |
} |
131 | 131 |
|
132 |
-/* XXX: optimize */ |
|
132 |
+void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp) |
|
133 |
+{ |
|
134 |
+ int i; |
|
135 |
+ for(i = 0; i < w; i++) { |
|
136 |
+ int a, b, c, p, pa, pb, pc; |
|
137 |
+ |
|
138 |
+ a = dst[i - bpp]; |
|
139 |
+ b = top[i]; |
|
140 |
+ c = top[i - bpp]; |
|
141 |
+ |
|
142 |
+ p = b - c; |
|
143 |
+ pc = a - c; |
|
144 |
+ |
|
145 |
+ pa = abs(p); |
|
146 |
+ pb = abs(pc); |
|
147 |
+ pc = abs(p + pc); |
|
148 |
+ |
|
149 |
+ if (pa <= pb && pa <= pc) |
|
150 |
+ p = a; |
|
151 |
+ else if (pb <= pc) |
|
152 |
+ p = b; |
|
153 |
+ else |
|
154 |
+ p = c; |
|
155 |
+ dst[i] = p + src[i]; |
|
156 |
+ } |
|
157 |
+} |
|
158 |
+ |
|
159 |
+#define UNROLL1(bpp, op) {\ |
|
160 |
+ r = dst[0];\ |
|
161 |
+ if(bpp >= 2) g = dst[1];\ |
|
162 |
+ if(bpp >= 3) b = dst[2];\ |
|
163 |
+ if(bpp >= 4) a = dst[3];\ |
|
164 |
+ for(; i < size; i+=bpp) {\ |
|
165 |
+ dst[i+0] = r = op(r, src[i+0], last[i+0]);\ |
|
166 |
+ if(bpp == 1) continue;\ |
|
167 |
+ dst[i+1] = g = op(g, src[i+1], last[i+1]);\ |
|
168 |
+ if(bpp == 2) continue;\ |
|
169 |
+ dst[i+2] = b = op(b, src[i+2], last[i+2]);\ |
|
170 |
+ if(bpp == 3) continue;\ |
|
171 |
+ dst[i+3] = a = op(a, src[i+3], last[i+3]);\ |
|
172 |
+ }\ |
|
173 |
+} |
|
174 |
+ |
|
175 |
+#define UNROLL_FILTER(op)\ |
|
176 |
+ if(bpp == 1) UNROLL1(1, op)\ |
|
177 |
+ else if(bpp == 2) UNROLL1(2, op)\ |
|
178 |
+ else if(bpp == 3) UNROLL1(3, op)\ |
|
179 |
+ else if(bpp == 4) UNROLL1(4, op)\ |
|
180 |
+ |
|
133 | 181 |
/* NOTE: 'dst' can be equal to 'last' */ |
134 |
-static void png_filter_row(uint8_t *dst, int filter_type, |
|
182 |
+static void png_filter_row(DSPContext *dsp, uint8_t *dst, int filter_type, |
|
135 | 183 |
uint8_t *src, uint8_t *last, int size, int bpp) |
136 | 184 |
{ |
137 |
- int i, p; |
|
185 |
+ int i, p, r, g, b, a; |
|
138 | 186 |
|
139 | 187 |
switch(filter_type) { |
140 | 188 |
case PNG_FILTER_VALUE_NONE: |
... | ... |
@@ -144,54 +195,41 @@ static void png_filter_row(uint8_t *dst, int filter_type, |
144 | 144 |
for(i = 0; i < bpp; i++) { |
145 | 145 |
dst[i] = src[i]; |
146 | 146 |
} |
147 |
- for(i = bpp; i < size; i++) { |
|
148 |
- p = dst[i - bpp]; |
|
149 |
- dst[i] = p + src[i]; |
|
147 |
+ if(bpp == 4) { |
|
148 |
+ p = *(int*)dst; |
|
149 |
+ for(; i < size; i+=bpp) { |
|
150 |
+ int s = *(int*)(src+i); |
|
151 |
+ p = ((s&0x7f7f7f7f) + (p&0x7f7f7f7f)) ^ ((s^p)&0x80808080); |
|
152 |
+ *(int*)(dst+i) = p; |
|
153 |
+ } |
|
154 |
+ } else { |
|
155 |
+#define OP_SUB(x,s,l) x+s |
|
156 |
+ UNROLL_FILTER(OP_SUB); |
|
150 | 157 |
} |
151 | 158 |
break; |
152 | 159 |
case PNG_FILTER_VALUE_UP: |
153 |
- for(i = 0; i < size; i++) { |
|
154 |
- p = last[i]; |
|
155 |
- dst[i] = p + src[i]; |
|
156 |
- } |
|
160 |
+ dsp->add_bytes_l2(dst, src, last, size); |
|
157 | 161 |
break; |
158 | 162 |
case PNG_FILTER_VALUE_AVG: |
159 | 163 |
for(i = 0; i < bpp; i++) { |
160 | 164 |
p = (last[i] >> 1); |
161 | 165 |
dst[i] = p + src[i]; |
162 | 166 |
} |
163 |
- for(i = bpp; i < size; i++) { |
|
164 |
- p = ((dst[i - bpp] + last[i]) >> 1); |
|
165 |
- dst[i] = p + src[i]; |
|
166 |
- } |
|
167 |
+#define OP_AVG(x,s,l) (((x + l) >> 1) + s) & 0xff |
|
168 |
+ UNROLL_FILTER(OP_AVG); |
|
167 | 169 |
break; |
168 | 170 |
case PNG_FILTER_VALUE_PAETH: |
169 | 171 |
for(i = 0; i < bpp; i++) { |
170 | 172 |
p = last[i]; |
171 | 173 |
dst[i] = p + src[i]; |
172 | 174 |
} |
173 |
- for(i = bpp; i < size; i++) { |
|
174 |
- int a, b, c, pa, pb, pc; |
|
175 |
- |
|
176 |
- a = dst[i - bpp]; |
|
177 |
- b = last[i]; |
|
178 |
- c = last[i - bpp]; |
|
179 |
- |
|
180 |
- p = b - c; |
|
181 |
- pc = a - c; |
|
182 |
- |
|
183 |
- pa = abs(p); |
|
184 |
- pb = abs(pc); |
|
185 |
- pc = abs(p + pc); |
|
186 |
- |
|
187 |
- if (pa <= pb && pa <= pc) |
|
188 |
- p = a; |
|
189 |
- else if (pb <= pc) |
|
190 |
- p = b; |
|
191 |
- else |
|
192 |
- p = c; |
|
193 |
- dst[i] = p + src[i]; |
|
175 |
+ if(bpp > 1 && size > 4) { |
|
176 |
+ // would write off the end of the array if we let it process the last pixel with bpp=3 |
|
177 |
+ int w = bpp==4 ? size : size-3; |
|
178 |
+ dsp->add_png_paeth_prediction(dst+i, src+i, last+i, w-i, bpp); |
|
179 |
+ i = w; |
|
194 | 180 |
} |
181 |
+ ff_add_png_paeth_prediction(dst+i, src+i, last+i, size-i, bpp); |
|
195 | 182 |
break; |
196 | 183 |
} |
197 | 184 |
} |
... | ... |
@@ -222,7 +260,7 @@ static void png_handle_row(PNGDecContext *s) |
222 | 222 |
ptr = s->image_buf + s->image_linesize * s->y; |
223 | 223 |
/* need to swap bytes correctly for RGB_ALPHA */ |
224 | 224 |
if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { |
225 |
- png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1, |
|
225 |
+ png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1, |
|
226 | 226 |
s->last_row, s->row_size, s->bpp); |
227 | 227 |
memcpy(s->last_row, s->tmp_row, s->row_size); |
228 | 228 |
convert_to_rgb32(ptr, s->tmp_row, s->width); |
... | ... |
@@ -233,7 +271,7 @@ static void png_handle_row(PNGDecContext *s) |
233 | 233 |
else |
234 | 234 |
last_row = ptr - s->image_linesize; |
235 | 235 |
|
236 |
- png_filter_row(ptr, s->crow_buf[0], s->crow_buf + 1, |
|
236 |
+ png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1, |
|
237 | 237 |
last_row, s->row_size, s->bpp); |
238 | 238 |
} |
239 | 239 |
s->y++; |
... | ... |
@@ -249,7 +287,7 @@ static void png_handle_row(PNGDecContext *s) |
249 | 249 |
wait for the next one */ |
250 | 250 |
if (got_line) |
251 | 251 |
break; |
252 |
- png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1, |
|
252 |
+ png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1, |
|
253 | 253 |
s->last_row, s->pass_row_size, s->bpp); |
254 | 254 |
memcpy(s->last_row, s->tmp_row, s->pass_row_size); |
255 | 255 |
got_line = 1; |
... | ... |
@@ -534,6 +572,7 @@ static int png_dec_init(AVCodecContext *avctx){ |
534 | 534 |
|
535 | 535 |
avcodec_get_frame_defaults((AVFrame*)&s->picture); |
536 | 536 |
avctx->coded_frame= (AVFrame*)&s->picture; |
537 |
+ dsputil_init(&s->dsp, avctx); |
|
537 | 538 |
|
538 | 539 |
return 0; |
539 | 540 |
} |