Add DXVA2 HEVC HWAccel
[ffmpeg.git] / libavcodec / pngdec.c
1 /*
2  * PNG image format
3  * Copyright (c) 2003 Fabrice Bellard
4  *
5  * This file is part of Libav.
6  *
7  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 #include "libavutil/imgutils.h"
22 #include "avcodec.h"
23 #include "bytestream.h"
24 #include "internal.h"
25 #include "png.h"
26 #include "pngdsp.h"
27
28 /* TODO:
29  * - add 2, 4 and 16 bit depth support
30  */
31
32 #include <zlib.h>
33
34 typedef struct PNGDecContext {
35     PNGDSPContext dsp;
36
37     GetByteContext gb;
38     AVFrame *prev;
39
40     int state;
41     int width, height;
42     int bit_depth;
43     int color_type;
44     int compression_type;
45     int interlace_type;
46     int filter_type;
47     int channels;
48     int bits_per_pixel;
49     int bpp;
50
51     uint8_t *image_buf;
52     int image_linesize;
53     uint32_t palette[256];
54     uint8_t *crow_buf;
55     uint8_t *last_row;
56     uint8_t *tmp_row;
57     int pass;
58     int crow_size; /* compressed row size (include filter type) */
59     int row_size; /* decompressed row size */
60     int pass_row_size; /* decompress row size of the current pass */
61     int y;
62     z_stream zstream;
63 } PNGDecContext;
64
65 /* Mask to determine which y pixels can be written in a pass */
66 static const uint8_t png_pass_dsp_ymask[NB_PASSES] = {
67     0xff, 0xff, 0x0f, 0xcc, 0x33, 0xff, 0x55,
68 };
69
70 /* Mask to determine which pixels to overwrite while displaying */
71 static const uint8_t png_pass_dsp_mask[NB_PASSES] = {
72     0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff
73 };
74
75 /* NOTE: we try to construct a good looking image at each pass. width
76  * is the original image width. We also do pixel format conversion at
77  * this stage */
78 static void png_put_interlaced_row(uint8_t *dst, int width,
79                                    int bits_per_pixel, int pass,
80                                    int color_type, const uint8_t *src)
81 {
82     int x, mask, dsp_mask, j, src_x, b, bpp;
83     uint8_t *d;
84     const uint8_t *s;
85
86     mask     = ff_png_pass_mask[pass];
87     dsp_mask = png_pass_dsp_mask[pass];
88
89     switch (bits_per_pixel) {
90     case 1:
91         /* we must initialize the line to zero before writing to it */
92         if (pass == 0)
93             memset(dst, 0, (width + 7) >> 3);
94         src_x = 0;
95         for (x = 0; x < width; x++) {
96             j = (x & 7);
97             if ((dsp_mask << j) & 0x80) {
98                 b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1;
99                 dst[x >> 3] |= b << (7 - j);
100             }
101             if ((mask << j) & 0x80)
102                 src_x++;
103         }
104         break;
105     default:
106         bpp = bits_per_pixel >> 3;
107         d   = dst;
108         s   = src;
109         if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
110             for (x = 0; x < width; x++) {
111                 j = x & 7;
112                 if ((dsp_mask << j) & 0x80) {
113                     *(uint32_t *)d = (s[3] << 24) | (s[0] << 16) | (s[1] << 8) | s[2];
114                 }
115                 d += bpp;
116                 if ((mask << j) & 0x80)
117                     s += bpp;
118             }
119         } else {
120             for (x = 0; x < width; x++) {
121                 j = x & 7;
122                 if ((dsp_mask << j) & 0x80) {
123                     memcpy(d, s, bpp);
124                 }
125                 d += bpp;
126                 if ((mask << j) & 0x80)
127                     s += bpp;
128             }
129         }
130         break;
131     }
132 }
133
134 void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top,
135                                  int w, int bpp)
136 {
137     int i;
138     for (i = 0; i < w; i++) {
139         int a, b, c, p, pa, pb, pc;
140
141         a = dst[i - bpp];
142         b = top[i];
143         c = top[i - bpp];
144
145         p  = b - c;
146         pc = a - c;
147
148         pa = abs(p);
149         pb = abs(pc);
150         pc = abs(p + pc);
151
152         if (pa <= pb && pa <= pc)
153             p = a;
154         else if (pb <= pc)
155             p = b;
156         else
157             p = c;
158         dst[i] = p + src[i];
159     }
160 }
161
162 #define UNROLL1(bpp, op)                                                      \
163     {                                                                         \
164         r = dst[0];                                                           \
165         if (bpp >= 2)                                                         \
166             g = dst[1];                                                       \
167         if (bpp >= 3)                                                         \
168             b = dst[2];                                                       \
169         if (bpp >= 4)                                                         \
170             a = dst[3];                                                       \
171         for (; i < size; i += bpp) {                                          \
172             dst[i + 0] = r = op(r, src[i + 0], last[i + 0]);                  \
173             if (bpp == 1)                                                     \
174                 continue;                                                     \
175             dst[i + 1] = g = op(g, src[i + 1], last[i + 1]);                  \
176             if (bpp == 2)                                                     \
177                 continue;                                                     \
178             dst[i + 2] = b = op(b, src[i + 2], last[i + 2]);                  \
179             if (bpp == 3)                                                     \
180                 continue;                                                     \
181             dst[i + 3] = a = op(a, src[i + 3], last[i + 3]);                  \
182         }                                                                     \
183     }
184
185 #define UNROLL_FILTER(op)                                                     \
186     if (bpp == 1) {                                                           \
187         UNROLL1(1, op)                                                        \
188     } else if (bpp == 2) {                                                    \
189         UNROLL1(2, op)                                                        \
190     } else if (bpp == 3) {                                                    \
191         UNROLL1(3, op)                                                        \
192     } else if (bpp == 4) {                                                    \
193         UNROLL1(4, op)                                                        \
194     } else {                                                                  \
195         for (; i < size; i += bpp) {                                          \
196             int j;                                                            \
197             for (j = 0; j < bpp; j++)                                         \
198                 dst[i + j] = op(dst[i + j - bpp], src[i + j], last[i + j]);   \
199         }                                                                     \
200     }
201
202 /* NOTE: 'dst' can be equal to 'last' */
203 static void png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type,
204                            uint8_t *src, uint8_t *last, int size, int bpp)
205 {
206     int i, p, r, g, b, a;
207
208     switch (filter_type) {
209     case PNG_FILTER_VALUE_NONE:
210         memcpy(dst, src, size);
211         break;
212     case PNG_FILTER_VALUE_SUB:
213         for (i = 0; i < bpp; i++)
214             dst[i] = src[i];
215         if (bpp == 4) {
216             p = *(int *)dst;
217             for (; i < size; i += bpp) {
218                 int s = *(int *)(src + i);
219                 p = ((s & 0x7f7f7f7f) + (p & 0x7f7f7f7f)) ^ ((s ^ p) & 0x80808080);
220                 *(int *)(dst + i) = p;
221             }
222         } else {
223 #define OP_SUB(x, s, l) x + s
224             UNROLL_FILTER(OP_SUB);
225         }
226         break;
227     case PNG_FILTER_VALUE_UP:
228         dsp->add_bytes_l2(dst, src, last, size);
229         break;
230     case PNG_FILTER_VALUE_AVG:
231         for (i = 0; i < bpp; i++) {
232             p      = (last[i] >> 1);
233             dst[i] = p + src[i];
234         }
235 #define OP_AVG(x, s, l) (((x + l) >> 1) + s) & 0xff
236         UNROLL_FILTER(OP_AVG);
237         break;
238     case PNG_FILTER_VALUE_PAETH:
239         for (i = 0; i < bpp; i++) {
240             p      = last[i];
241             dst[i] = p + src[i];
242         }
243         if (bpp > 2 && size > 4) {
244             /* would write off the end of the array if we let it process
245              * the last pixel with bpp=3 */
246             int w = bpp == 4 ? size : size - 3;
247             dsp->add_paeth_prediction(dst + i, src + i, last + i, w - i, bpp);
248             i = w;
249         }
250         ff_add_png_paeth_prediction(dst + i, src + i, last + i, size - i, bpp);
251         break;
252     }
253 }
254
255 static av_always_inline void convert_to_rgb32_loco(uint8_t *dst,
256                                                    const uint8_t *src,
257                                                    int width, int loco)
258 {
259     int j;
260     unsigned int r, g, b, a;
261
262     for (j = 0; j < width; j++) {
263         r = src[0];
264         g = src[1];
265         b = src[2];
266         a = src[3];
267         if (loco) {
268             r = (r + g) & 0xff;
269             b = (b + g) & 0xff;
270         }
271         *(uint32_t *) dst = (a << 24) | (r << 16) | (g << 8) | b;
272         dst += 4;
273         src += 4;
274     }
275 }
276
277 static void convert_to_rgb32(uint8_t *dst, const uint8_t *src,
278                              int width, int loco)
279 {
280     if (loco)
281         convert_to_rgb32_loco(dst, src, width, 1);
282     else
283         convert_to_rgb32_loco(dst, src, width, 0);
284 }
285
286 static void deloco_rgb24(uint8_t *dst, int size)
287 {
288     int i;
289     for (i = 0; i < size; i += 3) {
290         int g = dst[i + 1];
291         dst[i + 0] += g;
292         dst[i + 2] += g;
293     }
294 }
295
296 /* process exactly one decompressed row */
297 static void png_handle_row(PNGDecContext *s)
298 {
299     uint8_t *ptr, *last_row;
300     int got_line;
301
302     if (!s->interlace_type) {
303         ptr = s->image_buf + s->image_linesize * s->y;
304         /* need to swap bytes correctly for RGB_ALPHA */
305         if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
306             png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
307                            s->last_row, s->row_size, s->bpp);
308             convert_to_rgb32(ptr, s->tmp_row, s->width,
309                              s->filter_type == PNG_FILTER_TYPE_LOCO);
310             FFSWAP(uint8_t *, s->last_row, s->tmp_row);
311         } else {
312             /* in normal case, we avoid one copy */
313             if (s->y == 0)
314                 last_row = s->last_row;
315             else
316                 last_row = ptr - s->image_linesize;
317
318             png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1,
319                            last_row, s->row_size, s->bpp);
320         }
321         /* loco lags by 1 row so that it doesn't interfere with top prediction */
322         if (s->filter_type == PNG_FILTER_TYPE_LOCO &&
323             s->color_type == PNG_COLOR_TYPE_RGB && s->y > 0)
324             deloco_rgb24(ptr - s->image_linesize, s->row_size);
325         s->y++;
326         if (s->y == s->height) {
327             s->state |= PNG_ALLIMAGE;
328             if (s->filter_type == PNG_FILTER_TYPE_LOCO &&
329                 s->color_type == PNG_COLOR_TYPE_RGB)
330                 deloco_rgb24(ptr, s->row_size);
331         }
332     } else {
333         got_line = 0;
334         for (;;) {
335             ptr = s->image_buf + s->image_linesize * s->y;
336             if ((ff_png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) {
337                 /* if we already read one row, it is time to stop to
338                  * wait for the next one */
339                 if (got_line)
340                     break;
341                 png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
342                                s->last_row, s->pass_row_size, s->bpp);
343                 FFSWAP(uint8_t *, s->last_row, s->tmp_row);
344                 got_line = 1;
345             }
346             if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) {
347                 /* NOTE: RGB32 is handled directly in png_put_interlaced_row */
348                 png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass,
349                                        s->color_type, s->last_row);
350             }
351             s->y++;
352             if (s->y == s->height) {
353                 for (;;) {
354                     if (s->pass == NB_PASSES - 1) {
355                         s->state |= PNG_ALLIMAGE;
356                         goto the_end;
357                     } else {
358                         s->pass++;
359                         s->y = 0;
360                         s->pass_row_size = ff_png_pass_row_size(s->pass,
361                                                                 s->bits_per_pixel,
362                                                                 s->width);
363                         s->crow_size = s->pass_row_size + 1;
364                         if (s->pass_row_size != 0)
365                             break;
366                         /* skip pass if empty row */
367                     }
368                 }
369             }
370         }
371 the_end:;
372     }
373 }
374
375 static int png_decode_idat(PNGDecContext *s, int length)
376 {
377     int ret;
378     s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb));
379     s->zstream.next_in  = s->gb.buffer;
380     bytestream2_skip(&s->gb, length);
381
382     /* decode one line if possible */
383     while (s->zstream.avail_in > 0) {
384         ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
385         if (ret != Z_OK && ret != Z_STREAM_END) {
386             return -1;
387         }
388         if (s->zstream.avail_out == 0) {
389             if (!(s->state & PNG_ALLIMAGE)) {
390                 png_handle_row(s);
391             }
392             s->zstream.avail_out = s->crow_size;
393             s->zstream.next_out  = s->crow_buf;
394         }
395         if (ret == Z_STREAM_END && s->zstream.avail_in > 0) {
396             av_log(NULL, AV_LOG_WARNING,
397                    "%d undecompressed bytes left in buffer\n", s->zstream.avail_in);
398             return 0;
399         }
400     }
401     return 0;
402 }
403
404 static int decode_frame(AVCodecContext *avctx,
405                         void *data, int *got_frame,
406                         AVPacket *avpkt)
407 {
408     PNGDecContext *const s = avctx->priv_data;
409     const uint8_t *buf     = avpkt->data;
410     int buf_size           = avpkt->size;
411     AVFrame *p             = data;
412     uint8_t *crow_buf_base = NULL;
413     uint32_t tag, length;
414     int ret;
415
416     /* check signature */
417     if (buf_size < 8 ||
418         (memcmp(buf, ff_pngsig, 8) != 0 && memcmp(buf, ff_mngsig, 8) != 0)) {
419         av_log(avctx, AV_LOG_ERROR, "Invalid PNG signature (%d).\n", buf_size);
420         return AVERROR_INVALIDDATA;
421     }
422
423     bytestream2_init(&s->gb, buf + 8, buf_size - 8);
424     s->y = s->state = 0;
425
426     /* init the zlib */
427     s->zstream.zalloc = ff_png_zalloc;
428     s->zstream.zfree  = ff_png_zfree;
429     s->zstream.opaque = NULL;
430     ret = inflateInit(&s->zstream);
431     if (ret != Z_OK)
432         return -1;
433     for (;;) {
434         if (bytestream2_get_bytes_left(&s->gb) <= 0)
435             goto fail;
436         length = bytestream2_get_be32(&s->gb);
437         if (length > 0x7fffffff)
438             goto fail;
439         tag = bytestream2_get_le32(&s->gb);
440         av_dlog(avctx, "png: tag=%c%c%c%c length=%u\n",
441                 (tag & 0xff),
442                 ((tag >> 8) & 0xff),
443                 ((tag >> 16) & 0xff),
444                 ((tag >> 24) & 0xff), length);
445         switch (tag) {
446         case MKTAG('I', 'H', 'D', 'R'):
447             if (length != 13)
448                 goto fail;
449             s->width  = bytestream2_get_be32(&s->gb);
450             s->height = bytestream2_get_be32(&s->gb);
451             if (av_image_check_size(s->width, s->height, 0, avctx)) {
452                 s->width = s->height = 0;
453                 goto fail;
454             }
455             s->bit_depth        = bytestream2_get_byte(&s->gb);
456             s->color_type       = bytestream2_get_byte(&s->gb);
457             s->compression_type = bytestream2_get_byte(&s->gb);
458             s->filter_type      = bytestream2_get_byte(&s->gb);
459             s->interlace_type   = bytestream2_get_byte(&s->gb);
460             bytestream2_skip(&s->gb, 4); /* crc */
461             s->state |= PNG_IHDR;
462             av_dlog(avctx, "width=%d height=%d depth=%d color_type=%d "
463                            "compression_type=%d filter_type=%d interlace_type=%d\n",
464                     s->width, s->height, s->bit_depth, s->color_type,
465                     s->compression_type, s->filter_type, s->interlace_type);
466             break;
467         case MKTAG('I', 'D', 'A', 'T'):
468             if (!(s->state & PNG_IHDR))
469                 goto fail;
470             if (!(s->state & PNG_IDAT)) {
471                 /* init image info */
472                 avctx->width  = s->width;
473                 avctx->height = s->height;
474
475                 s->channels       = ff_png_get_nb_channels(s->color_type);
476                 s->bits_per_pixel = s->bit_depth * s->channels;
477                 s->bpp            = (s->bits_per_pixel + 7) >> 3;
478                 s->row_size       = (avctx->width * s->bits_per_pixel + 7) >> 3;
479
480                 if (s->bit_depth == 8 &&
481                     s->color_type == PNG_COLOR_TYPE_RGB) {
482                     avctx->pix_fmt = AV_PIX_FMT_RGB24;
483                 } else if (s->bit_depth == 8 &&
484                            s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
485                     avctx->pix_fmt = AV_PIX_FMT_RGB32;
486                 } else if (s->bit_depth == 8 &&
487                            s->color_type == PNG_COLOR_TYPE_GRAY) {
488                     avctx->pix_fmt = AV_PIX_FMT_GRAY8;
489                 } else if (s->bit_depth == 16 &&
490                            s->color_type == PNG_COLOR_TYPE_GRAY) {
491                     avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
492                 } else if (s->bit_depth == 16 &&
493                            s->color_type == PNG_COLOR_TYPE_RGB) {
494                     avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
495                 } else if (s->bit_depth == 1 &&
496                            s->color_type == PNG_COLOR_TYPE_GRAY) {
497                     avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
498                 } else if (s->bit_depth == 8 &&
499                            s->color_type == PNG_COLOR_TYPE_PALETTE) {
500                     avctx->pix_fmt = AV_PIX_FMT_PAL8;
501                 } else if (s->bit_depth == 8 &&
502                            s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
503                     avctx->pix_fmt = AV_PIX_FMT_YA8;
504                 } else if (s->bit_depth == 16 &&
505                            s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
506                     avctx->pix_fmt = AV_PIX_FMT_YA16BE;
507                 } else {
508                     goto fail;
509                 }
510
511                 if (ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF) < 0) {
512                     av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
513                     goto fail;
514                 }
515                 p->pict_type        = AV_PICTURE_TYPE_I;
516                 p->key_frame        = 1;
517                 p->interlaced_frame = !!s->interlace_type;
518
519                 /* compute the compressed row size */
520                 if (!s->interlace_type) {
521                     s->crow_size = s->row_size + 1;
522                 } else {
523                     s->pass          = 0;
524                     s->pass_row_size = ff_png_pass_row_size(s->pass,
525                                                             s->bits_per_pixel,
526                                                             s->width);
527                     s->crow_size = s->pass_row_size + 1;
528                 }
529                 av_dlog(avctx, "row_size=%d crow_size =%d\n",
530                         s->row_size, s->crow_size);
531                 s->image_buf      = p->data[0];
532                 s->image_linesize = p->linesize[0];
533                 /* copy the palette if needed */
534                 if (s->color_type == PNG_COLOR_TYPE_PALETTE)
535                     memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t));
536                 /* empty row is used if differencing to the first row */
537                 s->last_row = av_mallocz(s->row_size);
538                 if (!s->last_row)
539                     goto fail;
540                 if (s->interlace_type ||
541                     s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
542                     s->tmp_row = av_malloc(s->row_size);
543                     if (!s->tmp_row)
544                         goto fail;
545                 }
546                 /* compressed row */
547                 crow_buf_base = av_malloc(s->row_size + 16);
548                 if (!crow_buf_base)
549                     goto fail;
550
551                 /* we want crow_buf+1 to be 16-byte aligned */
552                 s->crow_buf          = crow_buf_base + 15;
553                 s->zstream.avail_out = s->crow_size;
554                 s->zstream.next_out  = s->crow_buf;
555             }
556             s->state |= PNG_IDAT;
557             if (png_decode_idat(s, length) < 0)
558                 goto fail;
559             bytestream2_skip(&s->gb, 4); /* crc */
560             break;
561         case MKTAG('P', 'L', 'T', 'E'):
562         {
563             int n, i, r, g, b;
564
565             if ((length % 3) != 0 || length > 256 * 3)
566                 goto skip_tag;
567             /* read the palette */
568             n = length / 3;
569             for (i = 0; i < n; i++) {
570                 r = bytestream2_get_byte(&s->gb);
571                 g = bytestream2_get_byte(&s->gb);
572                 b = bytestream2_get_byte(&s->gb);
573                 s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b;
574             }
575             for (; i < 256; i++)
576                 s->palette[i] = (0xff << 24);
577             s->state |= PNG_PLTE;
578             bytestream2_skip(&s->gb, 4);     /* crc */
579         }
580         break;
581         case MKTAG('t', 'R', 'N', 'S'):
582         {
583             int v, i;
584
585             /* read the transparency. XXX: Only palette mode supported */
586             if (s->color_type != PNG_COLOR_TYPE_PALETTE ||
587                 length > 256 ||
588                 !(s->state & PNG_PLTE))
589                 goto skip_tag;
590             for (i = 0; i < length; i++) {
591                 v = bytestream2_get_byte(&s->gb);
592                 s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24);
593             }
594             bytestream2_skip(&s->gb, 4);     /* crc */
595         }
596         break;
597         case MKTAG('I', 'E', 'N', 'D'):
598             if (!(s->state & PNG_ALLIMAGE))
599                 goto fail;
600             bytestream2_skip(&s->gb, 4); /* crc */
601             goto exit_loop;
602         default:
603             /* skip tag */
604 skip_tag:
605             bytestream2_skip(&s->gb, length + 4);
606             break;
607         }
608     }
609 exit_loop:
610     /* handle p-frames only if a predecessor frame is available */
611     if (s->prev->data[0]) {
612         if (!(avpkt->flags & AV_PKT_FLAG_KEY)) {
613             int i, j;
614             uint8_t *pd      = p->data[0];
615             uint8_t *pd_last = s->prev->data[0];
616
617             for (j = 0; j < s->height; j++) {
618                 for (i = 0; i < s->width * s->bpp; i++)
619                     pd[i] += pd_last[i];
620                 pd      += s->image_linesize;
621                 pd_last += s->image_linesize;
622             }
623         }
624     }
625
626     av_frame_unref(s->prev);
627     if ((ret = av_frame_ref(s->prev, p)) < 0)
628         goto fail;
629
630     *got_frame = 1;
631
632     ret = bytestream2_tell(&s->gb);
633 the_end:
634     inflateEnd(&s->zstream);
635     av_free(crow_buf_base);
636     s->crow_buf = NULL;
637     av_freep(&s->last_row);
638     av_freep(&s->tmp_row);
639     return ret;
640 fail:
641     ret = -1;
642     goto the_end;
643 }
644
645 static av_cold int png_dec_init(AVCodecContext *avctx)
646 {
647     PNGDecContext *s = avctx->priv_data;
648
649     s->prev = av_frame_alloc();
650     if (!s->prev)
651         return AVERROR(ENOMEM);
652
653     ff_pngdsp_init(&s->dsp);
654
655     return 0;
656 }
657
658 static av_cold int png_dec_end(AVCodecContext *avctx)
659 {
660     PNGDecContext *s = avctx->priv_data;
661
662     av_frame_free(&s->prev);
663
664     return 0;
665 }
666
667 AVCodec ff_png_decoder = {
668     .name           = "png",
669     .long_name      = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"),
670     .type           = AVMEDIA_TYPE_VIDEO,
671     .id             = AV_CODEC_ID_PNG,
672     .priv_data_size = sizeof(PNGDecContext),
673     .init           = png_dec_init,
674     .close          = png_dec_end,
675     .decode         = decode_frame,
676     .capabilities   = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
677 };