Revision 6d4c49a2 libavcodec/pngdec.c

View differences:

libavcodec/pngdec.c
18 18
 * License along with FFmpeg; if not, write to the Free Software
19 19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 20
 */
21

  
22
//#define DEBUG
23

  
21 24
#include "libavutil/imgutils.h"
22 25
#include "avcodec.h"
23 26
#include "bytestream.h"
24 27
#include "png.h"
25
#include "dsputil.h"
26 28

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

  
31 33
#include <zlib.h>
32 34

  
33
//#define DEBUG
34

  
35
typedef struct PNGDecContext {
36
    DSPContext dsp;
37

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

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

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

  
69 35
/* Mask to determine which y pixels can be written in a pass */
70 36
static const uint8_t png_pass_dsp_ymask[NB_PASSES] = {
71 37
    0xff, 0xff, 0x0f, 0xcc, 0x33, 0xff, 0x55,
......
134 100
    }
135 101
}
136 102

  
137
void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp)
103
// 0x7f7f7f7f or 0x7f7f7f7f7f7f7f7f or whatever, depending on the cpu's native arithmetic size
104
#define pb_7f (~0UL/255 * 0x7f)
105
#define pb_80 (~0UL/255 * 0x80)
106

  
107
static void add_bytes_l2_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w)
108
{
109
    long i;
110
    for(i=0; i<=w-sizeof(long); i+=sizeof(long)){
111
        long a = *(long*)(src1+i);
112
        long b = *(long*)(src2+i);
113
        *(long*)(dst+i) = ((a&pb_7f) + (b&pb_7f)) ^ ((a^b)&pb_80);
114
    }
115
    for(; i<w; i++)
116
        dst[i] = src1[i]+src2[i];
117
}
118

  
119
static void add_paeth_prediction_c(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp)
138 120
{
139 121
    int i;
140 122
    for(i = 0; i < w; i++) {
......
191 173
    }
192 174

  
193 175
/* NOTE: 'dst' can be equal to 'last' */
194
static void png_filter_row(DSPContext *dsp, uint8_t *dst, int filter_type,
176
static void png_filter_row(PNGDecContext *s, uint8_t *dst, int filter_type,
195 177
                           uint8_t *src, uint8_t *last, int size, int bpp)
196 178
{
197 179
    int i, p, r, g, b, a;
......
217 199
        }
218 200
        break;
219 201
    case PNG_FILTER_VALUE_UP:
220
        dsp->add_bytes_l2(dst, src, last, size);
202
        s->add_bytes_l2(dst, src, last, size);
221 203
        break;
222 204
    case PNG_FILTER_VALUE_AVG:
223 205
        for(i = 0; i < bpp; i++) {
......
235 217
        if(bpp > 1 && size > 4) {
236 218
            // would write off the end of the array if we let it process the last pixel with bpp=3
237 219
            int w = bpp==4 ? size : size-3;
238
            dsp->add_png_paeth_prediction(dst+i, src+i, last+i, w-i, bpp);
220
            s->add_paeth_prediction(dst+i, src+i, last+i, w-i, bpp);
239 221
            i = w;
240 222
        }
241
        ff_add_png_paeth_prediction(dst+i, src+i, last+i, size-i, bpp);
223
        add_paeth_prediction_c(dst+i, src+i, last+i, size-i, bpp);
242 224
        break;
243 225
    }
244 226
}
......
291 273
        ptr = s->image_buf + s->image_linesize * s->y;
292 274
        /* need to swap bytes correctly for RGB_ALPHA */
293 275
        if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
294
            png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
276
            png_filter_row(s, s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
295 277
                           s->last_row, s->row_size, s->bpp);
296 278
            convert_to_rgb32(ptr, s->tmp_row, s->width, s->filter_type == PNG_FILTER_TYPE_LOCO);
297 279
            FFSWAP(uint8_t*, s->last_row, s->tmp_row);
......
302 284
            else
303 285
                last_row = ptr - s->image_linesize;
304 286

  
305
            png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1,
287
            png_filter_row(s, ptr, s->crow_buf[0], s->crow_buf + 1,
306 288
                           last_row, s->row_size, s->bpp);
307 289
        }
308 290
        /* loco lags by 1 row so that it doesn't interfere with top prediction */
......
325 307
                   wait for the next one */
326 308
                if (got_line)
327 309
                    break;
328
                png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
310
                png_filter_row(s, s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
329 311
                               s->last_row, s->pass_row_size, s->bpp);
330 312
                FFSWAP(uint8_t*, s->last_row, s->tmp_row);
331 313
                got_line = 1;
......
633 615
    goto the_end;
634 616
}
635 617

  
636
static av_cold int png_dec_init(AVCodecContext *avctx){
618
static av_cold int png_dec_init(AVCodecContext *avctx)
619
{
637 620
    PNGDecContext *s = avctx->priv_data;
638 621

  
639 622
    s->current_picture = &s->picture1;
640 623
    s->last_picture = &s->picture2;
641 624
    avcodec_get_frame_defaults(&s->picture1);
642 625
    avcodec_get_frame_defaults(&s->picture2);
643
    dsputil_init(&s->dsp, avctx);
626

  
627
    ff_png_init_mmx(s);
628

  
629
    if (!s->add_paeth_prediction)
630
        s->add_paeth_prediction = add_paeth_prediction_c;
631
    if (!s->add_bytes_l2)
632
        s->add_bytes_l2 = add_bytes_l2_c;
644 633

  
645 634
    return 0;
646 635
}

Also available in: Unified diff