The branch, master has been updated
       via  0226b6fb2c0855eca417feb0a4e3bdf1f1193332 (commit)
      from  8426622bb9584ec4fc32215f006a91e7ddc480cc (commit)


- Log -----------------------------------------------------------------
commit 0226b6fb2c0855eca417feb0a4e3bdf1f1193332
Author:     Manuel Lauss <manuel.la...@gmail.com>
AuthorDate: Thu Aug 14 00:21:09 2025 +0200
Commit:     Manuel Lauss <manuel.la...@gmail.com>
CommitDate: Mon Aug 18 09:11:09 2025 +0000

    avcodec/sanm: bl16: fix artifacts in larger videos
    
    The DOS/Windows decoder precomputes a table of linear offsets of
    all motion vectors given the current image width.
    For larger widths (>=762), the pairs starting at indices 1 and 254
    of motion_vectors[] will overflow the int16_t, changing the sign.
    
    Playing back the 800x600 "jonesopn_8.snm" video of "Indiana Jones and
    the Infernal Machine" reveals a lot of artifacts and a lot of
    "Ignoring invalid motion vector (149, -41)->(136, 0), block size = 8"
    messages, hinting at the wrong direction of the motion vectors.
    
    Fix this by doing the calculation that the DOS/Windows players do,
    let the value overflow and reextract the "new" mvec x/y components.

diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c
index 9e99aa9dd9..e4308af647 100644
--- a/libavcodec/sanm.c
+++ b/libavcodec/sanm.c
@@ -2074,6 +2074,20 @@ static int codec2subblock(SANMVideoContext *ctx, int cx, 
int cy, int blk_size)
         mx = motion_vectors[opcode][0];
         my = motion_vectors[opcode][1];
 
+        /* The original implementation of this codec precomputes a table
+         * of int16_t all motion vectors for given image width.
+         * For larger widths, starting with 762 pixels, the calculation of
+         * mv table indices 1+ and 255- overflow the int16_t, inverting the
+         * sign of the offset.  This is actively exploited in e.g. the
+         *  "jonesopn_8.snm" video of "Indiana Jones and the Infernal Machine".
+         * Therefore let the overflow happen and extract x/y components from
+         * the new value.
+         */
+        if (ctx->width > 761) {
+            index = (int16_t)(my * ctx->width + mx);
+            mx = index % ctx->width;
+            my = index / ctx->width;
+        }
         if (good_mvec(ctx, cx, cy, mx, my, blk_size)) {
             copy_block(ctx->frm0 + cx      + ctx->pitch *  cy,
                        ctx->frm2 + cx + mx + ctx->pitch * (cy + my),

-----------------------------------------------------------------------

Summary of changes:
 libavcodec/sanm.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)


hooks/post-receive
-- 

_______________________________________________
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

To unsubscribe, visit link above, or email
ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to