Statistics
| Branch: | Revision:

ffmpeg / libavcodec / pngdec.c @ 09d1208c

History | View | Annotate | Download (20.9 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
#include "avcodec.h"
22
#include "bytestream.h"
23
#include "png.h"
24
#include "dsputil.h"
25

    
26
/* TODO:
27
 * - add 2, 4 and 16 bit depth support
28
 */
29

    
30
#include <zlib.h>
31

    
32
//#define DEBUG
33

    
34
typedef struct PNGDecContext {
35
    DSPContext dsp;
36

    
37
    const uint8_t *bytestream;
38
    const uint8_t *bytestream_start;
39
    const uint8_t *bytestream_end;
40
    AVFrame picture1, picture2;
41
    AVFrame *current_picture, *last_picture;
42

    
43
    int state;
44
    int width, height;
45
    int bit_depth;
46
    int color_type;
47
    int compression_type;
48
    int interlace_type;
49
    int filter_type;
50
    int channels;
51
    int bits_per_pixel;
52
    int bpp;
53

    
54
    uint8_t *image_buf;
55
    int image_linesize;
56
    uint32_t palette[256];
57
    uint8_t *crow_buf;
58
    uint8_t *last_row;
59
    uint8_t *tmp_row;
60
    int pass;
61
    int crow_size; /* compressed row size (include filter type) */
62
    int row_size; /* decompressed row size */
63
    int pass_row_size; /* decompress row size of the current pass */
64
    int y;
65
    z_stream zstream;
66
} PNGDecContext;
67

    
68
/* Mask to determine which y pixels can be written in a pass */
69
static const uint8_t png_pass_dsp_ymask[NB_PASSES] = {
70
    0xff, 0xff, 0x0f, 0xcc, 0x33, 0xff, 0x55,
71
};
72

    
73
/* Mask to determine which pixels to overwrite while displaying */
74
static const uint8_t png_pass_dsp_mask[NB_PASSES] = {
75
    0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff
76
};
77

    
78
/* NOTE: we try to construct a good looking image at each pass. width
79
   is the original image width. We also do pixel format conversion at
80
   this stage */
81
static void png_put_interlaced_row(uint8_t *dst, int width,
82
                                   int bits_per_pixel, int pass,
83
                                   int color_type, const uint8_t *src)
84
{
85
    int x, mask, dsp_mask, j, src_x, b, bpp;
86
    uint8_t *d;
87
    const uint8_t *s;
88

    
89
    mask = ff_png_pass_mask[pass];
90
    dsp_mask = png_pass_dsp_mask[pass];
91
    switch(bits_per_pixel) {
92
    case 1:
93
        /* we must initialize the line to zero before writing to it */
94
        if (pass == 0)
95
            memset(dst, 0, (width + 7) >> 3);
96
        src_x = 0;
97
        for(x = 0; x < width; x++) {
98
            j = (x & 7);
99
            if ((dsp_mask << j) & 0x80) {
100
                b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1;
101
                dst[x >> 3] |= b << (7 - j);
102
            }
103
            if ((mask << j) & 0x80)
104
                src_x++;
105
        }
106
        break;
107
    default:
108
        bpp = bits_per_pixel >> 3;
109
        d = dst;
110
        s = src;
111
        if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
112
            for(x = 0; x < width; x++) {
113
                j = x & 7;
114
                if ((dsp_mask << j) & 0x80) {
115
                    *(uint32_t *)d = (s[3] << 24) | (s[0] << 16) | (s[1] << 8) | s[2];
116
                }
117
                d += bpp;
118
                if ((mask << j) & 0x80)
119
                    s += bpp;
120
            }
121
        } else {
122
            for(x = 0; x < width; x++) {
123
                j = x & 7;
124
                if ((dsp_mask << j) & 0x80) {
125
                    memcpy(d, s, bpp);
126
                }
127
                d += bpp;
128
                if ((mask << j) & 0x80)
129
                    s += bpp;
130
            }
131
        }
132
        break;
133
    }
134
}
135

    
136
void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp)
137
{
138
    int i;
139
    for(i = 0; i < w; i++) {
140
        int a, b, c, p, pa, pb, pc;
141

    
142
        a = dst[i - bpp];
143
        b = top[i];
144
        c = top[i - bpp];
145

    
146
        p = b - c;
147
        pc = a - c;
148

    
149
        pa = abs(p);
150
        pb = abs(pc);
151
        pc = abs(p + pc);
152

    
153
        if (pa <= pb && pa <= pc)
154
            p = a;
155
        else if (pb <= pc)
156
            p = b;
157
        else
158
            p = c;
159
        dst[i] = p + src[i];
160
    }
161
}
162

    
163
#define UNROLL1(bpp, op) {\
164
                 r = dst[0];\
165
    if(bpp >= 2) g = dst[1];\
166
    if(bpp >= 3) b = dst[2];\
167
    if(bpp >= 4) a = dst[3];\
168
    for(; i < size; i+=bpp) {\
169
        dst[i+0] = r = op(r, src[i+0], last[i+0]);\
170
        if(bpp == 1) continue;\
171
        dst[i+1] = g = op(g, src[i+1], last[i+1]);\
172
        if(bpp == 2) continue;\
173
        dst[i+2] = b = op(b, src[i+2], last[i+2]);\
174
        if(bpp == 3) continue;\
175
        dst[i+3] = a = op(a, src[i+3], last[i+3]);\
176
    }\
177
}
178

    
179
#define UNROLL_FILTER(op)\
180
         if(bpp == 1) UNROLL1(1, op)\
181
    else if(bpp == 2) UNROLL1(2, op)\
182
    else if(bpp == 3) UNROLL1(3, op)\
183
    else if(bpp == 4) UNROLL1(4, op)\
184

    
185
/* NOTE: 'dst' can be equal to 'last' */
186
static void png_filter_row(DSPContext *dsp, uint8_t *dst, int filter_type,
187
                           uint8_t *src, uint8_t *last, int size, int bpp)
188
{
189
    int i, p, r, g, b, a;
190

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

    
238
static av_always_inline void convert_to_rgb32_loco(uint8_t *dst, const uint8_t *src, int width, int loco)
239
{
240
    int j;
241
    unsigned int r, g, b, a;
242

    
243
    for(j = 0;j < width; j++) {
244
        r = src[0];
245
        g = src[1];
246
        b = src[2];
247
        a = src[3];
248
        if(loco) {
249
            r = (r+g)&0xff;
250
            b = (b+g)&0xff;
251
        }
252
        *(uint32_t *)dst = (a << 24) | (r << 16) | (g << 8) | b;
253
        dst += 4;
254
        src += 4;
255
    }
256
}
257

    
258
static void convert_to_rgb32(uint8_t *dst, const uint8_t *src, int width, int loco)
259
{
260
    if(loco)
261
        convert_to_rgb32_loco(dst, src, width, 1);
262
    else
263
        convert_to_rgb32_loco(dst, src, width, 0);
264
}
265

    
266
static void deloco_rgb24(uint8_t *dst, int size)
267
{
268
    int i;
269
    for(i=0; i<size; i+=3) {
270
        int g = dst[i+1];
271
        dst[i+0] += g;
272
        dst[i+2] += g;
273
    }
274
}
275

    
276
/* process exactly one decompressed row */
277
static void png_handle_row(PNGDecContext *s)
278
{
279
    uint8_t *ptr, *last_row;
280
    int got_line;
281

    
282
    if (!s->interlace_type) {
283
        ptr = s->image_buf + s->image_linesize * s->y;
284
        /* need to swap bytes correctly for RGB_ALPHA */
285
        if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
286
            png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
287
                           s->last_row, s->row_size, s->bpp);
288
            convert_to_rgb32(ptr, s->tmp_row, s->width, s->filter_type == PNG_FILTER_TYPE_LOCO);
289
            FFSWAP(uint8_t*, s->last_row, s->tmp_row);
290
        } else {
291
            /* in normal case, we avoid one copy */
292
            if (s->y == 0)
293
                last_row = s->last_row;
294
            else
295
                last_row = ptr - s->image_linesize;
296

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

    
354
static int png_decode_idat(PNGDecContext *s, int length)
355
{
356
    int ret;
357
    s->zstream.avail_in = length;
358
    s->zstream.next_in = s->bytestream;
359
    s->bytestream += length;
360

    
361
    if(s->bytestream > s->bytestream_end)
362
        return -1;
363

    
364
    /* decode one line if possible */
365
    while (s->zstream.avail_in > 0) {
366
        ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
367
        if (ret != Z_OK && ret != Z_STREAM_END) {
368
            return -1;
369
        }
370
        if (s->zstream.avail_out == 0) {
371
            if (!(s->state & PNG_ALLIMAGE)) {
372
                png_handle_row(s);
373
            }
374
            s->zstream.avail_out = s->crow_size;
375
            s->zstream.next_out = s->crow_buf;
376
        }
377
    }
378
    return 0;
379
}
380

    
381
static int decode_frame(AVCodecContext *avctx,
382
                        void *data, int *data_size,
383
                        AVPacket *avpkt)
384
{
385
    const uint8_t *buf = avpkt->data;
386
    int buf_size = avpkt->size;
387
    PNGDecContext * const s = avctx->priv_data;
388
    AVFrame *picture = data;
389
    AVFrame *p;
390
    uint8_t *crow_buf_base = NULL;
391
    uint32_t tag, length;
392
    int ret, crc;
393

    
394
    FFSWAP(AVFrame *, s->current_picture, s->last_picture);
395
    avctx->coded_frame= s->current_picture;
396
    p = s->current_picture;
397

    
398
    s->bytestream_start=
399
    s->bytestream= buf;
400
    s->bytestream_end= buf + buf_size;
401

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

    
464
                s->channels = ff_png_get_nb_channels(s->color_type);
465
                s->bits_per_pixel = s->bit_depth * s->channels;
466
                s->bpp = (s->bits_per_pixel + 7) >> 3;
467
                s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3;
468

    
469
                if (s->bit_depth == 8 &&
470
                    s->color_type == PNG_COLOR_TYPE_RGB) {
471
                    avctx->pix_fmt = PIX_FMT_RGB24;
472
                } else if (s->bit_depth == 8 &&
473
                           s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
474
                    avctx->pix_fmt = PIX_FMT_RGB32;
475
                } else if (s->bit_depth == 8 &&
476
                           s->color_type == PNG_COLOR_TYPE_GRAY) {
477
                    avctx->pix_fmt = PIX_FMT_GRAY8;
478
                } else if (s->bit_depth == 16 &&
479
                           s->color_type == PNG_COLOR_TYPE_GRAY) {
480
                    avctx->pix_fmt = PIX_FMT_GRAY16BE;
481
                } else if (s->bit_depth == 1 &&
482
                           s->color_type == PNG_COLOR_TYPE_GRAY) {
483
                    avctx->pix_fmt = PIX_FMT_MONOBLACK;
484
                } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
485
                    avctx->pix_fmt = PIX_FMT_PAL8;
486
                } else {
487
                    goto fail;
488
                }
489
                if(p->data[0])
490
                    avctx->release_buffer(avctx, p);
491

    
492
                p->reference= 0;
493
                if(avctx->get_buffer(avctx, p) < 0){
494
                    av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
495
                    goto fail;
496
                }
497
                p->pict_type= FF_I_TYPE;
498
                p->key_frame= 1;
499
                p->interlaced_frame = !!s->interlace_type;
500

    
501
                /* compute the compressed row size */
502
                if (!s->interlace_type) {
503
                    s->crow_size = s->row_size + 1;
504
                } else {
505
                    s->pass = 0;
506
                    s->pass_row_size = ff_png_pass_row_size(s->pass,
507
                                                         s->bits_per_pixel,
508
                                                         s->width);
509
                    s->crow_size = s->pass_row_size + 1;
510
                }
511
#ifdef DEBUG
512
                av_log(avctx, AV_LOG_DEBUG, "row_size=%d crow_size =%d\n",
513
                       s->row_size, s->crow_size);
514
#endif
515
                s->image_buf = p->data[0];
516
                s->image_linesize = p->linesize[0];
517
                /* copy the palette if needed */
518
                if (s->color_type == PNG_COLOR_TYPE_PALETTE)
519
                    memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t));
