avcodec/sanm: simplify codec37 subcodec 3/4 path

A flag in the codec header determines whether opcodes 0xfd/0xfe
are to be treated as special or not.  The current code has 2
implementations of the same decoding scheme, with one treating
the 2 opcodes as special, the other not.
Collapse them into a single implementation and treat these opcode
according to the flag.

Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
Manuel Lauss 2025-01-09 09:03:12 +01:00 committed by Michael Niedermayer
parent fff7737b3d
commit 9a794897c3
No known key found for this signature in database
GPG key ID: B18E8928B3948D64

View file

@ -734,87 +734,47 @@ static int old_codec37(SANMVideoContext *ctx, int top,
break; break;
case 3: case 3:
case 4: case 4:
if (flags & 4) { for (j = 0; j < height; j += 4) {
for (j = 0; j < height; j += 4) { for (i = 0; i < width; i += 4) {
for (i = 0; i < width; i += 4) { int code;
int code; if (skip_run) {
if (skip_run) { skip_run--;
skip_run--; copy_block4(dst + i, prev + i, stride, stride, 4);
copy_block4(dst + i, prev + i, stride, stride, 4); continue;
continue; }
} if (bytestream2_get_bytes_left(&ctx->gb) < 1)
return AVERROR_INVALIDDATA;
code = bytestream2_get_byteu(&ctx->gb);
if (code == 0xFF) {
if (bytestream2_get_bytes_left(&ctx->gb) < 16)
return AVERROR_INVALIDDATA;
for (k = 0; k < 4; k++)
bytestream2_get_bufferu(&ctx->gb, dst + i + k * stride, 4);
} else if ((flags & 4) && (code == 0xFE)) {
if (bytestream2_get_bytes_left(&ctx->gb) < 4)
return AVERROR_INVALIDDATA;
for (k = 0; k < 4; k++)
memset(dst + i + k * stride, bytestream2_get_byteu(&ctx->gb), 4);
} else if ((flags & 4) && (code == 0xFD)) {
if (bytestream2_get_bytes_left(&ctx->gb) < 1) if (bytestream2_get_bytes_left(&ctx->gb) < 1)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
code = bytestream2_get_byteu(&ctx->gb); t = bytestream2_get_byteu(&ctx->gb);
switch (code) { for (k = 0; k < 4; k++)
case 0xFF: memset(dst + i + k * stride, t, 4);
if (bytestream2_get_bytes_left(&ctx->gb) < 16) } else if ((compr == 4) && (code == 0)) {
return AVERROR_INVALIDDATA; if (bytestream2_get_bytes_left(&ctx->gb) < 1)
for (k = 0; k < 4; k++) return AVERROR_INVALIDDATA;
bytestream2_get_bufferu(&ctx->gb, dst + i + k * stride, 4); skip_run = bytestream2_get_byteu(&ctx->gb) + 1;
break; i -= 4;
case 0xFE: } else {
if (bytestream2_get_bytes_left(&ctx->gb) < 4) mx = c37_mv[(mvoff * 255 + code) * 2];
return AVERROR_INVALIDDATA; my = c37_mv[(mvoff * 255 + code) * 2 + 1];
for (k = 0; k < 4; k++) codec37_mv(dst + i, prev + i + mx + my * stride,
memset(dst + i + k * stride, bytestream2_get_byteu(&ctx->gb), 4); ctx->height, stride, i + mx, j + my);
break;
case 0xFD:
if (bytestream2_get_bytes_left(&ctx->gb) < 1)
return AVERROR_INVALIDDATA;
t = bytestream2_get_byteu(&ctx->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)
return AVERROR_INVALIDDATA;
skip_run = bytestream2_get_byteu(&ctx->gb) + 1;
i -= 4;
} else {
mx = c37_mv[(mvoff * 255 + code) * 2];
my = c37_mv[(mvoff * 255 + code) * 2 + 1];
codec37_mv(dst + i, prev + i + mx + my * stride,
ctx->height, stride, i + mx, j + my);
}
}
} }
dst += stride * 4;
prev += stride * 4;
}
} else {
for (j = 0; j < height; j += 4) {
for (i = 0; i < width; i += 4) {
int code;
if (skip_run) {
skip_run--;
copy_block4(dst + i, prev + i, stride, stride, 4);
continue;
}
code = bytestream2_get_byte(&ctx->gb);
if (code == 0xFF) {
if (bytestream2_get_bytes_left(&ctx->gb) < 16)
return AVERROR_INVALIDDATA;
for (k = 0; k < 4; k++)
bytestream2_get_bufferu(&ctx->gb, dst + i + k * stride, 4);
} else if (compr == 4 && !code) {
if (bytestream2_get_bytes_left(&ctx->gb) < 1)
return AVERROR_INVALIDDATA;
skip_run = bytestream2_get_byteu(&ctx->gb) + 1;
i -= 4;
} else {
int mx, my;
mx = c37_mv[(mvoff * 255 + code) * 2];
my = c37_mv[(mvoff * 255 + code) * 2 + 1];
codec37_mv(dst + i, prev + i + mx + my * stride,
ctx->height, stride, i + mx, j + my);
}
}
dst += stride * 4;
prev += stride * 4;
} }
dst += stride * 4;
prev += stride * 4;
} }
break; break;
default: default: