[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