520
                /* empty row is used if differencing to the first row */
521
                s->last_row = av_mallocz(s->row_size);
522
                if (!s->last_row)
523
                    goto fail;
524
                if (s->interlace_type ||
525
                    s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
526
                    s->tmp_row = av_malloc(s->row_size);
527
                    if (!s->tmp_row)
528
                        goto fail;
529
                }
530
                /* compressed row */
531
                crow_buf_base = av_malloc(s->row_size + 16);
532
                if (!crow_buf_base)
533
                    goto fail;
534

    
535
                /* we want crow_buf+1 to be 16-byte aligned */
536
                s->crow_buf = crow_buf_base + 15;
537
                s->zstream.avail_out = s->crow_size;
538
                s->zstream.next_out = s->crow_buf;
539
            }
540
            s->state |= PNG_IDAT;
541
            if (png_decode_idat(s, length) < 0)
542
                goto fail;
543
            /* skip crc */
544
            crc = bytestream_get_be32(&s->bytestream);
545
            break;
546
        case MKTAG('P', 'L', 'T', 'E'):
547
            {
548
                int n, i, r, g, b;
549

    
550
                if ((length % 3) != 0 || length > 256 * 3)
551
                    goto skip_tag;
552
                /* read the palette */
553
                n = length / 3;
554
                for(i=0;i<n;i++) {
555
                    r = *s->bytestream++;
556
                    g = *s->bytestream++;
557
                    b = *s->bytestream++;
558
                    s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b;
559
                }
560
                for(;i<256;i++) {
561
                    s->palette[i] = (0xff << 24);
562
                }
563
                s->state |= PNG_PLTE;
564
                crc = bytestream_get_be32(&s->bytestream);
565
            }
