[FFmpeg-devel] [PATCH] sanm.c: implement codec 37 compression 1.
Reimar Döffinger
Reimar.Doeffinger at gmx.de
Sat Apr 2 12:56:11 CEST 2016
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.Doeffinger at 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
More information about the ffmpeg-devel
mailing list