Mostly (there are some artefacts) fixes samples in http://samples.mplayerhq.hu/game-formats/la-san/fullthrottle-demo/
Signed-off-by: Reimar Döffinger <reimar.doeffin...@gmx.de> --- libavcodec/sanm.c | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index ce3c868..6aeaa2c 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -624,6 +624,8 @@ static inline void codec37_mv(uint8_t *dst, const uint8_t *src, static int old_codec37(SANMVideoContext *ctx, int top, int left, int width, int height) { + GetByteContext gb_rle; + GetByteContext *gb = &ctx->gb; int stride = ctx->pitch; int i, j, k, t; uint8_t *dst, *prev; @@ -671,6 +673,16 @@ static int old_codec37(SANMVideoContext *ctx, int top, memset(ctx->frm1, 0, ctx->frm1_size); memset(ctx->frm2, 0, ctx->frm2_size); break; + case 1: + av_fast_malloc(&ctx->rle_buf, &ctx->rle_buf_size, decoded_size); + if (!ctx->rle_buf) { + av_log(ctx->avctx, AV_LOG_ERROR, "RLE buffer allocation failed.\n"); + return AVERROR(ENOMEM); + } + if (rle_decode(ctx, ctx->rle_buf, decoded_size)) + return AVERROR_INVALIDDATA; + bytestream2_init(&gb_rle, ctx->rle_buf, decoded_size); + gb = &gb_rle; case 3: case 4: if (flags & 4) { @@ -682,34 +694,34 @@ static int old_codec37(SANMVideoContext *ctx, int top, copy_block4(dst + i, prev + i, stride, stride, 4); continue; } - if (bytestream2_get_bytes_left(&ctx->gb) < 1) + if (bytestream2_get_bytes_left(gb) < 1) return AVERROR_INVALIDDATA; - code = bytestream2_get_byteu(&ctx->gb); + code = bytestream2_get_byteu(gb); switch (code) { case 0xFF: - if (bytestream2_get_bytes_left(&ctx->gb) < 16) + if (bytestream2_get_bytes_left(gb) < 16) return AVERROR_INVALIDDATA; for (k = 0; k < 4; k++) - bytestream2_get_bufferu(&ctx->gb, dst + i + k * stride, 4); + bytestream2_get_bufferu(gb, dst + i + k * stride, 4); break; case 0xFE: - if (bytestream2_get_bytes_left(&ctx->gb) < 4) + if (bytestream2_get_bytes_left(gb) < 4) return AVERROR_INVALIDDATA; for (k = 0; k < 4; k++) - memset(dst + i + k * stride, bytestream2_get_byteu(&ctx->gb), 4); + memset(dst + i + k * stride, bytestream2_get_byteu(gb), 4); break; case 0xFD: - if (bytestream2_get_bytes_left(&ctx->gb) < 1) + if (bytestream2_get_bytes_left(gb) < 1) return AVERROR_INVALIDDATA; - t = bytestream2_get_byteu(&ctx->gb); + t = bytestream2_get_byteu(gb); for (k = 0; k < 4; k++) memset(dst + i + k * stride, t, 4); break; default: if (compr == 4 && !code) { - if (bytestream2_get_bytes_left(&ctx->gb) < 1) + if (bytestream2_get_bytes_left(gb) < 1) return AVERROR_INVALIDDATA; - skip_run = bytestream2_get_byteu(&ctx->gb) + 1; + skip_run = bytestream2_get_byteu(gb) + 1; i -= 4; } else { int mx, my; @@ -733,16 +745,16 @@ static int old_codec37(SANMVideoContext *ctx, int top, copy_block4(dst + i, prev + i, stride, stride, 4); continue; } - code = bytestream2_get_byte(&ctx->gb); + code = bytestream2_get_byte(gb); if (code == 0xFF) { - if (bytestream2_get_bytes_left(&ctx->gb) < 16) + if (bytestream2_get_bytes_left(gb) < 16) return AVERROR_INVALIDDATA; for (k = 0; k < 4; k++) - bytestream2_get_bufferu(&ctx->gb, dst + i + k * stride, 4); + bytestream2_get_bufferu(gb, dst + i + k * stride, 4); } else if (compr == 4 && !code) { - if (bytestream2_get_bytes_left(&ctx->gb) < 1) + if (bytestream2_get_bytes_left(gb) < 1) return AVERROR_INVALIDDATA; - skip_run = bytestream2_get_byteu(&ctx->gb) + 1; + skip_run = bytestream2_get_byteu(gb) + 1; i -= 4; } else { int mx, my; -- 2.7.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel