Revision b958a7f1

View differences:

libavcodec/Makefile
129 129
OBJS-$(CONFIG_PBM_ENCODER)             += pnmenc.o pnm.o
130 130
OBJS-$(CONFIG_PGM_ENCODER)             += pnmenc.o pnm.o
131 131
OBJS-$(CONFIG_PGMYUV_ENCODER)          += pnmenc.o pnm.o
132
OBJS-$(CONFIG_PNG_DECODER)             += png.o
133
OBJS-$(CONFIG_PNG_ENCODER)             += png.o
132
OBJS-$(CONFIG_PNG_DECODER)             += png.o pngdec.o
133
OBJS-$(CONFIG_PNG_ENCODER)             += png.o pngenc.o
134 134
OBJS-$(CONFIG_PPM_ENCODER)             += pnmenc.o pnm.o
135 135
OBJS-$(CONFIG_PTX_DECODER)             += ptx.o
136 136
OBJS-$(CONFIG_QDM2_DECODER)            += qdm2.o mdct.o fft.o mpegaudiodec.o mpegaudiodecheader.o mpegaudio.o mpegaudiodata.o
libavcodec/png.c
20 20
 */
21 21
#include "avcodec.h"
22 22
#include "bytestream.h"
23
#include "png.h"
23 24

  
24
/* TODO:
25
 * - add 2, 4 and 16 bit depth support
26
 * - use filters when generating a png (better compression)
27
 */
28

  
29
#include <zlib.h>
30

  
31
//#define DEBUG
32

  
33
#define PNG_COLOR_MASK_PALETTE    1
34
#define PNG_COLOR_MASK_COLOR      2
35
#define PNG_COLOR_MASK_ALPHA      4
36

  
37
#define PNG_COLOR_TYPE_GRAY 0
38
#define PNG_COLOR_TYPE_PALETTE  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
39
#define PNG_COLOR_TYPE_RGB        (PNG_COLOR_MASK_COLOR)
40
#define PNG_COLOR_TYPE_RGB_ALPHA  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
41
#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
42

  
43
#define PNG_FILTER_VALUE_NONE  0
44
#define PNG_FILTER_VALUE_SUB   1
45
#define PNG_FILTER_VALUE_UP    2
46
#define PNG_FILTER_VALUE_AVG   3
47
#define PNG_FILTER_VALUE_PAETH 4
48

  
49
#define PNG_IHDR      0x0001
50
#define PNG_IDAT      0x0002
51
#define PNG_ALLIMAGE  0x0004
52
#define PNG_PLTE      0x0008
53

  
54
#define NB_PASSES 7
55

  
56
#define IOBUF_SIZE 4096
57

  
58
typedef struct PNGContext {
59
    uint8_t *bytestream;
60
    uint8_t *bytestream_start;
61
    uint8_t *bytestream_end;
62
    AVFrame picture;
63

  
64
    int state;
65
    int width, height;
66
    int bit_depth;
67
    int color_type;
68
    int compression_type;
69
    int interlace_type;
70
    int filter_type;
71
    int channels;
72
    int bits_per_pixel;
73
    int bpp;
74

  
75
    uint8_t *image_buf;
76
    int image_linesize;
77
    uint32_t palette[256];
78
    uint8_t *crow_buf;
79
    uint8_t *last_row;
80
    uint8_t *tmp_row;
81
    int pass;
82
    int crow_size; /* compressed row size (include filter type) */
83
    int row_size; /* decompressed row size */
84
    int pass_row_size; /* decompress row size of the current pass */
85
    int y;
86
    z_stream zstream;
87
    uint8_t buf[IOBUF_SIZE];
88
} PNGContext;
89

  
90
static const uint8_t pngsig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
25
const uint8_t ff_pngsig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
91 26

  
92 27
/* Mask to determine which y pixels are valid in a pass */
93
static const uint8_t png_pass_ymask[NB_PASSES] = {
28
const uint8_t ff_png_pass_ymask[NB_PASSES] = {
94 29
    0x80, 0x80, 0x08, 0x88, 0x22, 0xaa, 0x55,
95 30
};
96 31

  
97
/* Mask to determine which y pixels can be written in a pass */
98
static const uint8_t png_pass_dsp_ymask[NB_PASSES] = {
99
    0xff, 0xff, 0x0f, 0xcc, 0x33, 0xff, 0x55,
100
};
101

  
102 32
/* minimum x value */
103
static const uint8_t png_pass_xmin[NB_PASSES] = {
33
const uint8_t ff_png_pass_xmin[NB_PASSES] = {
104 34
    0, 4, 0, 2, 0, 1, 0
105 35
};
106 36

  
107 37
/* x shift to get row width */
108
static const uint8_t png_pass_xshift[NB_PASSES] = {
38
const uint8_t ff_png_pass_xshift[NB_PASSES] = {
109 39
    3, 3, 2, 2, 1, 1, 0
110 40
};
111 41

  
112 42
/* Mask to determine which pixels are valid in a pass */
113
static const uint8_t png_pass_mask[NB_PASSES] = {
43
const uint8_t ff_png_pass_mask[NB_PASSES] = {
114 44
    0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff
115 45
};
116 46

  
117
/* Mask to determine which pixels to overwrite while displaying */
118
static const uint8_t png_pass_dsp_mask[NB_PASSES] = {
119
    0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff
120
};
121
#if 0
122
static int png_probe(AVProbeData *pd)
123
{
124
    if (pd->buf_size >= 8 &&
125
        memcmp(pd->buf, pngsig, 8) == 0)
126
        return AVPROBE_SCORE_MAX;
127
    else
128
        return 0;
129
}
130
#endif
131
static void *png_zalloc(void *opaque, unsigned int items, unsigned int size)
47
void *ff_png_zalloc(void *opaque, unsigned int items, unsigned int size)
132 48
{
133 49
    if(items >= UINT_MAX / size)
134 50
        return NULL;
135 51
    return av_malloc(items * size);
136 52
}
137 53

  
138
static void png_zfree(void *opaque, void *ptr)
54
void ff_png_zfree(void *opaque, void *ptr)
139 55
{
140 56
    av_free(ptr);
141 57
}
142 58

  
143
static int png_get_nb_channels(int color_type)
59
int ff_png_get_nb_channels(int color_type)
144 60
{
145 61
    int channels;
146 62
    channels = 1;
......
153 69
}
154 70

  
155 71
/* compute the row size of an interleaved pass */
156
static int png_pass_row_size(int pass, int bits_per_pixel, int width)
72
int ff_png_pass_row_size(int pass, int bits_per_pixel, int width)
157 73
{
158 74
    int shift, xmin, pass_width;
159 75

  
160
    xmin = png_pass_xmin[pass];
76
    xmin = ff_png_pass_xmin[pass];
161 77
    if (width <= xmin)
162 78
        return 0;
163
    shift = png_pass_xshift[pass];
79
    shift = ff_png_pass_xshift[pass];
164 80
    pass_width = (width - xmin + (1 << shift) - 1) >> shift;
165 81
    return (pass_width * bits_per_pixel + 7) >> 3;
166 82
}
167 83

  
168
/* NOTE: we try to construct a good looking image at each pass. width
169
   is the original image width. We also do pixel format convertion at
170
   this stage */
171
static void png_put_interlaced_row(uint8_t *dst, int width,
172
                                   int bits_per_pixel, int pass,
173
                                   int color_type, const uint8_t *src)
174
{
175
    int x, mask, dsp_mask, j, src_x, b, bpp;
176
    uint8_t *d;
177
    const uint8_t *s;
178

  
179
    mask = png_pass_mask[pass];
180
    dsp_mask = png_pass_dsp_mask[pass];
181
    switch(bits_per_pixel) {
182
    case 1:
183
        /* we must initialize the line to zero before writing to it */
184
        if (pass == 0)
185
            memset(dst, 0, (width + 7) >> 3);
186
        src_x = 0;
187
        for(x = 0; x < width; x++) {
188
            j = (x & 7);
189
            if ((dsp_mask << j) & 0x80) {
190
                b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1;
191
                dst[x >> 3] |= b << (7 - j);
192
            }
193
            if ((mask << j) & 0x80)
194
                src_x++;
195
        }
196
        break;
197
    default:
198
        bpp = bits_per_pixel >> 3;
199
        d = dst;
200
        s = src;
201
        if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
202
            for(x = 0; x < width; x++) {
203
                j = x & 7;
204
                if ((dsp_mask << j) & 0x80) {
205
                    *(uint32_t *)d = (s[3] << 24) | (s[0] << 16) | (s[1] << 8) | s[2];
206
                }
207
                d += bpp;
208
                if ((mask << j) & 0x80)
209
                    s += bpp;
210
            }
211
        } else {
212
            for(x = 0; x < width; x++) {
213
                j = x & 7;
214
                if ((dsp_mask << j) & 0x80) {
215
                    memcpy(d, s, bpp);
216
                }
217
                d += bpp;
218
                if ((mask << j) & 0x80)
219
                    s += bpp;
220
            }
221
        }
222
        break;
223
    }
224
}
225

  
226
#ifdef CONFIG_ENCODERS
227
static void png_get_interlaced_row(uint8_t *dst, int row_size,
228
                                   int bits_per_pixel, int pass,
229
                                   const uint8_t *src, int width)
230
{
231
    int x, mask, dst_x, j, b, bpp;
232
    uint8_t *d;
233
    const uint8_t *s;
234

  
235
    mask = png_pass_mask[pass];
236
    switch(bits_per_pixel) {
237
    case 1:
238
        memset(dst, 0, row_size);
239
        dst_x = 0;
240
        for(x = 0; x < width; x++) {
241
            j = (x & 7);
242
            if ((mask << j) & 0x80) {
243
                b = (src[x >> 3] >> (7 - j)) & 1;
244
                dst[dst_x >> 3] |= b << (7 - (dst_x & 7));
245
                dst_x++;
246
            }
247
        }
248
        break;
249
    default:
250
        bpp = bits_per_pixel >> 3;
251
        d = dst;
252
        s = src;
253
        for(x = 0; x < width; x++) {
254
            j = x & 7;
255
            if ((mask << j) & 0x80) {
256
                memcpy(d, s, bpp);
257
                d += bpp;
258
            }
259
            s += bpp;
260
        }
261
        break;
262
    }
263
}
264
#endif
265

  
266
/* XXX: optimize */
267
/* NOTE: 'dst' can be equal to 'last' */
268
static void png_filter_row(uint8_t *dst, int filter_type,
269
                           uint8_t *src, uint8_t *last, int size, int bpp)
270
{
271
    int i, p;
272

  
273
    switch(filter_type) {
274
    case PNG_FILTER_VALUE_NONE:
275
        memcpy(dst, src, size);
276
        break;
277
    case PNG_FILTER_VALUE_SUB:
278
        for(i = 0; i < bpp; i++) {
279
            dst[i] = src[i];
280
        }
281
        for(i = bpp; i < size; i++) {
282
            p = dst[i - bpp];
283
            dst[i] = p + src[i];
284
        }
285
        break;
286
    case PNG_FILTER_VALUE_UP:
287
        for(i = 0; i < size; i++) {
288
            p = last[i];
289
            dst[i] = p + src[i];
290
        }
291
        break;
292
    case PNG_FILTER_VALUE_AVG:
293
        for(i = 0; i < bpp; i++) {
294
            p = (last[i] >> 1);
295
            dst[i] = p + src[i];
296
        }
297
        for(i = bpp; i < size; i++) {
298
            p = ((dst[i - bpp] + last[i]) >> 1);
299
            dst[i] = p + src[i];
300
        }
301
        break;
302
    case PNG_FILTER_VALUE_PAETH:
303
        for(i = 0; i < bpp; i++) {
304
            p = last[i];
305
            dst[i] = p + src[i];
306
        }
307
        for(i = bpp; i < size; i++) {
308
            int a, b, c, pa, pb, pc;
309

  
310
            a = dst[i - bpp];
311
            b = last[i];
312
            c = last[i - bpp];
313

  
314
            p = b - c;
315
            pc = a - c;
316

  
317
            pa = abs(p);
318
            pb = abs(pc);
319
            pc = abs(p + pc);
320

  
321
            if (pa <= pb && pa <= pc)
322
                p = a;
323
            else if (pb <= pc)
324
                p = b;
325
            else
326
                p = c;
327
            dst[i] = p + src[i];
328
        }
329
        break;
330
    }
331
}
332

  
333
#ifdef CONFIG_ENCODERS
334
static void convert_from_rgb32(uint8_t *dst, const uint8_t *src, int width)
335
{
336
    uint8_t *d;
337
    int j;
338
    unsigned int v;
339

  
340
    d = dst;
341
    for(j = 0; j < width; j++) {
342
        v = ((const uint32_t *)src)[j];
343
        d[0] = v >> 16;
344
        d[1] = v >> 8;
345
        d[2] = v;
346
        d[3] = v >> 24;
347
        d += 4;
348
    }
349
}
350
#endif
351

  
352
#ifdef CONFIG_DECODERS
353
static void convert_to_rgb32(uint8_t *dst, const uint8_t *src, int width)
354
{
355
    int j;
356
    unsigned int r, g, b, a;
357

  
358
    for(j = 0;j < width; j++) {
359
        r = src[0];
360
        g = src[1];
361
        b = src[2];
362
        a = src[3];
363
        *(uint32_t *)dst = (a << 24) | (r << 16) | (g << 8) | b;
364
        dst += 4;
365
        src += 4;
366
    }
367
}
368

  
369
/* process exactly one decompressed row */
370
static void png_handle_row(PNGContext *s)
371
{
372
    uint8_t *ptr, *last_row;
373
    int got_line;
374

  
375
    if (!s->interlace_type) {
376
        ptr = s->image_buf + s->image_linesize * s->y;
377
        /* need to swap bytes correctly for RGB_ALPHA */
378
        if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
379
            png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
380
                           s->last_row, s->row_size, s->bpp);
381
            memcpy(s->last_row, s->tmp_row, s->row_size);
382
            convert_to_rgb32(ptr, s->tmp_row, s->width);
383
        } else {
384
            /* in normal case, we avoid one copy */
385
            if (s->y == 0)
386
                last_row = s->last_row;
387
            else
388
                last_row = ptr - s->image_linesize;
389

  
390
            png_filter_row(ptr, s->crow_buf[0], s->crow_buf + 1,
391
                           last_row, s->row_size, s->bpp);
392
        }
393
        s->y++;
394
        if (s->y == s->height) {
395
            s->state |= PNG_ALLIMAGE;
396
        }
397
    } else {
398
        got_line = 0;
399
        for(;;) {
400
            ptr = s->image_buf + s->image_linesize * s->y;
401
            if ((png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) {
402
                /* if we already read one row, it is time to stop to
403
                   wait for the next one */
404
                if (got_line)
405
                    break;
406
                png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
407
                               s->last_row, s->pass_row_size, s->bpp);
408
                memcpy(s->last_row, s->tmp_row, s->pass_row_size);
409
                got_line = 1;
410
            }
411
            if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) {
412
                /* NOTE: RGB32 is handled directly in png_put_interlaced_row */
413
                png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass,
414
                                       s->color_type, s->last_row);
415
            }
416
            s->y++;
417
            if (s->y == s->height) {
418
                for(;;) {
419
                    if (s->pass == NB_PASSES - 1) {
420
                        s->state |= PNG_ALLIMAGE;
421
                        goto the_end;
422
                    } else {
423
                        s->pass++;
424
                        s->y = 0;
425
                        s->pass_row_size = png_pass_row_size(s->pass,
426
                                                             s->bits_per_pixel,
427
                                                             s->width);
428
                        s->crow_size = s->pass_row_size + 1;
429
                        if (s->pass_row_size != 0)
430
                            break;
431
                        /* skip pass if empty row */
432
                    }
433
                }
434
            }
435
        }
436
    the_end: ;
437
    }
438
}
439

  
440
static int png_decode_idat(PNGContext *s, int length)
441
{
442
    int ret;
443
    s->zstream.avail_in = length;
444
    s->zstream.next_in = s->bytestream;
445
    s->bytestream += length;
446

  
447
    if(s->bytestream > s->bytestream_end)
448
        return -1;
449

  
450
    /* decode one line if possible */
451
    while (s->zstream.avail_in > 0) {
452
        ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
453
        if (ret != Z_OK && ret != Z_STREAM_END) {
454
            return -1;
455
        }
456
        if (s->zstream.avail_out == 0) {
457
            if (!(s->state & PNG_ALLIMAGE)) {
458
                png_handle_row(s);
459
            }
460
            s->zstream.avail_out = s->crow_size;
461
            s->zstream.next_out = s->crow_buf;
462
        }
463
    }
464
    return 0;
465
}
466

  
467
static int decode_frame(AVCodecContext *avctx,
468
                        void *data, int *data_size,
469
                        uint8_t *buf, int buf_size)
470
{
471
    PNGContext * const s = avctx->priv_data;
472
    AVFrame *picture = data;
473
    AVFrame * const p= (AVFrame*)&s->picture;
474
    uint32_t tag, length;
475
    int ret, crc;
476

  
477
    s->bytestream_start=
478
    s->bytestream= buf;
479
    s->bytestream_end= buf + buf_size;
480

  
481
    /* check signature */
482
    if (memcmp(s->bytestream, pngsig, 8) != 0)
483
        return -1;
484
    s->bytestream+= 8;
485
    s->y=
486
    s->state=0;
487
//    memset(s, 0, sizeof(PNGContext));
488
    /* init the zlib */
489
    s->zstream.zalloc = png_zalloc;
490
    s->zstream.zfree = png_zfree;
491
    s->zstream.opaque = NULL;
492
    ret = inflateInit(&s->zstream);
493
    if (ret != Z_OK)
494
        return -1;
495
    for(;;) {
496
        int tag32;
497
        if (s->bytestream >= s->bytestream_end)
498
            goto fail;
499
        length = bytestream_get_be32(&s->bytestream);
500
        if (length > 0x7fffffff)
501
            goto fail;
502
        tag32 = bytestream_get_be32(&s->bytestream);
503
        tag = bswap_32(tag32);
504
#ifdef DEBUG
505
        av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n",
506
               (tag & 0xff),
507
               ((tag >> 8) & 0xff),
508
               ((tag >> 16) & 0xff),
509
               ((tag >> 24) & 0xff), length);
510
#endif
511
        switch(tag) {
512
        case MKTAG('I', 'H', 'D', 'R'):
513
            if (length != 13)
514
                goto fail;
515
            s->width = bytestream_get_be32(&s->bytestream);
516
            s->height = bytestream_get_be32(&s->bytestream);
517
            if(avcodec_check_dimensions(avctx, s->width, s->height)){
518
                s->width= s->height= 0;
519
                goto fail;
520
            }
521
            s->bit_depth = *s->bytestream++;
522
            s->color_type = *s->bytestream++;
523
            s->compression_type = *s->bytestream++;
524
            s->filter_type = *s->bytestream++;
525
            s->interlace_type = *s->bytestream++;
526
            crc = bytestream_get_be32(&s->bytestream);
527
            s->state |= PNG_IHDR;
528
#ifdef DEBUG
529
            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",
530
                   s->width, s->height, s->bit_depth, s->color_type,
531
                   s->compression_type, s->filter_type, s->interlace_type);
532
#endif
533
            break;
534
        case MKTAG('I', 'D', 'A', 'T'):
535
            if (!(s->state & PNG_IHDR))
536
                goto fail;
537
            if (!(s->state & PNG_IDAT)) {
538
                /* init image info */
539
                avctx->width = s->width;
540
                avctx->height = s->height;
541

  
542
                s->channels = png_get_nb_channels(s->color_type);
543
                s->bits_per_pixel = s->bit_depth * s->channels;
544
                s->bpp = (s->bits_per_pixel + 7) >> 3;
545
                s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3;
546

  
547
                if (s->bit_depth == 8 &&
548
                    s->color_type == PNG_COLOR_TYPE_RGB) {
549
                    avctx->pix_fmt = PIX_FMT_RGB24;
550
                } else if (s->bit_depth == 8 &&
551
                           s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
552
                    avctx->pix_fmt = PIX_FMT_RGB32;
553
                } else if (s->bit_depth == 8 &&
554
                           s->color_type == PNG_COLOR_TYPE_GRAY) {
555
                    avctx->pix_fmt = PIX_FMT_GRAY8;
556
                } else if (s->bit_depth == 16 &&
557
                           s->color_type == PNG_COLOR_TYPE_GRAY) {
558
                    avctx->pix_fmt = PIX_FMT_GRAY16BE;
559
                } else if (s->bit_depth == 1 &&
560
                           s->color_type == PNG_COLOR_TYPE_GRAY) {
561
                    avctx->pix_fmt = PIX_FMT_MONOBLACK;
562
                } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
563
                    avctx->pix_fmt = PIX_FMT_PAL8;
564
                } else {
565
                    goto fail;
566
                }
567
                if(p->data[0])
568
                    avctx->release_buffer(avctx, p);
569

  
570
                p->reference= 0;
571
                if(avctx->get_buffer(avctx, p) < 0){
572
                    av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
573
                    goto fail;
574
                }
575
                p->pict_type= FF_I_TYPE;
576
                p->key_frame= 1;
577
                p->interlaced_frame = !!s->interlace_type;
578

  
579
                /* compute the compressed row size */
580
                if (!s->interlace_type) {
581
                    s->crow_size = s->row_size + 1;
582
                } else {
583
                    s->pass = 0;
584
                    s->pass_row_size = png_pass_row_size(s->pass,
585
                                                         s->bits_per_pixel,
586
                                                         s->width);
587
                    s->crow_size = s->pass_row_size + 1;
588
                }
589
#ifdef DEBUG
590
                av_log(avctx, AV_LOG_DEBUG, "row_size=%d crow_size =%d\n",
591
                       s->row_size, s->crow_size);
592
#endif
593
                s->image_buf = p->data[0];
594
                s->image_linesize = p->linesize[0];
595
                /* copy the palette if needed */
596
                if (s->color_type == PNG_COLOR_TYPE_PALETTE)
597
                    memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t));
598
                /* empty row is used if differencing to the first row */
599
                s->last_row = av_mallocz(s->row_size);
600
                if (!s->last_row)
601
                    goto fail;
602
                if (s->interlace_type ||
603
                    s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
604
                    s->tmp_row = av_malloc(s->row_size);
605
                    if (!s->tmp_row)
606
                        goto fail;
607
                }
608
                /* compressed row */
609
                s->crow_buf = av_malloc(s->row_size + 1);
610
                if (!s->crow_buf)
611
                    goto fail;
612
                s->zstream.avail_out = s->crow_size;
613
                s->zstream.next_out = s->crow_buf;
614
            }
615
            s->state |= PNG_IDAT;
616
            if (png_decode_idat(s, length) < 0)
617
                goto fail;
618
            /* skip crc */
619
            crc = bytestream_get_be32(&s->bytestream);
620
            break;
621
        case MKTAG('P', 'L', 'T', 'E'):
622
            {
623
                int n, i, r, g, b;
624

  
625
                if ((length % 3) != 0 || length > 256 * 3)
626
                    goto skip_tag;
627
                /* read the palette */
628
                n = length / 3;
629
                for(i=0;i<n;i++) {
630
                    r = *s->bytestream++;
631
                    g = *s->bytestream++;
632
                    b = *s->bytestream++;
633
                    s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b;
634
                }
635
                for(;i<256;i++) {
636
                    s->palette[i] = (0xff << 24);
637
                }
638
                s->state |= PNG_PLTE;
639
                crc = bytestream_get_be32(&s->bytestream);
640
            }
641
            break;
642
        case MKTAG('t', 'R', 'N', 'S'):
643
            {
644
                int v, i;
645

  
646
                /* read the transparency. XXX: Only palette mode supported */
647
                if (s->color_type != PNG_COLOR_TYPE_PALETTE ||
648
                    length > 256 ||
649
                    !(s->state & PNG_PLTE))
650
                    goto skip_tag;
651
                for(i=0;i<length;i++) {
652
                    v = *s->bytestream++;
653
                    s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24);
654
                }
655
                crc = bytestream_get_be32(&s->bytestream);
656
            }
657
            break;
658
        case MKTAG('I', 'E', 'N', 'D'):
659
            if (!(s->state & PNG_ALLIMAGE))
660
                goto fail;
661
            crc = bytestream_get_be32(&s->bytestream);
662
            goto exit_loop;
663
        default:
664
            /* skip tag */
665
        skip_tag:
666
            s->bytestream += length + 4;
667
            break;
668
        }
669
    }
670
 exit_loop:
671
    *picture= *(AVFrame*)&s->picture;
672
    *data_size = sizeof(AVPicture);
673

  
674
    ret = s->bytestream - s->bytestream_start;
675
 the_end:
676
    inflateEnd(&s->zstream);
677
    av_freep(&s->crow_buf);
678
    av_freep(&s->last_row);
679
    av_freep(&s->tmp_row);
680
    return ret;
681
 fail:
682
    ret = -1;
683
    goto the_end;
684
}
685
#endif
686

  
687
#ifdef CONFIG_ENCODERS
688
static void png_write_chunk(uint8_t **f, uint32_t tag,
689
                            const uint8_t *buf, int length)
690
{
691
    uint32_t crc;
692
    uint8_t tagbuf[4];
693

  
694
    bytestream_put_be32(f, length);
695
    crc = crc32(0, Z_NULL, 0);
696
    AV_WL32(tagbuf, tag);
697
    crc = crc32(crc, tagbuf, 4);
698
    bytestream_put_be32(f, bswap_32(tag));
699
    if (length > 0) {
700
        crc = crc32(crc, buf, length);
701
        memcpy(*f, buf, length);
702
        *f += length;
703
    }
704
    bytestream_put_be32(f, crc);
705
}
706

  
707
/* XXX: do filtering */
708
static int png_write_row(PNGContext *s, const uint8_t *data, int size)
709
{
710
    int ret;
711

  
712
    s->zstream.avail_in = size;
713
    s->zstream.next_in = (uint8_t *)data;
714
    while (s->zstream.avail_in > 0) {
715
        ret = deflate(&s->zstream, Z_NO_FLUSH);
716
        if (ret != Z_OK)
717
            return -1;
718
        if (s->zstream.avail_out == 0) {
719
            if(s->bytestream_end - s->bytestream > IOBUF_SIZE + 100)
720
                png_write_chunk(&s->bytestream, MKTAG('I', 'D', 'A', 'T'), s->buf, IOBUF_SIZE);
721
            s->zstream.avail_out = IOBUF_SIZE;
722
            s->zstream.next_out = s->buf;
723
        }
724
    }
725
    return 0;
726
}
727
#endif /* CONFIG_ENCODERS */
728

  
729
static int common_init(AVCodecContext *avctx){
84
int ff_png_common_init(AVCodecContext *avctx){
730 85
    PNGContext *s = avctx->priv_data;
731 86

  
732 87
    avcodec_get_frame_defaults((AVFrame*)&s->picture);
......
735 90

  
736 91
    return 0;
737 92
}
738

  
739
#ifdef CONFIG_ENCODERS
740
static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
741
    PNGContext *s = avctx->priv_data;
742
    AVFrame *pict = data;
743
    AVFrame * const p= (AVFrame*)&s->picture;
744
    int bit_depth, color_type, y, len, row_size, ret, is_progressive;
745
    int bits_per_pixel, pass_row_size;
746
    uint8_t *ptr;
747
    uint8_t *crow_buf = NULL;
748
    uint8_t *tmp_buf = NULL;
749

  
750
    *p = *pict;
751
    p->pict_type= FF_I_TYPE;
752
    p->key_frame= 1;
753

  
754
    s->bytestream_start=
755
    s->bytestream= buf;
756
    s->bytestream_end= buf+buf_size;
757

  
758
    is_progressive = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT);
759
    switch(avctx->pix_fmt) {
760
    case PIX_FMT_RGB32:
761
        bit_depth = 8;
762
        color_type = PNG_COLOR_TYPE_RGB_ALPHA;
763
        break;
764
    case PIX_FMT_RGB24:
765
        bit_depth = 8;
766
        color_type = PNG_COLOR_TYPE_RGB;
767
        break;
768
    case PIX_FMT_GRAY8:
769
        bit_depth = 8;
770
        color_type = PNG_COLOR_TYPE_GRAY;
771
        break;
772
    case PIX_FMT_MONOBLACK:
773
        bit_depth = 1;
774
        color_type = PNG_COLOR_TYPE_GRAY;
775
        break;
776
    case PIX_FMT_PAL8:
777
        bit_depth = 8;
778
        color_type = PNG_COLOR_TYPE_PALETTE;
779
        break;
780
    default:
781
        return -1;
782
    }
783
    bits_per_pixel = png_get_nb_channels(color_type) * bit_depth;
784
    row_size = (avctx->width * bits_per_pixel + 7) >> 3;
785

  
786
    s->zstream.zalloc = png_zalloc;
787
    s->zstream.zfree = png_zfree;
788
    s->zstream.opaque = NULL;
789
    ret = deflateInit2(&s->zstream, Z_DEFAULT_COMPRESSION,
790
                       Z_DEFLATED, 15, 8, Z_DEFAULT_STRATEGY);
791
    if (ret != Z_OK)
792
        return -1;
793
    crow_buf = av_malloc(row_size + 1);
794
    if (!crow_buf)
795
        goto fail;
796
    if (is_progressive) {
797
        tmp_buf = av_malloc(row_size + 1);
798
        if (!tmp_buf)
799
            goto fail;
800
    }
801

  
802
    /* write png header */
803
    memcpy(s->bytestream, pngsig, 8);
804
    s->bytestream += 8;
805

  
806
    AV_WB32(s->buf, avctx->width);
807
    AV_WB32(s->buf + 4, avctx->height);
808
    s->buf[8] = bit_depth;
809
    s->buf[9] = color_type;
810
    s->buf[10] = 0; /* compression type */
811
    s->buf[11] = 0; /* filter type */
812
    s->buf[12] = is_progressive; /* interlace type */
813

  
814
    png_write_chunk(&s->bytestream, MKTAG('I', 'H', 'D', 'R'), s->buf, 13);
815

  
816
    /* put the palette if needed */
817
    if (color_type == PNG_COLOR_TYPE_PALETTE) {
818
        int has_alpha, alpha, i;
819
        unsigned int v;
820
        uint32_t *palette;
821
        uint8_t *alpha_ptr;
822

  
823
        palette = (uint32_t *)p->data[1];
824
        ptr = s->buf;
825
        alpha_ptr = s->buf + 256 * 3;
826
        has_alpha = 0;
827
        for(i = 0; i < 256; i++) {
828
            v = palette[i];
829
            alpha = v >> 24;
830
            if (alpha && alpha != 0xff)
831
                has_alpha = 1;
832
            *alpha_ptr++ = alpha;
833
            bytestream_put_be24(&ptr, v);
834
        }
835
        png_write_chunk(&s->bytestream, MKTAG('P', 'L', 'T', 'E'), s->buf, 256 * 3);
836
        if (has_alpha) {
837
            png_write_chunk(&s->bytestream, MKTAG('t', 'R', 'N', 'S'), s->buf + 256 * 3, 256);
838
        }
839
    }
840

  
841
    /* now put each row */
842
    s->zstream.avail_out = IOBUF_SIZE;
843
    s->zstream.next_out = s->buf;
844
    if (is_progressive) {
845
        uint8_t *ptr1;
846
        int pass;
847

  
848
        for(pass = 0; pass < NB_PASSES; pass++) {
849
            /* NOTE: a pass is completely omited if no pixels would be
850
               output */
851
            pass_row_size = png_pass_row_size(pass, bits_per_pixel, avctx->width);
852
            if (pass_row_size > 0) {
853
                for(y = 0; y < avctx->height; y++) {
854
                    if ((png_pass_ymask[pass] << (y & 7)) & 0x80) {
855
                        ptr = p->data[0] + y * p->linesize[0];
856
                        if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
857
                            convert_from_rgb32(tmp_buf, ptr, avctx->width);
858
                            ptr1 = tmp_buf;
859
                        } else {
860
                            ptr1 = ptr;
861
                        }
862
                        png_get_interlaced_row(crow_buf + 1, pass_row_size,
863
                                               bits_per_pixel, pass,
864
                                               ptr1, avctx->width);
865
                        crow_buf[0] = PNG_FILTER_VALUE_NONE;
866
                        png_write_row(s, crow_buf, pass_row_size + 1);
867
                    }
868
                }
869
            }
870
        }
871
    } else {
872
        for(y = 0; y < avctx->height; y++) {
873
            ptr = p->data[0] + y * p->linesize[0];
874
            if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
875
                convert_from_rgb32(crow_buf + 1, ptr, avctx->width);
876
            else
877
                memcpy(crow_buf + 1, ptr, row_size);
878
            crow_buf[0] = PNG_FILTER_VALUE_NONE;
879
            png_write_row(s, crow_buf, row_size + 1);
880
        }
881
    }
882
    /* compress last bytes */
883
    for(;;) {
884
        ret = deflate(&s->zstream, Z_FINISH);
885
        if (ret == Z_OK || ret == Z_STREAM_END) {
886
            len = IOBUF_SIZE - s->zstream.avail_out;
887
            if (len > 0 && s->bytestream_end - s->bytestream > len + 100) {
888
                png_write_chunk(&s->bytestream, MKTAG('I', 'D', 'A', 'T'), s->buf, len);
889
            }
890
            s->zstream.avail_out = IOBUF_SIZE;
891
            s->zstream.next_out = s->buf;
892
            if (ret == Z_STREAM_END)
893
                break;
894
        } else {
895
            goto fail;
896
        }
897
    }
898
    png_write_chunk(&s->bytestream, MKTAG('I', 'E', 'N', 'D'), NULL, 0);
899

  
900
    ret = s->bytestream - s->bytestream_start;
901
 the_end:
902
    av_free(crow_buf);
903
    av_free(tmp_buf);
904
    deflateEnd(&s->zstream);
905
    return ret;
906
 fail:
907
    ret = -1;
908
    goto the_end;
909
}
910
#endif
911

  
912
#ifdef CONFIG_PNG_DECODER
913
AVCodec png_decoder = {
914
    "png",
915
    CODEC_TYPE_VIDEO,
916
    CODEC_ID_PNG,
917
    sizeof(PNGContext),
918
    common_init,
919
    NULL,
920
    NULL, //decode_end,
921
    decode_frame,
922
    0 /*CODEC_CAP_DR1*/ /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
923
    NULL
924
};
925
#endif
926

  
927
#ifdef CONFIG_PNG_ENCODER
928
AVCodec png_encoder = {
929
    "png",
930
    CODEC_TYPE_VIDEO,
931
    CODEC_ID_PNG,
932
    sizeof(PNGContext),
933
    common_init,
934
    encode_frame,
935
    NULL, //encode_end,
936
    .pix_fmts= (enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_PAL8, PIX_FMT_GRAY8, PIX_FMT_MONOBLACK, -1},
937
};
938
#endif // CONFIG_PNG_ENCODER
libavcodec/png.h
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
#ifndef AVCODEC_PNG_H
23
#define AVCODEC_PNG_H
24

  
25
#include <stdint.h>
26
#include <zlib.h>
27

  
28
#define PNG_COLOR_MASK_PALETTE    1
29
#define PNG_COLOR_MASK_COLOR      2
30
#define PNG_COLOR_MASK_ALPHA      4
31

  
32
#define PNG_COLOR_TYPE_GRAY 0
33
#define PNG_COLOR_TYPE_PALETTE  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
34
#define PNG_COLOR_TYPE_RGB        (PNG_COLOR_MASK_COLOR)
35
#define PNG_COLOR_TYPE_RGB_ALPHA  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
36
#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
37

  
38
#define PNG_FILTER_VALUE_NONE  0
39
#define PNG_FILTER_VALUE_SUB   1
40
#define PNG_FILTER_VALUE_UP    2
41
#define PNG_FILTER_VALUE_AVG   3
42
#define PNG_FILTER_VALUE_PAETH 4
43

  
44
#define PNG_IHDR      0x0001
45
#define PNG_IDAT      0x0002
46
#define PNG_ALLIMAGE  0x0004
47
#define PNG_PLTE      0x0008
48

  
49
#define NB_PASSES 7
50

  
51
#define IOBUF_SIZE 4096
52

  
53
typedef struct PNGContext {
54
    uint8_t *bytestream;
55
    uint8_t *bytestream_start;
56
    uint8_t *bytestream_end;
57
    AVFrame picture;
58

  
59
    int state;
60
    int width, height;
61
    int bit_depth;
62
    int color_type;
63
    int compression_type;
64
    int interlace_type;
65
    int filter_type;
66
    int channels;
67
    int bits_per_pixel;
68
    int bpp;
69

  
70
    uint8_t *image_buf;
71
    int image_linesize;
72
    uint32_t palette[256];
73
    uint8_t *crow_buf;
74
    uint8_t *last_row;
75
    uint8_t *tmp_row;
76
    int pass;
77
    int crow_size; /* compressed row size (include filter type) */
78
    int row_size; /* decompressed row size */
79
    int pass_row_size; /* decompress row size of the current pass */
80
    int y;
81
    z_stream zstream;
82
    uint8_t buf[IOBUF_SIZE];
83
} PNGContext;
84

  
85
extern const uint8_t ff_pngsig[8];
86

  
87
/* Mask to determine which y pixels are valid in a pass */
88
extern const uint8_t ff_png_pass_ymask[NB_PASSES];
89

  
90
/* minimum x value */
91
extern const uint8_t ff_png_pass_xmin[NB_PASSES];
92

  
93
/* x shift to get row width */
94
extern const uint8_t ff_png_pass_xshift[NB_PASSES];
95

  
96
/* Mask to determine which pixels are valid in a pass */
97
extern const uint8_t ff_png_pass_mask[NB_PASSES];
98

  
99
extern void *ff_png_zalloc(void *opaque, unsigned int items,
100
                           unsigned int size);
101

  
102
extern void ff_png_zfree(void *opaque, void *ptr);
103

  
104
extern int ff_png_get_nb_channels(int color_type);
105

  
106
/* compute the row size of an interleaved pass */
107
extern int ff_png_pass_row_size(int pass, int bits_per_pixel, int width);
108

  
109
extern int ff_png_common_init(AVCodecContext *avctx);
110

  
111
#endif
libavcodec/pngdec.c
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

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

  
29
#include <zlib.h>
30

  
31
//#define DEBUG
32

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

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

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

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

  
101
/* XXX: optimize */
102
/* NOTE: 'dst' can be equal to 'last' */
103
static void png_filter_row(uint8_t *dst, int filter_type,
104
                           uint8_t *src, uint8_t *last, int size, int bpp)
105
{
106
    int i, p;
107

  
108
    switch(filter_type) {
109
    case PNG_FILTER_VALUE_NONE:
110
        memcpy(dst, src, size);
111
        break;
112
    case PNG_FILTER_VALUE_SUB:
113
        for(i = 0; i < bpp; i++) {
114
            dst[i] = src[i];
115
        }
116
        for(i = bpp; i < size; i++) {
117
            p = dst[i - bpp];
118
            dst[i] = p + src[i];
119
        }
120
        break;
121
    case PNG_FILTER_VALUE_UP:
122
        for(i = 0; i < size; i++) {
123
            p = last[i];
124
            dst[i] = p + src[i];
125
        }
126
        break;
127
    case PNG_FILTER_VALUE_AVG:
128
        for(i = 0; i < bpp; i++) {
129
            p = (last[i] >> 1);
130
            dst[i] = p + src[i];
131
        }
132
        for(i = bpp; i < size; i++) {
133
            p = ((dst[i - bpp] + last[i]) >> 1);
134
            dst[i] = p + src[i];
135
        }
136
        break;
137
    case PNG_FILTER_VALUE_PAETH:
138
        for(i = 0; i < bpp; i++) {
139
            p = last[i];
140
            dst[i] = p + src[i];
141
        }
142
        for(i = bpp; i < size; i++) {
143
            int a, b, c, pa, pb, pc;
144

  
145
            a = dst[i - bpp];
146
            b = last[i];
147
            c = last[i - bpp];
148

  
149
            p = b - c;
150
            pc = a - c;
151

  
152
            pa = abs(p);
153
            pb = abs(pc);
154
            pc = abs(p + pc);
155

  
156
            if (pa <= pb && pa <= pc)
157
                p = a;
158
            else if (pb <= pc)
159
                p = b;
160
            else
161
                p = c;
162
            dst[i] = p + src[i];
163
        }
164
        break;
165
    }
166
}
167

  
168
static void convert_to_rgb32(uint8_t *dst, const uint8_t *src, int width)
169
{
170
    int j;
171
    unsigned int r, g, b, a;
172

  
173
    for(j = 0;j < width; j++) {
174
        r = src[0];
175
        g = src[1];
176
        b = src[2];
177
        a = src[3];
178
        *(uint32_t *)dst = (a << 24) | (r << 16) | (g << 8) | b;
179
        dst += 4;
180
        src += 4;
181
    }
182
}
183

  
184
/* process exactly one decompressed row */
185
static void png_handle_row(PNGContext *s)
186
{
187
    uint8_t *ptr, *last_row;
188
    int got_line;
189

  
190
    if (!s->interlace_type) {
191
        ptr = s->image_buf + s->image_linesize * s->y;
192
        /* need to swap bytes correctly for RGB_ALPHA */
193
        if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
194
            png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
195
                           s->last_row, s->row_size, s->bpp);
196
            memcpy(s->last_row, s->tmp_row, s->row_size);
197
            convert_to_rgb32(ptr, s->tmp_row, s->width);
198
        } else {
199
            /* in normal case, we avoid one copy */
200
            if (s->y == 0)
201
                last_row = s->last_row;
202
            else
203
                last_row = ptr - s->image_linesize;
204

  
205
            png_filter_row(ptr, s->crow_buf[0], s->crow_buf + 1,
206
                           last_row, s->row_size, s->bpp);
207
        }
208
        s->y++;
209
        if (s->y == s->height) {
210
            s->state |= PNG_ALLIMAGE;
211
        }
212
    } else {
213
        got_line = 0;
214
        for(;;) {
215
            ptr = s->image_buf + s->image_linesize * s->y;
216
            if ((ff_png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) {
217
                /* if we already read one row, it is time to stop to
218
                   wait for the next one */
219
                if (got_line)
220
                    break;
221
                png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
222
                               s->last_row, s->pass_row_size, s->bpp);
223
                memcpy(s->last_row, s->tmp_row, s->pass_row_size);
224
                got_line = 1;
225
            }
226
            if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) {
227
                /* NOTE: RGB32 is handled directly in png_put_interlaced_row */
228
                png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass,
229
                                       s->color_type, s->last_row);
230
            }
231
            s->y++;
232
            if (s->y == s->height) {
233
                for(;;) {
234
                    if (s->pass == NB_PASSES - 1) {
235
                        s->state |= PNG_ALLIMAGE;
236
                        goto the_end;
237
                    } else {
238
                        s->pass++;
239
                        s->y = 0;
240
                        s->pass_row_size = ff_png_pass_row_size(s->pass,
241
                                                             s->bits_per_pixel,
242
                                                             s->width);
243
                        s->crow_size = s->pass_row_size + 1;
244
                        if (s->pass_row_size != 0)
245
                            break;
246
                        /* skip pass if empty row */
247
                    }
248
                }
249
            }
250
        }
251
    the_end: ;
252
    }
253
}
254

  
255
static int png_decode_idat(PNGContext *s, int length)
256
{
257
    int ret;
258
    s->zstream.avail_in = length;
259
    s->zstream.next_in = s->bytestream;
260
    s->bytestream += length;
261

  
262
    if(s->bytestream > s->bytestream_end)
263
        return -1;
264

  
265
    /* decode one line if possible */
266
    while (s->zstream.avail_in > 0) {
267
        ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
268
        if (ret != Z_OK && ret != Z_STREAM_END) {
269
            return -1;
270
        }
271
        if (s->zstream.avail_out == 0) {
272
            if (!(s->state & PNG_ALLIMAGE)) {
273
                png_handle_row(s);
274
            }
275
            s->zstream.avail_out = s->crow_size;
276
            s->zstream.next_out = s->crow_buf;
277
        }
278
    }
279
    return 0;
280
}
281

  
282
static int decode_frame(AVCodecContext *avctx,
283
                        void *data, int *data_size,
284
                        uint8_t *buf, int buf_size)
285
{
286
    PNGContext * const s = avctx->priv_data;
287
    AVFrame *picture = data;
288
    AVFrame * const p= (AVFrame*)&s->picture;
289
    uint32_t tag, length;
290
    int ret, crc;
291

  
292
    s->bytestream_start=
293
    s->bytestream= buf;
294
    s->bytestream_end= buf + buf_size;
295

  
296
    /* check signature */
297
    if (memcmp(s->bytestream, ff_pngsig, 8) != 0)
298
        return -1;
299
    s->bytestream+= 8;
300
    s->y=
301
    s->state=0;
302
//    memset(s, 0, sizeof(PNGContext));
303
    /* init the zlib */
304
    s->zstream.zalloc = ff_png_zalloc;
305
    s->zstream.zfree = ff_png_zfree;
306
    s->zstream.opaque = NULL;
307
    ret = inflateInit(&s->zstream);
308
    if (ret != Z_OK)
309
        return -1;
310
    for(;;) {
311
        int tag32;
312
        if (s->bytestream >= s->bytestream_end)
313
            goto fail;
314
        length = bytestream_get_be32(&s->bytestream);
315
        if (length > 0x7fffffff)
316
            goto fail;
317
        tag32 = bytestream_get_be32(&s->bytestream);
318
        tag = bswap_32(tag32);
319
#ifdef DEBUG
320
        av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n",
321
               (tag & 0xff),
322
               ((tag >> 8) & 0xff),
323
               ((tag >> 16) & 0xff),
324
               ((tag >> 24) & 0xff), length);
325
#endif
326
        switch(tag) {
327
        case MKTAG('I', 'H', 'D', 'R'):
328
            if (length != 13)
329
                goto fail;
330
            s->width = bytestream_get_be32(&s->bytestream);
331
            s->height = bytestream_get_be32(&s->bytestream);
332
            if(avcodec_check_dimensions(avctx, s->width, s->height)){
333
                s->width= s->height= 0;
334
                goto fail;
335
            }
336
            s->bit_depth = *s->bytestream++;
337
            s->color_type = *s->bytestream++;
338
            s->compression_type = *s->bytestream++;
339
            s->filter_type = *s->bytestream++;
340
            s->interlace_type = *s->bytestream++;
341
            crc = bytestream_get_be32(&s->bytestream);
342
            s->state |= PNG_IHDR;
343
#ifdef DEBUG
344
            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",
345
                   s->width, s->height, s->bit_depth, s->color_type,
346
                   s->compression_type, s->filter_type, s->interlace_type);
347
#endif
348
            break;
349
        case MKTAG('I', 'D', 'A', 'T'):
350
            if (!(s->state & PNG_IHDR))
351
                goto fail;
352
            if (!(s->state & PNG_IDAT)) {
353
                /* init image info */
354
                avctx->width = s->width;
355
                avctx->height = s->height;
356

  
357
                s->channels = ff_png_get_nb_channels(s->color_type);
358
                s->bits_per_pixel = s->bit_depth * s->channels;
359
                s->bpp = (s->bits_per_pixel + 7) >> 3;
360
                s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3;
361

  
362
                if (s->bit_depth == 8 &&
363
                    s->color_type == PNG_COLOR_TYPE_RGB) {
364
                    avctx->pix_fmt = PIX_FMT_RGB24;
365
                } else if (s->bit_depth == 8 &&
366
                           s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
367
                    avctx->pix_fmt = PIX_FMT_RGB32;
368
                } else if (s->bit_depth == 8 &&
369
                           s->color_type == PNG_COLOR_TYPE_GRAY) {
370
                    avctx->pix_fmt = PIX_FMT_GRAY8;
371
                } else if (s->bit_depth == 16 &&
372
                           s->color_type == PNG_COLOR_TYPE_GRAY) {
373
                    avctx->pix_fmt = PIX_FMT_GRAY16BE;
374
                } else if (s->bit_depth == 1 &&
375
                           s->color_type == PNG_COLOR_TYPE_GRAY) {
376
                    avctx->pix_fmt = PIX_FMT_MONOBLACK;
377
                } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
378
                    avctx->pix_fmt = PIX_FMT_PAL8;
379
                } else {
380
                    goto fail;
381
                }
382
                if(p->data[0])
383
                    avctx->release_buffer(avctx, p);
384

  
385
                p->reference= 0;
386
                if(avctx->get_buffer(avctx, p) < 0){
387
                    av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
388
                    goto fail;
389
                }
390
                p->pict_type= FF_I_TYPE;
391
                p->key_frame= 1;
392
                p->interlaced_frame = !!s->interlace_type;
393

  
394
                /* compute the compressed row size */
395
                if (!s->interlace_type) {
396
                    s->crow_size = s->row_size + 1;
397
                } else {
398
                    s->pass = 0;
399
                    s->pass_row_size = ff_png_pass_row_size(s->pass,
400
                                                         s->bits_per_pixel,
401
                                                         s->width);
402
                    s->crow_size = s->pass_row_size + 1;
403
                }
404
#ifdef DEBUG
405
                av_log(avctx, AV_LOG_DEBUG, "row_size=%d crow_size =%d\n",
406
                       s->row_size, s->crow_size);
407
#endif
408
                s->image_buf = p->data[0];
409
                s->image_linesize = p->linesize[0];
410
                /* copy the palette if needed */
411
                if (s->color_type == PNG_COLOR_TYPE_PALETTE)
412
                    memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t));
413
                /* empty row is used if differencing to the first row */
414
                s->last_row = av_mallocz(s->row_size);
415
                if (!s->last_row)
416
                    goto fail;
417
                if (s->interlace_type ||
418
                    s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
419
                    s->tmp_row = av_malloc(s->row_size);
420
                    if (!s->tmp_row)
421
                        goto fail;
422
                }
423
                /* compressed row */
424
                s->crow_buf = av_malloc(s->row_size + 1);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff