[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