Statistics
| Branch: | Revision:

ffmpeg / libavcodec / pngdec.c @ 045cc36f

History | View | Annotate | Download (21.4 KB)

1
/*
2
 * PNG image format
3
 * Copyright (c) 2003 Fabrice Bellard
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21

    
22
//#define DEBUG
23

    
24
#include "libavutil/imgutils.h"
25
#include "avcodec.h"
26
#include "bytestream.h"
27
#include "png.h"
28

    
29
/* TODO:
30
 * - add 2, 4 and 16 bit depth support
31
 */
32

    
33
#include <zlib.h>
34

    
35
/* Mask to determine which y pixels can be written in a pass */
36
static const uint8_t png_pass_dsp_ymask[NB_PASSES] = {
37
    0xff, 0xff, 0x0f, 0xcc, 0x33, 0xff, 0x55,
38
};
39

    
40
/* Mask to determine which pixels to overwrite while displaying */
41
static const uint8_t png_pass_dsp_mask[NB_PASSES] = {
42
    0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff
43
};
44

    
45
/* NOTE: we try to construct a good looking image at each pass. width
46
   is the original image width. We also do pixel format conversion at
47
   this stage */
48
static void png_put_interlaced_row(uint8_t *dst, int width,
49
                                   int bits_per_pixel, int pass,
50
                                   int color_type, const uint8_t *src)
51
{
52
    int x, mask, dsp_mask, j, src_x, b, bpp;
53
    uint8_t *d;
54
    const uint8_t *s;
55

    
56
    mask = ff_png_pass_mask[pass];
57
    dsp_mask = png_pass_dsp_mask[pass];
58
    switch(bits_per_pixel) {
59
    case 1:
60
        /* we must initialize the line to zero before writing to it */
61
        if (pass == 0)
62
            memset(dst, 0, (width + 7) >> 3);
63
        src_x = 0;
64
        for(x = 0; x < width; x++) {
65
            j = (x & 7);
66
            if ((dsp_mask << j) & 0x80) {
67
                b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1;
68
                dst[x >> 3] |= b << (7 - j);
69
            }
70
            if ((mask << j) & 0x80)
71
                src_x++;
72
        }
73
        break;
74
    default:
75
        bpp = bits_per_pixel >> 3;
76
        d = dst;
77
        s = src;
78
        if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
79
            for(x = 0; x < width; x++) {
80
                j = x & 7;
81
                if ((dsp_mask << j) & 0x80) {
82
                    *(uint32_t *)d = (s[3] << 24) | (s[0] << 16) | (s[1] << 8) | s[2];
83
                }
84
                d += bpp;
85
                if ((mask << j) & 0x80)
86
                    s += bpp;
87
            }
88
        } else {
89
            for(x = 0; x < width; x++) {
90
                j = x & 7;
91
                if ((dsp_mask << j) & 0x80) {
92
                    memcpy(d, s, bpp);
93
                }
94
                d += bpp;
95
                if ((mask << j) & 0x80)
96
                    s += bpp;
97
            }
98
        }
99
        break;
100
    }
101
}
102

    
103
// 0x7f7f7f7f or 0x7f7f7f7f7f7f7f7f or whatever, depending on the cpu's native arithmetic size
104
#define pb_7f (~0UL/255 * 0x7f)
105
#define pb_80 (~0UL/255 * 0x80)
106

    
107
static void add_bytes_l2_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w)
108
{
109
    long i;
110
    for(i=0; i<=w-sizeof(long); i+=sizeof(long)){
111
        long a = *(long*)(src1+i);
112
        long b = *(long*)(src2+i);
113
        *(long*)(dst+i) = ((a&pb_7f) + (b&pb_7f)) ^ ((a^b)&pb_80);
114
    }
115
    for(; i<w; i++)
116
        dst[i] = src1[i]+src2[i];
117
}
118

    
119
static void add_paeth_prediction_c(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp)
120
{
121
    int i;
122
    for(i = 0; i < w; i++) {
123
        int a, b, c, p, pa, pb, pc;
124

    
125
        a = dst[i - bpp];
126
        b = top[i];
127
        c = top[i - bpp];
128

    
129
        p = b - c;
130
        pc = a - c;
131

    
132
        pa = abs(p);
133
        pb = abs(pc);
134
        pc = abs(p + pc);
135

    
136
        if (pa <= pb && pa <= pc)
137
            p = a;
138
        else if (pb <= pc)
139
            p = b;
140
        else
141
            p = c;
142
        dst[i] = p + src[i];
143
    }
144
}
145

    
146
#define UNROLL1(bpp, op) {\
147
                 r = dst[0];\
