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
34typedef 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 */
69static 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 */
74static 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 */
81static 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
136void 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    else {\
185        for (; i < size; i += bpp) {\
186            int j;\
187            for (j = 0; j < bpp; j++)\
188                dst[i+j] = op(dst[i+j-bpp], src[i+j], last[i+j]);\
189        }\
190    }
191
192/* NOTE: 'dst' can be equal to 'last' */
193static void png_filter_row(DSPContext *dsp, uint8_t *dst, int filter_type,
194                           uint8_t *src, uint8_t *last, int size, int bpp)
195{
196    int i, p, r, g, b, a;
197
198    switch(filter_type) {
199    case PNG_FILTER_VALUE_NONE:
200        memcpy(dst, src, size);
201        break;
202    case PNG_FILTER_VALUE_SUB:
203        for(i = 0; i < bpp; i++) {
204            dst[i] = src[i];
205        }
206        if(bpp == 4) {
207            p = *(int*)dst;
208            for(; i < size; i+=bpp) {
209                int s = *(int*)(src+i);
210                p = ((s&0x7f7f7f7f) + (p&0x7f7f7f7f)) ^ ((s^p)&0x80808080);
211                *(int*)(dst+i) = p;
212            }
213        } else {
214#define OP_SUB(x,s,l) x+s
215            UNROLL_FILTER(OP_SUB);
216        }
217        break;
218    case PNG_FILTER_VALUE_UP:
219        dsp->add_bytes_l2(dst, src, last, size);
220        break;
221    case PNG_FILTER_VALUE_AVG:
222        for(i = 0; i < bpp; i++) {
223            p = (last[i] >> 1);
224            dst[i] = p + src[i];
225        }
226#define OP_AVG(x,s,l) (((x + l) >> 1) + s) & 0xff
227        UNROLL_FILTER(OP_AVG);
228        break;
229    case PNG_FILTER_VALUE_PAETH:
230        for(i = 0; i < bpp; i++) {
231            p = last[i];
232            dst[i] = p + src[i];
233        }
234        if(bpp > 1 && size > 4) {
235            // would write off the end of the array if we let it process the last pixel with bpp=3
236            int w = bpp==4 ? size : size-3;
237            dsp->add_png_paeth_prediction(dst+i, src+i, last+i, w-i, bpp);
238            i = w;
239        }
240        ff_add_png_paeth_prediction(dst+i, src+i, last+i, size-i, bpp);
241        break;
242    }
243}
244
245static av_always_inline void convert_to_rgb32_loco(uint8_t *dst, const uint8_t *src, int width, int loco)
246{
247    int j;
248    unsigned int r, g, b, a;
249
250    for(j = 0;j < width; j++) {
251        r = src[0];
252        g = src[1];
253        b = src[2];
254        a = src[3];
255        if(loco) {
256            r = (r+g)&0xff;
257            b = (b+g)&0xff;
258        }
259        *(uint32_t *)dst = (a << 24) | (r << 16) | (g << 8) | b;
260        dst += 4;
261        src += 4;
262    }
263}
264
265static void convert_to_rgb32(uint8_t *dst, const uint8_t *src, int width, int loco)
266{
267    if(loco)
268        convert_to_rgb32_loco(dst, src, width, 1);
269    else
270        convert_to_rgb32_loco(dst, src, width, 0);
271}
272
273static void deloco_rgb24(uint8_t *dst, int size)
274{
275    int i;
276    for(i=0; i<size; i+=3) {
277        int g = dst[i+1];
278        dst[i+0] += g;
279        dst[i+2] += g;
280    }
281}
282
283/* process exactly one decompressed row */
284static void png_handle_row(PNGDecContext *s)
285{
286    uint8_t *ptr, *last_row;
287    int got_line;
288
289    if (!s->interlace_type) {
290        ptr = s->image_buf + s->image_linesize * s->y;
291        /* need to swap bytes correctly for RGB_ALPHA */
292        if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
293            png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
294                           s->last_row, s->row_size, s->bpp);
295            convert_to_rgb32(ptr, s->tmp_row, s->width, s->filter_type == PNG_FILTER_TYPE_LOCO);
296            FFSWAP(uint8_t*, s->last_row, s->tmp_row);
297        } else {
298            /* in normal case, we avoid one copy */
299            if (s->y == 0)
300                last_row = s->last_row;
301            else
302                last_row = ptr - s->image_linesize;
303
304            png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1,
305                           last_row, s->row_size, s->bpp);
306        }
307        /* loco lags by 1 row so that it doesn't interfere with top prediction */
308        if (s->filter_type == PNG_FILTER_TYPE_LOCO &&
309            s->color_type == PNG_COLOR_TYPE_RGB && s->y > 0)
310            deloco_rgb24(ptr - s->image_linesize, s->row_size);
311        s->y++;
312        if (s->y == s->height) {
313            s->state |= PNG_ALLIMAGE;
314            if (s->filter_type == PNG_FILTER_TYPE_LOCO &&
315                s->color_type == PNG_COLOR_TYPE_RGB)
316                deloco_rgb24(ptr, s->row_size);
317        }
318    } else {
319        got_line = 0;
320        for(;;) {
321            ptr = s->image_buf + s->image_linesize * s->y;
322            if ((ff_png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) {
323                /* if we already read one row, it is time to stop to
324                   wait for the next one */
325                if (got_line)
326                    break;
327                png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
328                               s->last_row, s->pass_row_size, s->bpp);
329                FFSWAP(uint8_t*, s->last_row, s->tmp_row);
330                got_line = 1;
331            }
332            if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) {
333                /* NOTE: RGB32 is handled directly in png_put_interlaced_row */
334                png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass,
335                                       s->color_type, s->last_row);
336            }
337            s->y++;
338            if (s->y == s->height) {
339                for(;;) {
340                    if (s->pass == NB_PASSES - 1) {
341                        s->state |= PNG_ALLIMAGE;
342                        goto the_end;
343                    } else {
344                        s->pass++;
345                        s->y = 0;
346                        s->pass_row_size = ff_png_pass_row_size(s->pass,
347                                                             s->bits_per_pixel,
348                                                             s->width);
349                        s->crow_size = s->pass_row_size + 1;
350                        if (s->pass_row_size != 0)
351                            break;
352                        /* skip pass if empty row */
353                    }
354                }
355            }
356        }
357    the_end: ;
358    }
359}
360
361static int png_decode_idat(PNGDecContext *s, int length)
362{
363    int ret;
364    s->zstream.avail_in = length;
365    s->zstream.next_in = s->bytestream;
366    s->bytestream += length;
367
368    if(s->bytestream > s->bytestream_end)
369        return -1;
370
371    /* decode one line if possible */
372    while (s->zstream.avail_in > 0) {
373        ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
374        if (ret != Z_OK && ret != Z_STREAM_END) {
375            return -1;
376        }
377        if (s->zstream.avail_out == 0) {
378            if (!(s->state & PNG_ALLIMAGE)) {
379                png_handle_row(s);
380            }
381            s->zstream.avail_out = s->crow_size;
382            s->zstream.next_out = s->crow_buf;
383        }
384    }
385    return 0;
386}
387
388static int decode_frame(AVCodecContext *avctx,
389                        void *data, int *data_size,
390                        AVPacket *avpkt)
391{
392    const uint8_t *buf = avpkt->data;
393    int buf_size = avpkt->size;
394    PNGDecContext * const s = avctx->priv_data;
395    AVFrame *picture = data;
396    AVFrame *p;
397    uint8_t *crow_buf_base = NULL;
398    uint32_t tag, length;
399    int ret, crc;
400
401    FFSWAP(AVFrame *, s->current_picture, s->last_picture);
402    avctx->coded_frame= s->current_picture;
403    p = s->current_picture;
404
405    s->bytestream_start=
406    s->bytestream= buf;
407    s->bytestream_end= buf + buf_size;
408
409    /* check signature */
410    if (memcmp(s->bytestream, ff_pngsig, 8) != 0 &&
411        memcmp(s->bytestream, ff_mngsig, 8) != 0)
412        return -1;
413    s->bytestream+= 8;
414    s->y=
415    s->state=0;
416//    memset(s, 0, sizeof(PNGDecContext));
417    /* init the zlib */
418    s->zstream.zalloc = ff_png_zalloc;
419    s->zstream.zfree = ff_png_zfree;
420    s->zstream.opaque = NULL;
421    ret = inflateInit(&s->zstream);
422    if (ret != Z_OK)
423        return -1;
424    for(;;) {
425        int tag32;
426        if (s->bytestream >= s->bytestream_end)
427            goto fail;
428        length = bytestream_get_be32(&s->bytestream);
429        if (length > 0x7fffffff)
430            goto fail;
431        tag32 = bytestream_get_be32(&s->bytestream);
432        tag = bswap_32(tag32);
433        dprintf(avctx, "png: tag=%c%c%c%c length=%u\n",
434                (tag & 0xff),
435                ((tag >> 8) & 0xff),
436                ((tag >> 16) & 0xff),
437                ((tag >> 24) & 0xff), length);
438        switch(tag) {
439        case MKTAG('I', 'H', 'D', 'R'):
440            if (length != 13)
441                goto fail;
442            s->width = bytestream_get_be32(&s->bytestream);
443            s->height = bytestream_get_be32(&s->bytestream);
444            if(avcodec_check_dimensions(avctx, s->width, s->height)){
445                s->width= s->height= 0;
446                goto fail;
447            }
448            s->bit_depth = *s->bytestream++;
449            s->color_type = *s->bytestream++;
450            s->compression_type = *s->bytestream++;
451            s->filter_type = *s->bytestream++;
452            s->interlace_type = *s->bytestream++;
453            crc = bytestream_get_be32(&s->bytestream);
454            s->state |= PNG_IHDR;
455            dprintf(avctx, "width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n",
456                    s->width, s->height, s->bit_depth, s->color_type,
457                    s->compression_type, s->filter_type, s->interlace_type);
458            break;
459        case MKTAG('I', 'D', 'A', 'T'):
460            if (!(s->state & PNG_IHDR))
461                goto fail;
462            if (!(s->state & PNG_IDAT)) {
463                /* init image info */
464                avctx->width = s->width;
465                avctx->height = s->height;
466
467                s->channels = ff_png_get_nb_channels(s->color_type);
468                s->bits_per_pixel = s->bit_depth * s->channels;
469                s->bpp = (s->bits_per_pixel + 7) >> 3;
470                s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3;
471
472                if (s->bit_depth == 8 &&
473                    s->color_type == PNG_COLOR_TYPE_RGB) {
474                    avctx->pix_fmt = PIX_FMT_RGB24;
475                } else if (s->bit_depth == 8 &&
476                           s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
477                    avctx->pix_fmt = PIX_FMT_RGB32;
478                } else if (s->bit_depth == 8 &&
479                           s->color_type == PNG_COLOR_TYPE_GRAY) {
480                    avctx->pix_fmt = PIX_FMT_GRAY8;
481                } else if (s->bit_depth == 16 &&
482                           s->color_type == PNG_COLOR_TYPE_GRAY) {
483                    avctx->pix_fmt = PIX_FMT_GRAY16BE;
484                } else if (s->bit_depth == 16 &&
485                           s->color_type == PNG_COLOR_TYPE_RGB) {
486                    avctx->pix_fmt = PIX_FMT_RGB48BE;
487                } else if (s->bit_depth == 1 &&
488                           s->color_type == PNG_COLOR_TYPE_GRAY) {
489                    avctx->pix_fmt = PIX_FMT_MONOBLACK;
490                } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
491                    avctx->pix_fmt = PIX_FMT_PAL8;
492                } else if (s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
493                    avctx->pix_fmt = PIX_FMT_Y400A;
494                } else {
495                    goto fail;
496                }
497                if(p->data[0])
498                    avctx->release_buffer(avctx, p);
499
500                p->reference= 0;
501                if(avctx->get_buffer(avctx, p) < 0){
502                    av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
503                    goto fail;
504                }
505                p->pict_type= FF_I_TYPE;
506                p->key_frame= 1;
507                p->interlaced_frame = !!s->interlace_type;
508
509                /* compute the compressed row size */
510                if (!s->interlace_type) {
511                    s->crow_size = s->row_size + 1;
512                } else {
513                    s->pass = 0;
514                    s->pass_row_size = ff_png_pass_row_size(s->pass,
515                                                         s->bits_per_pixel,
516                                                         s->width);
517                    s->crow_size = s->pass_row_size + 1;
518                }
519                dprintf(avctx, "row_size=%d crow_size =%d\n",
520                        s->row_size, s->crow_size);
521                s->image_buf = p->data[0];
522                s->image_linesize = p->linesize[0];
523                /* copy the palette if needed */
524                if (s->color_type == PNG_COLOR_TYPE_PALETTE)
525                    memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t));
526                /* empty row is used if differencing to the first row */
527                s->last_row = av_mallocz(s->row_size);
528                if (!s->last_row)
529                    goto fail;
530                if (s->interlace_type ||
531                    s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
532                    s->tmp_row = av_malloc(s->row_size);
533                    if (!s->tmp_row)
534                        goto fail;
535                }
536                /* compressed row */
537                crow_buf_base = av_malloc(s->row_size + 16);
538                if (!crow_buf_base)
539                    goto fail;
540
541                /* we want crow_buf+1 to be 16-byte aligned */
542                s->crow_buf = crow_buf_base + 15;
543                s->zstream.avail_out = s->crow_size;
544                s->zstream.next_out = s->crow_buf;
545            }
546            s->state |= PNG_IDAT;
547            if (png_decode_idat(s, length) < 0)
548                goto fail;
549            /* skip crc */
550            crc = bytestream_get_be32(&s->bytestream);
551            break;
552        case MKTAG('P', 'L', 'T', 'E'):
553            {
554                int n, i, r, g, b;
555
556                if ((length % 3) != 0 || length > 256 * 3)
557                    goto skip_tag;
558                /* read the palette */
559                n = length / 3;
560                for(i=0;i<n;i++) {
561                    r = *s->bytestream++;
562                    g = *s->bytestream++;
563                    b = *s->bytestream++;
564                    s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b;
565                }
566                for(;i<256;i++) {
567                    s->palette[i] = (0xff << 24);
568                }
569                s->state |= PNG_PLTE;
570                crc = bytestream_get_be32(&s->bytestream);
571            }
572            break;
573        case MKTAG('t', 'R', 'N', 'S'):
574            {
575                int v, i;
576
577                /* read the transparency. XXX: Only palette mode supported */
578                if (s->color_type != PNG_COLOR_TYPE_PALETTE ||
579                    length > 256 ||
580                    !(s->state & PNG_PLTE))
581                    goto skip_tag;
582                for(i=0;i<length;i++) {
583                    v = *s->bytestream++;
584                    s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24);
585                }
586                crc = bytestream_get_be32(&s->bytestream);
587            }
588            break;
589        case MKTAG('I', 'E', 'N', 'D'):
590            if (!(s->state & PNG_ALLIMAGE))
591                goto fail;
592            crc = bytestream_get_be32(&s->bytestream);
593            goto exit_loop;
594        default:
595            /* skip tag */
596        skip_tag:
597            s->bytestream += length + 4;
598            break;
599        }
600    }
601 exit_loop:
602     /* handle p-frames only if a predecessor frame is available */
603     if(s->last_picture->data[0] != NULL) {
604         if(!(avpkt->flags & AV_PKT_FLAG_KEY)) {
605            int i, j;
606            uint8_t *pd = s->current_picture->data[0];
607            uint8_t *pd_last = s->last_picture->data[0];
608
609            for(j=0; j < s->height; j++) {
610                for(i=0; i < s->width * s->bpp; i++) {
611                    pd[i] += pd_last[i];
612                }
613                pd += s->image_linesize;
614                pd_last += s->image_linesize;
615            }
616        }
617    }
618
619    *picture= *s->current_picture;
620    *data_size = sizeof(AVFrame);
621
622    ret = s->bytestream - s->bytestream_start;
623 the_end:
624    inflateEnd(&s->zstream);
625    av_free(crow_buf_base);
626    s->crow_buf = NULL;
627    av_freep(&s->last_row);
628    av_freep(&s->tmp_row);
629    return ret;
630 fail:
631    ret = -1;
632    goto the_end;
633}
634
635static av_cold int png_dec_init(AVCodecContext *avctx){
636    PNGDecContext *s = avctx->priv_data;
637
638    s->current_picture = &s->picture1;
639    s->last_picture = &s->picture2;
640    avcodec_get_frame_defaults(&s->picture1);
641    avcodec_get_frame_defaults(&s->picture2);
642    dsputil_init(&s->dsp, avctx);
643
644    return 0;
645}
646
647static av_cold int png_dec_end(AVCodecContext *avctx)
648{
649    PNGDecContext *s = avctx->priv_data;
650
651    if (s->picture1.data[0])
652        avctx->release_buffer(avctx, &s->picture1);
653    if (s->picture2.data[0])
654        avctx->release_buffer(avctx, &s->picture2);
655
656    return 0;
657}
658
659AVCodec png_decoder = {
660    "png",
661    AVMEDIA_TYPE_VIDEO,
662    CODEC_ID_PNG,
663    sizeof(PNGDecContext),
664    png_dec_init,
665    NULL,
666    png_dec_end,
667    decode_frame,
668    CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
669    NULL,
670    .long_name = NULL_IF_CONFIG_SMALL("PNG image"),
671};
672