* [FFmpeg-devel] [PATCH] avcodec/sanm: mv and oob fixes (PR #20284)
@ 2025-08-19 11:16 Manuel Lauss via ffmpeg-devel
0 siblings, 0 replies; only message in thread
From: Manuel Lauss via ffmpeg-devel @ 2025-08-19 11:16 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Manuel Lauss
PR #20284 opened by Manuel Lauss (mlauss2)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20284
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20284.patch
- Fix the old_codec1..31 implementations to check whether a pixel is inside the visible/allocated buffer area. Should render commit 134fbfd1dcb5 obsolete, also since it breaks Rebel Assault 1 videos.
- Fix old_codec48 decoding. Commit d5bdb0b705ce broke it, rewrite the MV check and add another row of 8x8 blocks to the allocated buffer space, since even "valid"/released videos try to access data outside the defined image area. The worst I've seen is 8 rows with "Mysteries of the Sith", adding the extra block row restores playback of all videos and does not trigger the MV check.
From c7c8b6ad047c0f93d7cedde6afd2d24bd4286a3f Mon Sep 17 00:00:00 2001
From: Manuel Lauss <manuel.lauss@gmail.com>
Date: Tue, 19 Aug 2025 11:13:46 +0200
Subject: [PATCH 1/2] avcodec/sanm: don't write outside buffer
adjust codecs1-34 to check whether the coordinates they want to
write to are inside the currently defined buffer. Especially
Rebel Assault 1 makes use of FOBJs that are partially outside the
defined buffer width, so only draw pixels that are really visible.
This also fixes a bug in the Intro of Rebel Assault 1, where a Sun
is partially drawn outside the right side of the buffer and the
invisible part rendered on the left side.
This also undoes 134fbfd1dcb59441e38d870ddd231772f4e8e127 since
it breaks Rebel Assault 1.
Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
---
libavcodec/sanm.c | 266 +++++++++++++++++++++++-----------------------
1 file changed, 132 insertions(+), 134 deletions(-)
diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c
index e4308af647..770fd3a1d0 100644
--- a/libavcodec/sanm.c
+++ b/libavcodec/sanm.c
@@ -668,72 +668,6 @@ static av_cold int decode_end(AVCodecContext *avctx)
return 0;
}
-static int old_codec4(SANMVideoContext *ctx, GetByteContext *gb, int top, int left,
- int w, int h, uint8_t param, uint16_t param2, int codec)
-{
- const uint16_t p = ctx->pitch;
- const uint32_t maxpxo = ctx->height * p;
- uint8_t mask, bits, idx, *gs, *dst = (uint8_t *)ctx->fbuf;
- int i, j, k, l, bit, ret;
- int32_t pxoff, pxo2;
-
- if (ctx->c4param != param) {
- if (codec > 32)
- codec33_gen_tiles(ctx, param);
- else
- codec4_gen_tiles(ctx, param);
- ctx->c4param = param;
- }
- if (param2 > 0) {
- ret = codec4_load_tiles(ctx, gb, param2, param);
- if (ret)
- return ret;
- }
-
- if (codec > 32)
- codec -= 29;
-
- for (j = 0; j < w; j += 4) {
- mask = bits = 0;
- for (i = 0; i < h; i += 4) {
- pxoff = j + left + ((top + i) * p);
- if (param2 > 0) {
- if (bits == 0) {
- if (bytestream2_get_bytes_left(gb) < 1)
- return AVERROR_INVALIDDATA;
- mask = bytestream2_get_byteu(gb);
- bits = 8;
- }
- bit = !!(mask & 0x80);
- mask <<= 1;
- bits--;
- } else {
- bit = 0;
- }
-
- if (bytestream2_get_bytes_left(gb) < 1)
- return AVERROR_INVALIDDATA;
- idx = bytestream2_get_byteu(gb);
- if ((bit == 0) && (idx == 0x80) && (codec != 5))
- continue;
-
- gs = &(ctx->c4tbl[bit][idx][0]);
- pxo2 = pxoff;
- for (k = 0; k < 4; k++) {
- for (l = 0; l < 4; l++) {
- if (pxo2 >= 0 && pxo2 < maxpxo) {
- *(dst + pxo2) = *gs;
- }
- gs++;
- pxo2++;
- }
- pxo2 = pxo2 - 4 + p;
- }
- }
- }
- return 0;
-}
-
static int rle_decode(SANMVideoContext *ctx, GetByteContext *gb, uint8_t *dst, const int out_size)
{
int opcode, color, run_len, left = out_size;
@@ -760,13 +694,97 @@ static int rle_decode(SANMVideoContext *ctx, GetByteContext *gb, uint8_t *dst, c
return 0;
}
+/* helpers to ensure coordinates are always inside the buffer area, to be used
+ * by old_codec1..31
+ */
+static inline int validofs(int x, int y, int maxx, int maxy)
+{
+ return ((x >= 0) && (y >= 0) && (x < maxx) && (y < maxy));
+}
+
+static inline uint8_t readpx(const uint8_t *dst, int x, int y, int pitch)
+{
+ return *(uint8_t *)(dst + x + y * pitch);
+}
+
+static inline void writepx(const uint8_t *dst, int x, int y, int pitch, uint8_t px)
+{
+ *(uint8_t *)(dst + x + y * pitch) = px;
+}
+
+static inline void chkwrpx(const uint8_t *dst, int x, int y, int maxx, int maxy, uint8_t col)
+{
+ if (validofs(x, y, maxx, maxy))
+ writepx(dst, x, y, maxx, col);
+}
+
+static int old_codec4(SANMVideoContext *ctx, GetByteContext *gb, int top, int left,
+ int w, int h, uint8_t param, uint16_t param2, int codec)
+{
+ const uint8_t *dst = (uint8_t *)ctx->fbuf;
+ const int mx = ctx->width;
+ const int my = ctx->height;
+ uint8_t mask, bits, idx, *gs;
+ int i, j, k, l, bit, ret;
+
+ if (ctx->c4param != param) {
+ if (codec > 32)
+ codec33_gen_tiles(ctx, param);
+ else
+ codec4_gen_tiles(ctx, param);
+ ctx->c4param = param;
+ }
+ if (param2 > 0) {
+ ret = codec4_load_tiles(ctx, gb, param2, param);
+ if (ret)
+ return ret;
+ }
+
+ if (codec > 32)
+ codec -= 29;
+
+ for (j = 0; j < w; j += 4) {
+ mask = bits = 0;
+ for (i = 0; i < h; i += 4) {
+ if (param2 > 0) {
+ if (bits == 0) {
+ if (bytestream2_get_bytes_left(gb) < 1)
+ return AVERROR_INVALIDDATA;
+ mask = bytestream2_get_byteu(gb);
+ bits = 8;
+ }
+ bit = !!(mask & 0x80);
+ mask <<= 1;
+ bits--;
+ } else {
+ bit = 0;
+ }
+
+ if (bytestream2_get_bytes_left(gb) < 1)
+ return AVERROR_INVALIDDATA;
+ idx = bytestream2_get_byteu(gb);
+ if ((bit == 0) && (idx == 0x80) && (codec != 5))
+ continue;
+
+ gs = &(ctx->c4tbl[bit][idx][0]);
+ for (k = 0; k < 4; k++) {
+ for (l = 0; l < 4; l++) {
+ chkwrpx(dst, left + j + l, top + i + k, mx, my, *gs++);
+ }
+ }
+ }
+ }
+ return 0;
+}
+
static int old_codec23(SANMVideoContext *ctx, GetByteContext *gb, int top, int left,
int width, int height, uint8_t param, uint16_t param2)
{
- const uint32_t maxpxo = ctx->height * ctx->pitch;
- uint8_t *dst, lut[256], c;
+ const uint8_t *dst = (uint8_t *)ctx->fbuf;
+ const int mx = ctx->width;
+ const int my = ctx->height;
+ uint8_t lut[256], c;
int i, j, k, pc, sk;
- int32_t pxoff;
if (ctx->subversion < 2) {
/* Rebel Assault 1: constant offset + 0xd0 */
@@ -785,11 +803,9 @@ static int old_codec23(SANMVideoContext *ctx, GetByteContext *gb, int top, int l
if (bytestream2_get_bytes_left(gb) < 1)
return 0; /* some c23 frames just set up the LUT */
- dst = (uint8_t *)ctx->fbuf;
for (i = 0; i < height; i++) {
if (bytestream2_get_bytes_left(gb) < 2)
return 0;
- pxoff = left + ((top + i) * ctx->pitch);
k = bytestream2_get_le16u(gb);
sk = 1;
pc = 0;
@@ -798,15 +814,13 @@ static int old_codec23(SANMVideoContext *ctx, GetByteContext *gb, int top, int l
return AVERROR_INVALIDDATA;
j = bytestream2_get_byteu(gb);
if (sk) {
- pxoff += j;
pc += j;
} else {
while (j--) {
- if (pxoff >=0 && pxoff < maxpxo) {
- c = *(dst + pxoff);
- *(dst + pxoff) = lut[c];
+ if (validofs(pc + left, top + i, mx, my)) {
+ c = readpx(dst, pc + left, top + i, mx);
+ writepx(dst, pc + left, top + i, mx, lut[c]);
}
- pxoff++;
pc++;
}
}
@@ -819,15 +833,15 @@ static int old_codec23(SANMVideoContext *ctx, GetByteContext *gb, int top, int l
static int old_codec21(SANMVideoContext *ctx, GetByteContext *gb, int top, int left,
int width, int height)
{
- const uint32_t maxpxo = ctx->height * ctx->pitch;
- uint8_t *dst = (uint8_t *)ctx->fbuf, c;
- int i, j, k, pc, sk, pxoff;
+ const uint8_t *dst = (uint8_t *)ctx->fbuf;
+ const int mx = ctx->width;
+ const int my = ctx->height;
+ uint8_t c;
+ int i, j, k, pc, sk;
- dst = (uint8_t *)ctx->fbuf;
for (i = 0; i < height; i++) {
if (bytestream2_get_bytes_left(gb) < 2)
return 0;
- pxoff = left + ((top + i) * ctx->pitch);
k = bytestream2_get_le16u(gb);
sk = 1;
pc = 0;
@@ -837,17 +851,13 @@ static int old_codec21(SANMVideoContext *ctx, GetByteContext *gb, int top, int l
j = bytestream2_get_le16u(gb);
k -= 2;
if (sk) {
- pxoff += j;
pc += j;
} else {
if (bytestream2_get_bytes_left(gb) < (j + 1))
return AVERROR_INVALIDDATA;
do {
c = bytestream2_get_byteu(gb);
- if (pxoff >=0 && pxoff < maxpxo) {
- *(dst + pxoff) = c;
- }
- pxoff++;
+ chkwrpx(dst, left + pc, top + i, mx, my, c);
pc++;
j--;
k--;
@@ -862,9 +872,10 @@ static int old_codec21(SANMVideoContext *ctx, GetByteContext *gb, int top, int l
static int old_codec1(SANMVideoContext *ctx, GetByteContext *gb, int top,
int left, int width, int height, int opaque)
{
- int i, j, len, flag, code, val, end, pxoff;
- const int maxpxo = ctx->height * ctx->pitch;
- uint8_t *dst = (uint8_t *)ctx->fbuf;
+ const uint8_t *dst = (uint8_t *)ctx->fbuf;
+ int i, j, len, flag, code, val, end, x;
+ const int mx = ctx->width;
+ const int my = ctx->height;
for (i = 0; i < height; i++) {
if (bytestream2_get_bytes_left(gb) < 2)
@@ -872,8 +883,8 @@ static int old_codec1(SANMVideoContext *ctx, GetByteContext *gb, int top,
len = bytestream2_get_le16u(gb);
end = bytestream2_tell(gb) + len;
+ x = left;
- pxoff = left + ((top + i) * ctx->pitch);
while (bytestream2_tell(gb) < end) {
if (bytestream2_get_bytes_left(gb) < 2)
return AVERROR_INVALIDDATA;
@@ -883,23 +894,19 @@ static int old_codec1(SANMVideoContext *ctx, GetByteContext *gb, int top,
code = (code >> 1) + 1;
if (flag) {
val = bytestream2_get_byteu(gb);
- if (val || opaque) {
- for (j = 0; j < code; j++) {
- if (pxoff >= 0 && pxoff < maxpxo)
- *(dst + pxoff) = val;
- pxoff++;
- }
- } else {
- pxoff += code;
+ for (j = 0; j < code; j++) {
+ if (val || opaque)
+ chkwrpx(dst, x, top + i, mx, my, val);
+ x++;
}
} else {
if (bytestream2_get_bytes_left(gb) < code)
return AVERROR_INVALIDDATA;
for (j = 0; j < code; j++) {
val = bytestream2_get_byteu(gb);
- if ((pxoff >= 0) && (pxoff < maxpxo) && (val || opaque))
- *(dst + pxoff) = val;
- pxoff++;
+ if (val || opaque)
+ chkwrpx(dst, x, top + i, mx, my, val);
+ x++;
}
}
}
@@ -912,9 +919,10 @@ static int old_codec1(SANMVideoContext *ctx, GetByteContext *gb, int top,
static int old_codec31(SANMVideoContext *ctx, GetByteContext *gb, int top,
int left, int width, int height, int p1, int opaque)
{
- int i, j, len, flag, code, val, end, pxoff;
- const int maxpxo = ctx->height * ctx->pitch;
- uint8_t *dst = (uint8_t *)ctx->fbuf;
+ const uint8_t *dst = (uint8_t *)ctx->fbuf;
+ int i, j, len, flag, code, val, end, x;
+ const int mx = ctx->width;
+ const int my = ctx->height;
for (i = 0; i < height; i++) {
if (bytestream2_get_bytes_left(gb) < 2)
@@ -922,8 +930,8 @@ static int old_codec31(SANMVideoContext *ctx, GetByteContext *gb, int top,
len = bytestream2_get_le16u(gb);
end = bytestream2_tell(gb) + len;
+ x = left;
- pxoff = left + ((top + i) * ctx->pitch);
while (bytestream2_tell(gb) < end) {
if (bytestream2_get_bytes_left(gb) < 2)
return AVERROR_INVALIDDATA;
@@ -934,28 +942,24 @@ static int old_codec31(SANMVideoContext *ctx, GetByteContext *gb, int top,
if (flag) {
val = bytestream2_get_byteu(gb);
for (j = 0; j < code; j++) {
- if ((0 != (val & 0xf)) || opaque) {
- if (pxoff >= 0 && pxoff < maxpxo)
- *(dst + pxoff) = p1 + (val & 0xf);
- }
- pxoff++;
- if ((0 != (val >> 4)) || opaque) {
- if (pxoff >= 0 && pxoff < maxpxo)
- *(dst + pxoff) = p1 + (val >> 4);
- }
- pxoff++;
+ if (opaque || (val & 0xf))
+ chkwrpx(dst, x, top + i, mx, my, p1 + (val & 0x0f));
+ x++;
+ if (opaque || (val >> 4))
+ chkwrpx(dst, x, top + i, mx, my, p1 + (val >> 4));
+ x++;
}
} else {
if (bytestream2_get_bytes_left(gb) < code)
return AVERROR_INVALIDDATA;
for (j = 0; j < code; j++) {
val = bytestream2_get_byteu(gb);
- if ((pxoff >= 0) && (pxoff < maxpxo) && ((0 != (val & 0xf)) || opaque))
- *(dst + pxoff) = p1 + (val & 0xf);
- pxoff++;
- if ((pxoff >= 0) && (pxoff < maxpxo) && ((0 != (val >> 4)) || opaque))
- *(dst + pxoff) = p1 + (val >> 4);
- pxoff++;
+ if (opaque || (val & 0xf))
+ chkwrpx(dst, x, top + i, mx, my, p1 + (val & 0x0f));
+ x++;
+ if (opaque || (val >> 4))
+ chkwrpx(dst, x, top + i, mx, my, p1 + (val >> 4));
+ x++;
}
}
}
@@ -968,17 +972,16 @@ static int old_codec31(SANMVideoContext *ctx, GetByteContext *gb, int top,
static int old_codec2(SANMVideoContext *ctx, GetByteContext *gb, int top,
int left, int width, int height)
{
- uint8_t *dst = (uint8_t *)ctx->fbuf, col;
- int16_t xpos = left, ypos = top;
+ const uint8_t *dst = (uint8_t *)ctx->fbuf;
+ const int mx = ctx->width;
+ const int my = ctx->height;
+ uint8_t col;
while (bytestream2_get_bytes_left(gb) > 3) {
- xpos += bytestream2_get_le16u(gb);
- ypos += bytestream2_get_byteu(gb);
+ left += bytestream2_get_le16u(gb);
+ top += bytestream2_get_byteu(gb);
col = bytestream2_get_byteu(gb);
- if (xpos >= 0 && ypos >= 0 &&
- xpos < ctx->width && ypos < ctx->height) {
- *(dst + xpos + ypos * ctx->pitch) = col;
- }
+ chkwrpx(dst, left, top, mx, my, col);
}
return 0;
}
@@ -1757,11 +1760,6 @@ static int process_frame_obj(SANMVideoContext *ctx, GetByteContext *gb)
memset(ctx->fbuf, 0, ctx->frm0_size);
}
- if (w + FFMAX(left, 0) > ctx->avctx->width || h + FFMAX(top, 0) > ctx->avctx->height) {
- avpriv_request_sample(ctx->avctx, "overly large frame\n");
- return AVERROR_PATCHWELCOME;
- }
-
switch (codec) {
case 1:
case 3:
--
2.49.1
From 117b05f6026ae5a43557baeccb8469de736aa670 Mon Sep 17 00:00:00 2001
From: Manuel Lauss <manuel.lauss@gmail.com>
Date: Tue, 19 Aug 2025 12:43:17 +0200
Subject: [PATCH 2/2] avcodec/sanm: fix codec48 decoding
Commit d5bdb0b705ce ("avcodec/sanm: Check mv in codec48_block()")
completely broke decoding of valid codec48 videos.
Rewrite the MV check, and most importantly, add another row of 8x8
blocks to the allocated buffer, since even "valid" videos released
by LucasArts try to copy blocks from up to 8 rows outside the
defined image area.
Fixes: d5bdb0b705ce96739e812ca5317361674359369c
Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
---
libavcodec/sanm.c | 51 +++++++++++++++++++++++------------------------
1 file changed, 25 insertions(+), 26 deletions(-)
diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c
index 770fd3a1d0..0e18c0a910 100644
--- a/libavcodec/sanm.c
+++ b/libavcodec/sanm.c
@@ -446,6 +446,7 @@ static void init_sizes(SANMVideoContext *ctx, int width, int height)
ctx->aligned_width = FFALIGN(width, 8);
ctx->aligned_height = FFALIGN(height, 8);
+ ctx->aligned_height += 8; /* for slighly too large MVs in codec37/48 */
ctx->buf_size = ctx->aligned_width * ctx->aligned_height * sizeof(ctx->frm0[0]);
ctx->pitch = width;
@@ -1430,20 +1431,20 @@ static void c48_4to8(uint8_t *dst, const uint8_t *src, const uint16_t w)
}
}
-static int check_mv(int x, int y, const uint16_t w, int h, int blocksize, int mvofs) {
- if (mvofs < -x + -y*w)
- return AVERROR_INVALIDDATA;
-
- if (mvofs > w-x-blocksize + w*(h-y-blocksize))
- return AVERROR_INVALIDDATA;
-
- return 0;
+static inline int c48_valid_mv(int x, int y, const uint16_t w, const int h, int bs, int mvofs)
+{
+ const int m = (x + bs - 1 + w * (y + bs - 1));
+ const int n = (x + w * y);
+ if ((mvofs < 0 && ((n - mvofs) < 0)) || ((m + mvofs) >= (w * h))) {
+ return 0;
+ }
+ return 1;
}
-static int codec48_block(SANMVideoContext *ctx, uint8_t *dst, uint8_t *db, int x, int y,
- const uint16_t w, int h)
+static int codec48_block(SANMVideoContext *ctx, int x, int y, const uint16_t w)
{
- uint8_t opc, sb[16];
+ uint8_t opc, sb[16], *dst = (uint8_t *)ctx->frm0 + x + y * w;
+ uint8_t *db = (uint8_t *)ctx->frm2 + x + y * w;
int i, j, k, l;
int16_t mvofs;
uint32_t ofs;
@@ -1466,8 +1467,8 @@ static int codec48_block(SANMVideoContext *ctx, uint8_t *dst, uint8_t *db, int x
if (bytestream2_get_bytes_left(&ctx->gb) < 2)
return 1;
mvofs = bytestream2_get_le16(&ctx->gb);
- if (check_mv(x, y, w, h, 8, mvofs))
- return 1;
+ if (!c48_valid_mv(x, y, w, ctx->aligned_height, 8, mvofs))
+ break;
for (i = 0; i < 8; i++) {
ofs = w * i;
for (k = 0; k < 8; k++)
@@ -1495,8 +1496,8 @@ static int codec48_block(SANMVideoContext *ctx, uint8_t *dst, uint8_t *db, int x
for (k = 0; k < 8; k += 4) {
opc = bytestream2_get_byteu(&ctx->gb);
mvofs = c37_mv[opc * 2] + (c37_mv[opc * 2 + 1] * w);
- if (check_mv(x+k, y+i, w, h, 4, mvofs))
- return 1;
+ if (!c48_valid_mv(x+k, y+i, w, ctx->aligned_height, 4, mvofs))
+ continue;
for (j = 0; j < 4; j++) {
ofs = (w * (j + i)) + k;
for (l = 0; l < 4; l++)
@@ -1511,8 +1512,8 @@ static int codec48_block(SANMVideoContext *ctx, uint8_t *dst, uint8_t *db, int x
for (i = 0; i < 8; i += 4) {
for (k = 0; k < 8; k += 4) {
mvofs = bytestream2_get_le16(&ctx->gb);
- if (check_mv(x+k, y+i, w, h, 4, mvofs))
- return 1;
+ if (!c48_valid_mv(x+k, y+i, w, ctx->aligned_height, 4, mvofs))
+ continue;
for (j = 0; j < 4; j++) {
ofs = (w * (j + i)) + k;
for (l = 0; l < 4; l++)
@@ -1535,8 +1536,8 @@ static int codec48_block(SANMVideoContext *ctx, uint8_t *dst, uint8_t *db, int x
ofs = (w * i) + j;
opc = bytestream2_get_byteu(&ctx->gb);
mvofs = c37_mv[opc * 2] + (c37_mv[opc * 2 + 1] * w);
- if (check_mv(x+j, y+i, w, h, 2, mvofs))
- return 1;
+ if (!c48_valid_mv(x+j, y+i, w, ctx->aligned_height, 2, mvofs))
+ continue;
for (l = 0; l < 2; l++) {
*(dst + ofs + l + 0) = *(db + ofs + l + 0 + mvofs);
*(dst + ofs + l + w) = *(db + ofs + l + w + mvofs);
@@ -1551,8 +1552,8 @@ static int codec48_block(SANMVideoContext *ctx, uint8_t *dst, uint8_t *db, int x
for (j = 0; j < 8; j += 2) {
ofs = w * i + j;
mvofs = bytestream2_get_le16(&ctx->gb);
- if (check_mv(x+j, y+i, w, h, 2, mvofs))
- return 1;
+ if (!c48_valid_mv(x+j, y+i, w, ctx->aligned_height, 2, mvofs))
+ continue;
for (l = 0; l < 2; l++) {
*(dst + ofs + l + 0) = *(db + ofs + l + 0 + mvofs);
*(dst + ofs + l + w) = *(db + ofs + l + w + mvofs);
@@ -1571,8 +1572,8 @@ static int codec48_block(SANMVideoContext *ctx, uint8_t *dst, uint8_t *db, int x
break;
default: // copy 8x8 block from prev, c37_mv from source
mvofs = c37_mv[opc * 2] + (c37_mv[opc * 2 + 1] * w);
- if (check_mv(x, y, w, h, 8, mvofs))
- return 1;
+ if (!c48_valid_mv(x, y, w, ctx->aligned_height, 8, mvofs))
+ break;
for (i = 0; i < 8; i++) {
ofs = i * w;
for (l = 0; l < 8; l++)
@@ -1638,11 +1639,9 @@ static int old_codec48(SANMVideoContext *ctx, int width, int height)
if (seq == ctx->prev_seq + 1) {
for (j = 0; j < height; j += 8) {
for (i = 0; i < width; i += 8) {
- if (codec48_block(ctx, dst + i, prev + i, i, j, width, height))
+ if (codec48_block(ctx, i, j, width))
return AVERROR_INVALIDDATA;
}
- dst += width * 8;
- prev += width * 8;
}
}
break;
--
2.49.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2025-08-19 11:16 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-08-19 11:16 [FFmpeg-devel] [PATCH] avcodec/sanm: mv and oob fixes (PR #20284) Manuel Lauss via ffmpeg-devel
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git