148
    if(bpp >= 2) g = dst[1];\
149
    if(bpp >= 3) b = dst[2];\
150
    if(bpp >= 4) a = dst[3];\
151
    for(; i < size; i+=bpp) {\
152
        dst[i+0] = r = op(r, src[i+0], last[i+0]);\
153
        if(bpp == 1) continue;\
154
        dst[i+1] = g = op(g, src[i+1], last[i+1]);\
155
        if(bpp == 2) continue;\
156
        dst[i+2] = b = op(b, src[i+2], last[i+2]);\
157
        if(bpp == 3) continue;\
158
        dst[i+3] = a = op(a, src[i+3], last[i+3]);\
159
    }\
160
}
161

    
162
#define UNROLL_FILTER(op)\
163
         if(bpp == 1) UNROLL1(1, op)\
164
    else if(bpp == 2) UNROLL1(2, op)\
165
    else if(bpp == 3) UNROLL1(3, op)\
166
    else if(bpp == 4) UNROLL1(4, op)\
167
    else {\
168
        for (; i < size; i += bpp) {\
169
            int j;\
170
            for (j = 0; j < bpp; j++)\
171
                dst[i+j] = op(dst[i+j-bpp], src[i+j], last[i+j]);\
172
        }\
173
    }
174

    
175
/* NOTE: 'dst' can be equal to 'last' */
176
static void png_filter_row(PNGDecContext *s, uint8_t *dst, int filter_type,
177
                           uint8_t *src, uint8_t *last, int size, int bpp)
178
{
179
    int i, p, r, g, b, a;
180

    
181
    switch(filter_type) {
182
    case PNG_FILTER_VALUE_NONE:
183
        memcpy(dst, src, size);
184
        break;
185
    case PNG_FILTER_VALUE_SUB:
186
        for(i = 0; i < bpp; i++) {
187
            dst[i] = src[i];
188
        }
189
        if(bpp == 4) {
190
            p = *(int*)dst;
191
            for(; i < size; i+=bpp) {
192
                int s = *(int*)(src+i);
193
                p = ((s&0x7f7f7f7f) + (p&0x7f7f7f7f)) ^ ((s^p)&0x80808080);
194
                *(int*)(dst+i) = p;
195
            }
196
        } else {
197
#define OP_SUB(x,s,l) x+s
198
            UNROLL_FILTER(OP_SUB);
199
        }
200
        break;
201
    case PNG_FILTER_VALUE_UP:
202
        s->add_bytes_l2(dst, src, last, size);
203
        break;
204
    case PNG_FILTER_VALUE_AVG:
205
        for(i = 0; i < bpp; i++) {
206
            p = (last[i] >> 1);
207
            dst[i] = p + src[i];
208
        }
209
#define OP_AVG(x,s,l) (((x + l) >> 1) + s) & 0xff
210
        UNROLL_FILTER(OP_AVG);
211
        break;
212
    case PNG_FILTER_VALUE_PAETH:
213
        for(i = 0; i < bpp; i++) {
214
            p = last[i];
215
            dst[i] = p + src[i];
216
        }
217
        if(bpp > 1 && size > 4) {
218
            // would write off the end of the array if we let it process the last pixel with bpp=3
219
            int w = bpp==4 ? size : size-3;
220
            s->add_paeth_prediction(dst+i, src+i, last+i, w-i, bpp);
221
            i = w;
222
        }
223
        add_paeth_prediction_c(dst+i, src+i, last+i, size-i, bpp);
224
        break;
225
    }
226
}
227

    
228
static av_always_inline void convert_to_rgb32_loco(uint8_t *dst, const uint8_t *src, int width, int loco)
229
{
230
    int j;
231
    unsigned int r, g, b, a;
232

    
233
    for(j = 0;j < width; j++) {
234
        r = src[0];
235
        g = src[1];
236
        b = src[2];
237
        a = src[3];
238
        if(loco) {
239
            r = (r+g)&0xff;
240
            b = (b+g)&0xff;
241
        }
242
        *(uint32_t *)dst = (a << 24) | (r << 16) | (g << 8) | b;
243
        dst += 4;
244
        src += 4;
245
    }
246
}
247

    
248
static void convert_to_rgb32(uint8_t *dst, const uint8_t *src, int width, int loco)
249
{
250
    if(loco)
251
        convert_to_rgb32_loco(dst, src, width, 1);
252
    else
253
        convert_to_rgb32_loco(dst, src, width, 0);
254
}
255

    
256
static void deloco_rgb24(uint8_t *dst, int size)
257
{
258
    int i;
259
    for(i=0; i<size; i+=3) {
260
        int g = dst[i+1];
261
        dst[i+0] += g;
262
        dst[i+2] += g;
263
    }
264
}
265

    
266
/* process exactly one decompressed row */
267
static void png_handle_row(PNGDecContext *s)
268
{
269
    uint8_t *ptr, *last_row;
270
    int got_line;
271

    
272
    if (!s->interlace_type) {
273
        ptr = s->image_buf + s->image_linesize * s->y;
274
        /* need to swap bytes correctly for RGB_ALPHA */
275
        if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
276
            png_filter_row(s, s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
277
                           s->last_row, s->row_size, s->bpp);
278
            convert_to_rgb32(ptr, s->tmp_row, s->width, s->filter_type == PNG_FILTER_TYPE_LOCO);
279
            FFSWAP(uint8_t*, s->last_row, s->tmp_row);
280
        } else {
281
            /* in normal case, we avoid one copy */
282
            if (s->y == 0)
283
                last_row = s->last_row;
284
            else
285
                last_row = ptr - s->image_linesize;
286

    
287
            png_filter_row(s, ptr, s->crow_buf[0], s->crow_buf + 1,
288
                           last_row, s->row_size, s->bpp);
289
        }
290
        /* loco lags by 1 row so that it doesn't interfere with top prediction */
291
        if (s->filter_type == PNG_FILTER_TYPE_LOCO &&
292
            s->color_type == PNG_COLOR_TYPE_RGB && s->y > 0)
293
            deloco_rgb24(ptr - s->image_linesize, s->row_size);
294
        s->y++;
295
        if (s->y == s->height) {
296
            s->state |= PNG_ALLIMAGE;
297
            if (s->filter_type == PNG_FILTER_TYPE_LOCO &&
298
                s->color_type == PNG_COLOR_TYPE_RGB)
299
                deloco_rgb24(ptr, s->row_size);
300
        }
301
    } else {
302
        got_line = 0;
303
        for(;;) {
304
            ptr = s->image_buf + s->image_linesize * s->y;
305
            if ((ff_png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) {
306
                /* if we already read one row, it is time to stop to
307
                   wait for the next one */
308
                if (got_line)
309
                    break;
310
                png_filter_row(s, s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
311
                               s->last_row, s->pass_row_size, s->bpp);
312
                FFSWAP(uint8_t*, s->last_row, s->tmp_row);
313
                got_line = 1;
314
            }
315
            if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) {
316
                /* NOTE: RGB32 is handled directly in png_put_interlaced_row */
317
                png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass,
318
                                       s->color_type, s->last_row);
319
            }
320
            s->y++;
321
            if (s->y == s->height) {
322
                for(;;) {
323
                    if (s->pass == NB_PASSES - 1) {
324
                        s->state |= PNG_ALLIMAGE;
325
                        goto the_end;
326
                    } else {
327
                        s->pass++;
328
                        s->y = 0;
329
                        s->pass_row_size = ff_png_pass_row_size(s->pass,
330
                                                             s->bits_per_pixel,
331
                                                             s->width);
332
                        s->crow_size = s->pass_row_size + 1;
333
                        if (s->pass_row_size != 0)
334
                            break;
335
                        /* skip pass if empty row */
336
                    }
337
                }
338
            }
339
        }
340
    the_end: ;
341
    }
