[FFmpeg-devel] [PATCH 3/3] iff: DEEP RLE 32-bit decoder
Paul B Mahol
onemda at gmail.com
Sun Nov 18 12:45:33 CET 2012
On 11/18/12, Peter Ross <pross at xvid.org> wrote:
> Fixes ticket #1046.
> ---
> libavcodec/iff.c | 51
> +++++++++++++++++++++++++++++++++++++++++++++++++++
> libavformat/iff.c | 2 +-
> 2 files changed, 52 insertions(+), 1 deletion(-)
>
> diff --git a/libavcodec/iff.c b/libavcodec/iff.c
> index 9184015..dfcca09 100644
> --- a/libavcodec/iff.c
> +++ b/libavcodec/iff.c
> @@ -598,6 +598,49 @@ static int decode_frame_ilbm(AVCodecContext *avctx,
> return buf_size;
> }
>
> +/**
> + * Decode DEEP RLE 32-bit buffer
> + */
This is not doxygen comment (if it is you would need to expand it with
more info).
> +static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int
> src_size, int width, int height, int linesize)
> +{
> + const uint8_t *src_end = src + src_size;
> + int x = 0, y = 0, i;
> + while (src + 5 <= src_end) {
> + int opcode;
> + opcode = *(int8_t *)src++;
> + if (opcode >= 0) {
> + int size = opcode + 1;
> + for (i = 0; i < size; i++) {
> + int length = FFMIN(size - i, width);
> + memcpy(dst + y*linesize + x * 4, src, length * 4);
> + src += length * 4;
> + x += length;
> + i += length;
> + if (x >= width) {
> + x = 0;
> + y += 1;
> + if (y >= height)
> + return;
> + }
> + }
> + } else {
> + int size = -opcode + 1;
> + uint32_t pixel = AV_RL32(src);
> + for (i = 0; i < size; i++) {
> + *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
> + x += 1;
> + if (x >= width) {
> + x = 0;
> + y += 1;
> + if (y >= height)
> + return;
> + }
> + }
> + src += 4;
> + }
> + }
> +}
> +
> static int decode_frame_byterun1(AVCodecContext *avctx,
> void *data, int *data_size,
> AVPacket *avpkt)
> @@ -683,6 +726,14 @@ static int decode_frame_byterun1(AVCodecContext
> *avctx,
> av_log_ask_for_sample(avctx, "unsupported bpp\n");
> return AVERROR_INVALIDDATA;
> }
> + } else if (avctx->codec_tag == MKTAG('D','E','E','P')) { // IFF-DEEP
> + const AVPixFmtDescriptor *desc =
> av_pix_fmt_desc_get(avctx->pix_fmt);
> + if (av_get_bits_per_pixel(desc) == 32)
> + decode_deep_rle32(s->frame.data[0], buf, buf_size,
> avctx->width, avctx->height, s->frame.linesize[0]);
> + else {
> + av_log_ask_for_sample(avctx, "unsupported bpp\n");
> + return AVERROR_INVALIDDATA;
> + }
> }
>
> *data_size = sizeof(AVFrame);
> diff --git a/libavformat/iff.c b/libavformat/iff.c
> index 53e104d..b748f49 100644
> --- a/libavformat/iff.c
> +++ b/libavformat/iff.c
> @@ -272,7 +272,7 @@ static int iff_read_header(AVFormatContext *s)
> st->codec->width = avio_rb16(pb);
> st->codec->height = avio_rb16(pb);
> iff->bitmap_compression = avio_rb16(pb);
> - if (iff->bitmap_compression != 0) {
> + if (iff->bitmap_compression > 1) {
> av_log(s, AV_LOG_ERROR,
> "compression %i not supported\n",
> iff->bitmap_compression);
> return AVERROR_PATCHWELCOME;
> --
> 1.7.10.4
>
> -- Peter
> (A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B)
>
ok if overread and writing out of array do not happen for zuffed files.
More information about the ffmpeg-devel
mailing list