Revision 8b46d75e libavformat/png.c

View differences:

libavformat/png.c
63 63
    uint32_t palette[256];
64 64
    uint8_t *crow_buf;
65 65
    uint8_t *empty_row;
66
    uint8_t *tmp_row;
66 67
    int crow_size; /* compressed row size (include filter type) */
67 68
    int row_size; /* decompressed row size */
68 69
    int y;
......
91 92
}
92 93

  
93 94
/* XXX: optimize */
95
/* NOTE: 'dst' can be equal to 'last' */
94 96
static void png_filter_row(uint8_t *dst, int filter_type, 
95 97
                           uint8_t *src, uint8_t *last, int size, int bpp)
96 98
{
......
159 161
static void png_handle_row(PNGDecodeState *s)
160 162
{
161 163
    uint8_t *ptr, *last_row;
164

  
162 165
    ptr = s->image_buf + s->image_linesize * s->y;
163
    if (s->y == 0)
164
        last_row = s->empty_row;
165
    else
166
        last_row = ptr - s->image_linesize;
167 166

  
168
    png_filter_row(ptr, s->crow_buf[0], s->crow_buf + 1, 
169
                   last_row, s->row_size, s->bpp);
167
    /* need to swap bytes correctly for RGB_ALPHA */
168
    if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
169
        int j, w;
170
        unsigned int r, g, b, a;
171
        const uint8_t *src;
172

  
173
        png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1, 
174
                       s->empty_row, s->row_size, s->bpp);
175
        memcpy(s->empty_row, s->tmp_row, s->row_size);
176

  
177
        src = s->tmp_row;
178
        w = s->width;
179
        for(j = 0;j < w; j++) {
180
            r = src[0];
181
            g = src[1];
182
            b = src[2];
183
            a = src[3];
184
            *(uint32_t *)ptr = (a << 24) | (r << 16) | (g << 8) | b;
185
            ptr += 4;
186
            src += 4;
187
        }
188
    } else {
189
        /* in normal case, we avoid one copy */
190

  
191
        if (s->y == 0)
192
            last_row = s->empty_row;
193
        else
194
            last_row = ptr - s->image_linesize;
195
        
196
        png_filter_row(ptr, s->crow_buf[0], s->crow_buf + 1, 
197
                       last_row, s->row_size, s->bpp);
198
    }
170 199
}
171 200

  
172 201
static int png_decode_idat(PNGDecodeState *s, ByteIOContext *f, int length)
......
283 312
                    info->pix_fmt = PIX_FMT_RGB24;
284 313
                    s->row_size = s->width * 3;
285 314
                } else if (s->bit_depth == 8 && 
315
                           s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
316
                    info->pix_fmt = PIX_FMT_RGBA32;
317
                    s->row_size = s->width * 4;
318
                } else if (s->bit_depth == 8 && 
286 319
                           s->color_type == PNG_COLOR_TYPE_GRAY) {
287 320
                    info->pix_fmt = PIX_FMT_GRAY8;
288 321
                    s->row_size = s->width;
......
292 325
                    s->row_size = (s->width + 7) >> 3;
293 326
                } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
294 327
                    info->pix_fmt = PIX_FMT_PAL8;
295
                    s->row_size = s->width;;
328
                    s->row_size = s->width;
296 329
                } else {
297 330
                    goto fail;
298 331
                }
......
319 352
                s->empty_row = av_mallocz(s->row_size);
320 353
                if (!s->empty_row)
321 354
                    goto fail;
355
                if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
356
                    s->tmp_row = av_malloc(s->row_size);
357
                    if (!s->tmp_row)
358
                        goto fail;
359
                }
322 360
                /* compressed row */
323 361
                s->crow_buf = av_malloc(s->crow_size);
324 362
                if (!s->crow_buf)
......
386 424
 the_end:
387 425
    inflateEnd(&s->zstream);
388 426
    av_free(s->crow_buf);
427
    av_free(s->empty_row);
428
    av_free(s->tmp_row);
389 429
    return ret;
390 430
 fail:
391 431
    ret = -1;
......
431 471
    z_stream zstream;
432 472
    
433 473
    switch(info->pix_fmt) {
474
    case PIX_FMT_RGBA32:
475
        bit_depth = 8;
476
        color_type = PNG_COLOR_TYPE_RGB_ALPHA;
477
        row_size = info->width * 4;
478
        break;
434 479
    case PIX_FMT_RGB24:
435 480
        bit_depth = 8;
436 481
        color_type = PNG_COLOR_TYPE_RGB;
......
512 557
    for(y = 0;y < info->height; y++) {
513 558
        /* XXX: do filtering */
514 559
        ptr = info->pict.data[0] + y * info->pict.linesize[0];
515
        memcpy(crow_buf + 1, ptr, row_size);
560
        if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
561
            uint8_t *d;
562
            int j, w;
563
            unsigned int v;
564

  
565
            w = info->width;
566
            d = crow_buf + 1;
567
            for(j = 0; j < w; j++) {
568
                v = ((uint32_t *)ptr)[j];
569
                d[0] = v >> 16;
570
                d[1] = v >> 8;
571
                d[2] = v;
572
                d[3] = v >> 24;
573
                d += 4;
574
            }
575
        } else {
576
            memcpy(crow_buf + 1, ptr, row_size);
577
        }
516 578
        crow_buf[0] = PNG_FILTER_VALUE_NONE;
517 579
        zstream.avail_in = row_size + 1;
518 580
        zstream.next_in = crow_buf;
......
561 623
    "png",
562 624
    png_probe,
563 625
    png_read,
564
    (1 << PIX_FMT_RGB24) | (1 << PIX_FMT_GRAY8) | (1 << PIX_FMT_MONOBLACK) | (1 << PIX_FMT_PAL8),
626
    (1 << PIX_FMT_RGBA32) | (1 << PIX_FMT_RGB24) | (1 << PIX_FMT_GRAY8) | 
627
    (1 << PIX_FMT_MONOBLACK) | (1 << PIX_FMT_PAL8),
565 628
    png_write,
566 629
};
567 630
#endif

Also available in: Unified diff