342
}
343

    
344
static int png_decode_idat(PNGDecContext *s, int length)
345
{
346
    int ret;
347
    s->zstream.avail_in = length;
348
    s->zstream.next_in = s->bytestream;
349
    s->bytestream += length;
350

    
351
    if(s->bytestream > s->bytestream_end)
352
        return -1;
353

    
354
    /* decode one line if possible */
355
    while (s->zstream.avail_in > 0) {
356
        ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
357
        if (ret != Z_OK && ret != Z_STREAM_END) {
358
            return -1;
359
        }
360
        if (s->zstream.avail_out == 0) {
361
            if (!(s->state & PNG_ALLIMAGE)) {
362
                png_handle_row(s);
363
            }
364
            s->zstream.avail_out = s->crow_size;
365
            s->zstream.next_out = s->crow_buf;
366
        }
367
    }
368
    return 0;
369
}
370

    
371
static int decode_frame(AVCodecContext *avctx,
372
                        void *data, int *data_size,
373
                        AVPacket *avpkt)
374
{
375
    const uint8_t *buf = avpkt->data;
376
    int buf_size = avpkt->size;
377
    PNGDecContext * const s = avctx->priv_data;
378
    AVFrame *picture = data;
379
    AVFrame *p;
380
    uint8_t *crow_buf_base = NULL;
381
    uint32_t tag, length;
382
    int ret, crc;
383

    
384
    FFSWAP(AVFrame *, s->current_picture, s->last_picture);
385
    avctx->coded_frame= s->current_picture;
386
    p = s->current_picture;
387

    
388
    s->bytestream_start=
389
    s->bytestream= buf;
390
    s->bytestream_end= buf + buf_size;
391

    
392
    /* check signature */
393
    if (memcmp(s->bytestream, ff_pngsig, 8) != 0 &&
394
        memcmp(s->bytestream, ff_mngsig, 8) != 0)
395
        return -1;
396
    s->bytestream+= 8;
397
    s->y=
398
    s->state=0;
399
//    memset(s, 0, sizeof(PNGDecContext));
400
    /* init the zlib */
401
    s->zstream.zalloc = ff_png_zalloc;
402
    s->zstream.zfree = ff_png_zfree;
403
    s->zstream.opaque = NULL;
404
    ret = inflateInit(&s->zstream);
405
    if (ret != Z_OK)
406
        return -1;
407
    for(;;) {
408
        int tag32;
409
        if (s->bytestream >= s->bytestream_end)
410
            goto fail;
411
        length = bytestream_get_be32(&s->bytestream);
412
        if (length > 0x7fffffff)
413
            goto fail;
414
        tag32 = bytestream_get_be32(&s->bytestream);
415
        tag = av_bswap32(tag32);
416
        av_dlog(avctx, "png: tag=%c%c%c%c length=%u\n",
417
                (tag & 0xff),
418
                ((tag >> 8) & 0xff),
419
                ((tag >> 16) & 0xff),
420
                ((tag >> 24) & 0xff), length);
421
        switch(tag) {
422
        case MKTAG('I', 'H', 'D', 'R'):
423
            if (length != 13)
424
                goto fail;
425
            s->width = bytestream_get_be32(&s->bytestream);
426
            s->height = bytestream_get_be32(&s->bytestream);
427
            if(av_image_check_size(s->width, s->height, 0, avctx)){
428
                s->width= s->height= 0;
429
                goto fail;
430
            }
431
            s->bit_depth = *s->bytestream++;
432
            s->color_type = *s->bytestream++;
433
            s->compression_type = *s->bytestream++;
434
            s->filter_type = *s->bytestream++;
435
            s->interlace_type = *s->bytestream++;
436
            crc = bytestream_get_be32(&s->bytestream);
437
            s->state |= PNG_IHDR;
438
            av_dlog(avctx, "width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n",
439
                    s->width, s->height, s->bit_depth, s->color_type,
440
                    s->compression_type, s->filter_type, s->interlace_type);
441
            break;
442
        case MKTAG('I', 'D', 'A', 'T'):
443
            if (!(s->state & PNG_IHDR))
444
                goto fail;
445
            if (!(s->state & PNG_IDAT)) {
446
                /* init image info */
447
                avctx->width = s->width;
448
                avctx->height = s->height;
449

    
450
                s->channels = ff_png_get_nb_channels(s->color_type);
451
                s->bits_per_pixel = s->bit_depth * s->channels;
452
                s->bpp = (s->bits_per_pixel + 7) >> 3;
453
                s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3;
454

    
455
                if (s->bit_depth == 8 &&
456
                    s->color_type == PNG_COLOR_TYPE_RGB) {
457
                    avctx->pix_fmt = PIX_FMT_RGB24;
458
                } else if (s->bit_depth == 8 &&
459
                           s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
460
                    avctx->pix_fmt = PIX_FMT_RGB32;
461
                } else if (s->bit_depth == 8 &&
462
                           s->color_type == PNG_COLOR_TYPE_GRAY) {
463
                    avctx->pix_fmt = PIX_FMT_GRAY8;
464
                } else if (s->bit_depth == 16 &&
465
                           s->color_type == PNG_COLOR_TYPE_GRAY) {
466
                    avctx->pix_fmt = PIX_FMT_GRAY16BE;
467
                } else if (s->bit_depth == 16 &&
468
                           s->color_type == PNG_COLOR_TYPE_RGB) {
469
                    avctx->pix_fmt = PIX_FMT_RGB48BE;
470
                } else if (s->bit_depth == 1 &&
471
                           s->color_type == PNG_COLOR_TYPE_GRAY) {
472
                    avctx->pix_fmt = PIX_FMT_MONOBLACK;
473
                } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
474
                    avctx->pix_fmt = PIX_FMT_PAL8;
475
                } else if (s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
476
                    avctx->pix_fmt = PIX_FMT_GRAY8A;
477
                } else {
478
                    goto fail;
479
                }
480
                if(p->data[0])
481
                    avctx->release_buffer(avctx, p);
482

    
483
                p->reference= 0;
484
                if(avctx->get_buffer(avctx, p) < 0){
485
                    av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
486
                    goto fail;
487
                }
488
                p->pict_type= FF_I_TYPE;
489
                p->key_frame= 1;
490
                p->interlaced_frame = !!s->interlace_type;
491

    
492
                /* compute the compressed row size */
493
                if (!s->interlace_type) {
494
                    s->crow_size = s->row_size + 1;
495
                } else {
496
                    s->pass = 0;
497
                    s->pass_row_size = ff_png_pass_row_size(s->pass,
498
                                                         s->bits_per_pixel,
499
                                                         s->width);
500
                    s->crow_size = s->pass_row_size + 1;
501
                }
502
                av_dlog(avctx, "row_size=%d crow_size =%d\n",
503
                        s->row_size, s->crow_size);
504
                s->image_buf = p->data[0];
505
                s->image_linesize = p->linesize[0];
506
                /* copy the palette if needed */
507
                if (s->color_type == PNG_COLOR_TYPE_PALETTE)
508
                    memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t));
509
                /* empty row is used if differencing to the first row */
510
                s->last_row = av_mallocz(s->row_size);
511
                if (!s->last_row)
512
                    goto fail;
513
                if (s->interlace_type ||
514
                    s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
515
                    s->tmp_row = av_malloc(s->row_size);
516
                    if (!s->tmp_row)
517
                        goto fail;
518
                }
519
                /* compressed row */
520
                crow_buf_base = av_malloc(s->row_size + 16);
521
                if (!crow_buf_base)
522
                    goto fail;
523

    
524
                /* we want crow_buf+1 to be 16-byte aligned */
525
                s->crow_buf = crow_buf_base + 15;
526
                s->zstream.avail_out = s->crow_size;
527
                s->zstream.next_out = s->crow_buf;
528
            }
529
            s->state |= PNG_IDAT;
530
            if (png_decode_idat(s, length) < 0)
531
                goto fail;
532
            /* skip crc */
533
            crc = bytestream_get_be32(&s->bytestream);
534
            break;
535
        case MKTAG('P', 'L', 'T', 'E'):
536
            {
537
                int n, i, r, g, b;
538

    
539
                if ((length % 3) != 0 || length > 256 * 3)
540
                    goto skip_tag;
541
                /* read the palette */
542
                n = length / 3;
543
                for(i=0;i<n;i++) {
544
                    r = *s->bytestream++;
545
                    g = *s->bytestream++;
546
                    b = *s->bytestream++;
547
                    s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b;
548
                }
549
                for(;i<256;i++) {
550
                    s->palette[i] = (0xff << 24);
551
                }
552
                s->state |= PNG_PLTE;
553
                crc = bytestream_get_be32(&s->bytestream);
554
            }
555
            break;
556
        case MKTAG('t', 'R', 'N', 'S'):
557
            {
558
                int v, i;
559

    
560
                /* read the transparency. XXX: Only palette mode supported */
561
                if (s->color_type != PNG_COLOR_TYPE_PALETTE ||
562
                    length > 256 ||
563
                    !(s->state & PNG_PLTE))
564
                    goto skip_tag;
565
                for(i=0;i<length;i++) {
566
                    v = *s->bytestream++;
567
                    s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24);
568
                }
569
                crc = bytestream_get_be32(&s->bytestream);
570
            }
571
            break;
572
        case MKTAG('I', 'E', 'N', 'D'):
573
            if (!(s->state & PNG_ALLIMAGE))
574
                goto fail;
575
            crc = bytestream_get_be32(&s->bytestream);
576
            goto exit_loop;
577
        default:
578
            /* skip tag */
579
        skip_tag:
580
            s->bytestream += length + 4;
581
            break;
582
        }
583
    }
584
 exit_loop:
585
     /* handle p-frames only if a predecessor frame is available */
586
     if(s->last_picture->data[0] != NULL) {
587
         if(!(avpkt->flags & AV_PKT_FLAG_KEY)) {
588
            int i, j;
589
            uint8_t *pd = s->current_picture->data[0];
590
            uint8_t *pd_last = s->last_picture->data[0];
591

    
592
            for(j=0; j < s->height; j++) {
593
                for(i=0; i < s->width * s->bpp; i++) {
594
                    pd[i] += pd_last[i];
595
                }
596
                pd += s->image_linesize;
597
                pd_last += s->image_linesize;
598
            }
599
        }
600
    }
601

    
602
    *picture= *s->current_picture;
603
    *data_size = sizeof(AVFrame);
604

    
605
    ret = s->bytestream - s->bytestream_start;
606
 the_end:
607
    inflateEnd(&s->zstream);
608
    av_free(crow_buf_base);
609
    s->crow_buf = NULL;
610
    av_freep(&s->last_row);
611
    av_freep(&s->tmp_row);
612
    return ret;
613
 fail:
614
    ret = -1;
615
    goto the_end;
616
}
617

    
618
static av_cold int png_dec_init(AVCodecContext *avctx)
619
{
620
    PNGDecContext *s = avctx->priv_data;
621

    
622
    s->current_picture = &s->picture1;
623
    s->last_picture = &s->picture2;
624
    avcodec_get_frame_defaults(&s->picture1);
625
    avcodec_get_frame_defaults(&s->picture2);
626

    
627
#if HAVE_MMX
628
    ff_png_init_mmx(s);
629
#endif
630

    
631
    if (!s->add_paeth_prediction)
632
        s->add_paeth_prediction = add_paeth_prediction_c;
633
    if (!s->add_bytes_l2)
634
        s->add_bytes_l2 = add_bytes_l2_c;
635

    
636
    return 0;
637
}
638

    
639
static av_cold int png_dec_end(AVCodecContext *avctx)
640
{
641
    PNGDecContext *s = avctx->priv_data;
642

    
643
    if (s->picture1.data[0])
644
        avctx->release_buffer(avctx, &s->picture1);
645
    if (s->picture2.data[0])
646
        avctx->release_buffer(avctx, &s->picture2);
647

    
648
    return 0;
649
}
650

    
651
AVCodec ff_png_decoder = {
652
    "png",
653
    AVMEDIA_TYPE_VIDEO,
654
    CODEC_ID_PNG,
655
    sizeof(PNGDecContext),
656
    png_dec_init,
657
    NULL,
658
    png_dec_end,
659
    decode_frame,
660
    CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
661
    NULL,
662
    .max_lowres = 5,
663
    .long_name = NULL_IF_CONFIG_SMALL("PNG image"),
664
};