566
            break;
567
        case MKTAG('t', 'R', 'N', 'S'):
568
            {
569
                int v, i;
570

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

    
603
            for(j=0; j < s->height; j++) {
604
                for(i=0; i < s->width * s->bpp; i++) {
605
                    pd[i] += pd_last[i];
606
                }
607
                pd += s->image_linesize;
608
                pd_last += s->image_linesize;
609
            }
610
        }
611
    }
612

    
613
    *picture= *s->current_picture;
614
    *data_size = sizeof(AVFrame);
615

    
616
    ret = s->bytestream - s->bytestream_start;
617
 the_end:
618
    inflateEnd(&s->zstream);
619
    av_free(crow_buf_base);
620
    s->crow_buf = NULL;
621
    av_freep(&s->last_row);
622
    av_freep(&s->tmp_row);
623
    return ret;
624
 fail:
625
    ret = -1;
626
    goto the_end;
627
}
628

    
629
static av_cold int png_dec_init(AVCodecContext *avctx){
630
    PNGDecContext *s = avctx->priv_data;
631

    
632
    s->current_picture = &s->picture1;
633
    s->last_picture = &s->picture2;
634
    avcodec_get_frame_defaults(&s->picture1);
635
    avcodec_get_frame_defaults(&s->picture2);
636
    dsputil_init(&s->dsp, avctx);
637

    
638
    return 0;
639
}
640

    
641
AVCodec png_decoder = {
642
    "png",
643
    CODEC_TYPE_VIDEO,
644
    CODEC_ID_PNG,
645
    sizeof(PNGDecContext),
646
    png_dec_init,
647
    NULL,
648
    NULL, //decode_end,
649
    decode_frame,
650
    0 /*CODEC_CAP_DR1*/ /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
651
    NULL,
652
    .long_name = NULL_IF_CONFIG_SMALL("PNG image"),
653
};