/* * * Decode a frame * */ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) { CamtasiaContext * const c = avctx->priv_data; const unsigned char *encoded = buf; unsigned char *outptr; int zret; // Zlib return code int len = buf_size; if(c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); c->pic.reference = 1; c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; if(avctx->get_buffer(avctx, &c->pic) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } outptr = c->pic.data[0]; // Output image pointer zret = inflateReset(&(c->zstream)); if (zret != Z_OK) { av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); return -1; } c->zstream.next_in = encoded; c->zstream.avail_in = len; c->zstream.next_out = c->decomp_buf; c->zstream.avail_out = c->decomp_size; zret = inflate(&(c->zstream), Z_FINISH); // Z_DATA_ERROR means empty picture if ((zret != Z_OK) && (zret != Z_STREAM_END) && (zret != Z_DATA_ERROR)) { av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret); return -1; } if(zret != Z_DATA_ERROR) ff_msrle_decode(avctx, &c->pic, c->bpp, c->decomp_buf, c->zstream.avail_out); /* make the palette available on the way out */ if (c->avctx->pix_fmt == PIX_FMT_PAL8) { memcpy(c->pic.data[1], c->avctx->palctrl->palette, AVPALETTE_SIZE); if (c->avctx->palctrl->palette_changed) { c->pic.palette_has_changed = 1; c->avctx->palctrl->palette_changed = 0; } } *data_size = sizeof(AVFrame); *(AVFrame*)data = c->pic; /* always report that the buffer was completely consumed */ return buf_size; }
static int aasc_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AascContext *s = (AascContext *)avctx->priv_data; int compr, i, stride; s->frame.reference = 3; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if (avctx->reget_buffer(avctx, &s->frame)) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return -1; } compr = AV_RL32(buf); buf += 4; buf_size -= 4; switch(compr){ case 0: stride = (avctx->width * 3 + 3) & ~3; for(i = avctx->height - 1; i >= 0; i--){ if(avctx->width*3 > buf_size){ av_log(avctx, AV_LOG_ERROR, "Next line is beyond buffer bounds\n"); break; } memcpy(s->frame.data[0] + i*s->frame.linesize[0], buf, avctx->width*3); buf += stride; buf_size -= stride; } break; case 1: ff_msrle_decode(avctx, (AVPicture*)&s->frame, 8, buf - 4, buf_size + 4); break; default: av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr); return -1; } *data_size = sizeof(AVFrame); *(AVFrame*)data = s->frame; /* report that the buffer was completely consumed */ return buf_size; }
static int aasc_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AascContext *s = avctx->priv_data; int compr, i, stride, ret; if (buf_size < 4) return AVERROR_INVALIDDATA; if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } compr = AV_RL32(buf); buf += 4; buf_size -= 4; switch (compr) { case 0: stride = (avctx->width * 3 + 3) & ~3; if (buf_size < stride * avctx->height) return AVERROR_INVALIDDATA; for (i = avctx->height - 1; i >= 0; i--) { memcpy(s->frame->data[0] + i * s->frame->linesize[0], buf, avctx->width * 3); buf += stride; } break; case 1: bytestream2_init(&s->gb, buf, buf_size); ff_msrle_decode(avctx, (AVPicture*)s->frame, 8, &s->gb); break; default: av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr); return AVERROR_INVALIDDATA; } *got_frame = 1; if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; /* report that the buffer was completely consumed */ return avpkt->size; }
static int aasc_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AascContext *s = avctx->priv_data; int compr, i, stride, ret; s->frame.reference = 1; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } compr = AV_RL32(buf); buf += 4; buf_size -= 4; switch (compr) { case 0: stride = (avctx->width * 3 + 3) & ~3; for (i = avctx->height - 1; i >= 0; i--) { memcpy(s->frame.data[0] + i * s->frame.linesize[0], buf, avctx->width * 3); buf += stride; } break; case 1: bytestream2_init(&s->gb, buf - 4, buf_size + 4); ff_msrle_decode(avctx, (AVPicture*)&s->frame, 8, &s->gb); break; default: av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr); return AVERROR_INVALIDDATA; } *got_frame = 1; *(AVFrame*)data = s->frame; /* report that the buffer was completely consumed */ return buf_size; }
static int aasc_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AascContext *s = avctx->priv_data; int compr, i, stride, psize, ret; if (buf_size < 4) { av_log(avctx, AV_LOG_ERROR, "frame too short\n"); return AVERROR_INVALIDDATA; } if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; compr = AV_RL32(buf); buf += 4; buf_size -= 4; psize = avctx->bits_per_coded_sample / 8; switch (avctx->codec_tag) { case MKTAG('A', 'A', 'S', '4'): bytestream2_init(&s->gb, buf - 4, buf_size + 4); ff_msrle_decode(avctx, (AVPicture*)s->frame, 8, &s->gb); break; case MKTAG('A', 'A', 'S', 'C'): switch (compr) { case 0: stride = (avctx->width * psize + psize) & ~psize; if (buf_size < stride * avctx->height) return AVERROR_INVALIDDATA; for (i = avctx->height - 1; i >= 0; i--) { memcpy(s->frame->data[0] + i * s->frame->linesize[0], buf, avctx->width * psize); buf += stride; buf_size -= stride; } break; case 1: bytestream2_init(&s->gb, buf, buf_size); ff_msrle_decode(avctx, (AVPicture*)s->frame, 8, &s->gb); break; default: av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr); return AVERROR_INVALIDDATA; } break; default: av_log(avctx, AV_LOG_ERROR, "Unknown FourCC: %X\n", avctx->codec_tag); return -1; } if (avctx->pix_fmt == AV_PIX_FMT_PAL8) memcpy(s->frame->data[1], s->palette, s->palette_size); *got_frame = 1; if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; /* report that the buffer was completely consumed */ return avpkt->size; }
static int aasc_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AascContext *s = avctx->priv_data; int compr, i, stride, psize, ret; if (buf_size < 4) { av_log(avctx, AV_LOG_ERROR, "frame too short\n"); return AVERROR_INVALIDDATA; } s->frame.reference = 3; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } compr = AV_RL32(buf); buf += 4; buf_size -= 4; psize = avctx->bits_per_coded_sample / 8; switch (avctx->codec_tag) { case MKTAG('A', 'A', 'S', '4'): bytestream2_init(&s->gb, buf - 4, buf_size + 4); ff_msrle_decode(avctx, (AVPicture*)&s->frame, 8, &s->gb); break; case MKTAG('A', 'A', 'S', 'C'): switch (compr) { case 0: stride = (avctx->width * psize + psize) & ~psize; for (i = avctx->height - 1; i >= 0; i--) { if (avctx->width * psize > buf_size) { av_log(avctx, AV_LOG_ERROR, "Next line is beyond buffer bounds\n"); break; } memcpy(s->frame.data[0] + i*s->frame.linesize[0], buf, avctx->width * psize); buf += stride; buf_size -= stride; } break; case 1: bytestream2_init(&s->gb, buf, buf_size); ff_msrle_decode(avctx, (AVPicture*)&s->frame, 8, &s->gb); break; default: av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr); return AVERROR_INVALIDDATA; } break; default: av_log(avctx, AV_LOG_ERROR, "Unknown FourCC: %X\n", avctx->codec_tag); return -1; } if (avctx->pix_fmt == AV_PIX_FMT_PAL8) memcpy(s->frame.data[1], s->palette, s->palette_size); *got_frame = 1; *(AVFrame*)data = s->frame; /* report that the buffer was completely consumed */ return buf_size; }