Commit 609e2e64 authored by Michael Niedermayer's avatar Michael Niedermayer

avcodec/scpr: Use local variables in decode_run_i()

This improves the speed of decode_run_i()

Before: clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_SCPR_fuzzer-5656821117747200 in 17420 ms
After:  clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_SCPR_fuzzer-5656821117747200 in 14018 ms

Improves: 11270/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_SCPR_fuzzer-5656821117747200

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpegSigned-off-by: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent b6c2c589
...@@ -78,58 +78,62 @@ typedef struct SCPRContext { ...@@ -78,58 +78,62 @@ typedef struct SCPRContext {
} SCPRContext; } SCPRContext;
static int decode_run_i(AVCodecContext *avctx, uint32_t ptype, int run, static int decode_run_i(AVCodecContext *avctx, uint32_t ptype, int run,
int *x, int *y, uint32_t clr, uint32_t *dst, int *px, int *py, uint32_t clr, uint32_t *dst,
int linesize, uint32_t *lx, uint32_t *ly, int linesize, uint32_t *plx, uint32_t *ply,
uint32_t backstep, int off, int *cx, int *cx1) uint32_t backstep, int off, int *cx, int *cx1)
{ {
uint32_t r, g, b; uint32_t r, g, b;
int z; int z;
int x = *px,
y = *py;
uint32_t lx = *plx,
ly = *ply;
switch (ptype) { switch (ptype) {
case 0: case 0:
while (run-- > 0) { while (run-- > 0) {
if (*y >= avctx->height) if (y >= avctx->height)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
dst[*y * linesize + *x] = clr; dst[y * linesize + x] = clr;
*lx = *x; lx = x;
*ly = *y; ly = y;
(*x)++; (x)++;
if (*x >= avctx->width) { if (x >= avctx->width) {
*x = 0; x = 0;
(*y)++; (y)++;
} }
} }
break; break;
case 1: case 1:
while (run-- > 0) { while (run-- > 0) {
if (*y >= avctx->height) if (y >= avctx->height)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
dst[*y * linesize + *x] = dst[*ly * linesize + *lx]; dst[y * linesize + x] = dst[ly * linesize + lx];
*lx = *x; lx = x;
*ly = *y; ly = y;
(*x)++; (x)++;
if (*x >= avctx->width) { if (x >= avctx->width) {
*x = 0; x = 0;
(*y)++; (y)++;
} }
} }
clr = dst[*ly * linesize + *lx]; clr = dst[ly * linesize + lx];
break; break;
case 2: case 2:
while (run-- > 0) { while (run-- > 0) {
if (*y < 1 || *y >= avctx->height) if (y < 1 || y >= avctx->height)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
clr = dst[*y * linesize + *x + off + 1]; clr = dst[y * linesize + x + off + 1];
dst[*y * linesize + *x] = clr; dst[y * linesize + x] = clr;
*lx = *x; lx = x;
*ly = *y; ly = y;
(*x)++; (x)++;
if (*x >= avctx->width) { if (x >= avctx->width) {
*x = 0; x = 0;
(*y)++; (y)++;
} }
} }
break; break;
...@@ -137,61 +141,66 @@ static int decode_run_i(AVCodecContext *avctx, uint32_t ptype, int run, ...@@ -137,61 +141,66 @@ static int decode_run_i(AVCodecContext *avctx, uint32_t ptype, int run,
while (run-- > 0) { while (run-- > 0) {
uint8_t *odst = (uint8_t *)dst; uint8_t *odst = (uint8_t *)dst;
if (*y < 1 || *y >= avctx->height || if (y < 1 || y >= avctx->height ||
(*y == 1 && *x == 0)) (y == 1 && x == 0))
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
if (*x == 0) { if (x == 0) {
z = backstep; z = backstep;
} else { } else {
z = 0; z = 0;
} }
r = odst[(*ly * linesize + *lx) * 4] + r = odst[(ly * linesize + lx) * 4] +
odst[((*y * linesize + *x) + off) * 4 + 4] - odst[((y * linesize + x) + off) * 4 + 4] -
odst[((*y * linesize + *x) + off - z) * 4]; odst[((y * linesize + x) + off - z) * 4];
g = odst[(*ly * linesize + *lx) * 4 + 1] + g = odst[(ly * linesize + lx) * 4 + 1] +
odst[((*y * linesize + *x) + off) * 4 + 5] - odst[((y * linesize + x) + off) * 4 + 5] -
odst[((*y * linesize + *x) + off - z) * 4 + 1]; odst[((y * linesize + x) + off - z) * 4 + 1];
b = odst[(*ly * linesize + *lx) * 4 + 2] + b = odst[(ly * linesize + lx) * 4 + 2] +
odst[((*y * linesize + *x) + off) * 4 + 6] - odst[((y * linesize + x) + off) * 4 + 6] -
odst[((*y * linesize + *x) + off - z) * 4 + 2]; odst[((y * linesize + x) + off - z) * 4 + 2];
clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF); clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF);
dst[*y * linesize + *x] = clr; dst[y * linesize + x] = clr;
*lx = *x; lx = x;
*ly = *y; ly = y;
(*x)++; (x)++;
if (*x >= avctx->width) { if (x >= avctx->width) {
*x = 0; x = 0;
(*y)++; (y)++;
} }
} }
break; break;
case 5: case 5:
while (run-- > 0) { while (run-- > 0) {
if (*y < 1 || *y >= avctx->height || if (y < 1 || y >= avctx->height ||
(*y == 1 && *x == 0)) (y == 1 && x == 0))
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
if (*x == 0) { if (x == 0) {
z = backstep; z = backstep;
} else { } else {
z = 0; z = 0;
} }
clr = dst[*y * linesize + *x + off - z]; clr = dst[y * linesize + x + off - z];
dst[*y * linesize + *x] = clr; dst[y * linesize + x] = clr;
*lx = *x; lx = x;
*ly = *y; ly = y;
(*x)++; (x)++;
if (*x >= avctx->width) { if (x >= avctx->width) {
*x = 0; x = 0;
(*y)++; (y)++;
} }
} }
break; break;
} }
*px = x;
*py = y;
*plx= lx;
*ply= ly;
if (avctx->bits_per_coded_sample == 16) { if (avctx->bits_per_coded_sample == 16) {
*cx1 = (clr & 0x3F00) >> 2; *cx1 = (clr & 0x3F00) >> 2;
*cx = (clr & 0x3FFFFF) >> 16; *cx = (clr & 0x3FFFFF) >> 16;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment