ThreadFrame last_picture;
ThreadFrame picture;
- uint8_t* extra_data;
- int extra_data_size;
-
int state;
int width, height;
int cur_w, cur_h;
av_bprint_init(bp, 0, -1);
while (zstream.avail_in > 0) {
- av_bprint_get_buffer(bp, 1, &buf, &buf_size);
- if (!buf_size) {
+ av_bprint_get_buffer(bp, 2, &buf, &buf_size);
+ if (buf_size < 2) {
ret = AVERROR(ENOMEM);
goto fail;
}
zstream.next_out = buf;
- zstream.avail_out = buf_size;
+ zstream.avail_out = buf_size - 1;
ret = inflate(&zstream, Z_PARTIAL_FLUSH);
if (ret != Z_OK && ret != Z_STREAM_END) {
ret = AVERROR_EXTERNAL;
return AVERROR_INVALIDDATA;
}
- if (sequence_number == 0 && dispose_op == APNG_DISPOSE_OP_PREVIOUS) {
+ if ((sequence_number == 0 || !s->previous_picture.f->data[0]) &&
+ dispose_op == APNG_DISPOSE_OP_PREVIOUS) {
// No previous frame to revert to for the first frame
// Spec says to just treat it as a APNG_DISPOSE_OP_BACKGROUND
dispose_op = APNG_DISPOSE_OP_BACKGROUND;
p = s->picture.f;
if (!(s->state & PNG_IHDR)) {
- int side_data_size = 0;
- uint8_t *side_data = NULL;
- if (avpkt)
- side_data = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &side_data_size);
-
- if (side_data_size) {
- av_freep(&s->extra_data);
- s->extra_data = av_mallocz(side_data_size + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!s->extra_data)
- return AVERROR(ENOMEM);
- s->extra_data_size = side_data_size;
- memcpy(s->extra_data, side_data, s->extra_data_size);
- }
-
- if (!s->extra_data_size)
+ if (!avctx->extradata_size)
return AVERROR_INVALIDDATA;
/* only init fields, there is no zlib use in extradata */
s->zstream.zalloc = ff_png_zalloc;
s->zstream.zfree = ff_png_zfree;
- bytestream2_init(&s->gb, s->extra_data, s->extra_data_size);
+ bytestream2_init(&s->gb, avctx->extradata, avctx->extradata_size);
if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0)
goto end;
}
s->last_row_size = 0;
av_freep(&s->tmp_row);
s->tmp_row_size = 0;
- av_freep(&s->extra_data);
- s->extra_data_size = 0;
return 0;
}