[FFmpeg-devel] [PATCH 1/2] avcodec/scpr: avoid negative linesize
Paul B Mahol
onemda at gmail.com
Sun Mar 12 13:40:39 EET 2017
Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
libavcodec/scpr.c | 89 ++++++++++++++++++++++++++++++-------------------------
1 file changed, 48 insertions(+), 41 deletions(-)
diff --git a/libavcodec/scpr.c b/libavcodec/scpr.c
index 465926a..a37e99a 100644
--- a/libavcodec/scpr.c
+++ b/libavcodec/scpr.c
@@ -290,6 +290,14 @@ static int decode_unit(SCPRContext *s, PixelModel *pixel, unsigned step, unsigne
return 0;
}
+static int vflip(int pos, int h, int linesize)
+{
+ int y = pos / linesize;
+ int x = pos % linesize;
+
+ return (h - y) * linesize + x;
+}
+
static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize)
{
SCPRContext *s = avctx->priv_data;
@@ -299,6 +307,7 @@ static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize)
unsigned backstep = linesize - avctx->width;
const int cxshift = s->cxshift;
unsigned lx, ly, ptype;
+ const int hy = avctx->height - 1;
reinit_tables(s);
bytestream2_skip(gb, 2);
@@ -331,7 +340,7 @@ static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize)
clr = (b << 16) + (g << 8) + r;
k += run;
while (run-- > 0) {
- dst[y * linesize + x] = clr;
+ dst[vflip(y * linesize + x, hy, linesize)] = clr;
lx = x;
ly = y;
x++;
@@ -379,7 +388,7 @@ static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize)
if (y >= avctx->height)
return AVERROR_INVALIDDATA;
- dst[y * linesize + x] = clr;
+ dst[vflip(y * linesize + x, hy, linesize)] = clr;
lx = x;
ly = y;
x++;
@@ -394,7 +403,7 @@ static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize)
if (y >= avctx->height)
return AVERROR_INVALIDDATA;
- dst[y * linesize + x] = dst[ly * linesize + lx];
+ dst[vflip(y * linesize + x, hy, linesize)] = dst[vflip(ly * linesize + lx, hy, linesize)];
lx = x;
ly = y;
x++;
@@ -403,15 +412,15 @@ static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize)
y++;
}
}
- clr = dst[ly * linesize + lx];
+ clr = dst[vflip(ly * linesize + lx, hy, linesize)];
break;
case 2:
while (run-- > 0) {
if (y < 1 || y >= avctx->height)
return AVERROR_INVALIDDATA;
- clr = dst[y * linesize + x + off + 1];
- dst[y * linesize + x] = clr;
+ clr = dst[vflip(y * linesize + x + off + 1, hy, linesize)];
+ dst[vflip(y * linesize + x, hy, linesize)] = clr;
lx = x;
ly = y;
x++;
@@ -435,17 +444,17 @@ static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize)
z = 0;
}
- r = odst[(ly * linesize + lx) * 4] +
- odst[((y * linesize + x) + off - z) * 4 + 4] -
- odst[((y * linesize + x) + off - z) * 4];
- g = odst[(ly * linesize + lx) * 4 + 1] +
- odst[((y * linesize + x) + off - z) * 4 + 5] -
- odst[((y * linesize + x) + off - z) * 4 + 1];
- b = odst[(ly * linesize + lx) * 4 + 2] +
- odst[((y * linesize + x) + off - z) * 4 + 6] -
- odst[((y * linesize + x) + off - z) * 4 + 2];
+ r = odst[vflip((ly * linesize + lx) * 4, hy, linesize * 4)] +
+ odst[vflip(((y * linesize + x) + off - z) * 4 + 4, hy, linesize * 4)] -
+ odst[vflip(((y * linesize + x) + off - z) * 4, hy, linesize * 4)];
+ g = odst[vflip((ly * linesize + lx) * 4 + 1, hy, linesize * 4)] +
+ odst[vflip(((y * linesize + x) + off - z) * 4 + 5, hy, linesize * 4)] -
+ odst[vflip(((y * linesize + x) + off - z) * 4 + 1, hy, linesize * 4)];
+ b = odst[vflip((ly * linesize + lx) * 4 + 2, hy, linesize * 4)] +
+ odst[vflip(((y * linesize + x) + off - z) * 4 + 6, hy, linesize * 4)] -
+ odst[vflip(((y * linesize + x) + off - z) * 4 + 2, hy, linesize * 4)];
clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF);
- dst[y * linesize + x] = clr;
+ dst[vflip(y * linesize + x, hy, linesize)] = clr;
lx = x;
ly = y;
x++;
@@ -467,8 +476,8 @@ static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize)
z = 0;
}
- clr = dst[y * linesize + x + off - z];
- dst[y * linesize + x] = clr;
+ clr = dst[vflip(y * linesize + x + off - z, hy, linesize)];
+ dst[vflip(y * linesize + x, hy, linesize)] = clr;
lx = x;
ly = y;
x++;
@@ -501,6 +510,7 @@ static int decompress_p(AVCodecContext *avctx,
int ret, temp, min, max, x, y, cx = 0, cx1 = 0;
int backstep = linesize - avctx->width;
const int cxshift = s->cxshift;
+ const int hy = avctx->height - 1;
if (bytestream2_get_byte(gb) == 0)
return 0;
@@ -567,7 +577,7 @@ static int decompress_p(AVCodecContext *avctx,
for (i = 0; i < sy2 - sy1 && (by + sy1 + i) < avctx->height && (by + mvy + sy1 + i) < avctx->height; i++) {
for (j = 0; j < sx2 - sx1 && (bx + sx1 + j) < avctx->width && (bx + mvx + sx1 + j) < avctx->width; j++) {
- dst[(by + i + sy1) * linesize + bx + sx1 + j] = prev[(by + mvy + sy1 + i) * plinesize + bx + sx1 + mvx + j];
+ dst[vflip((by + i + sy1) * linesize + bx + sx1 + j, hy, linesize)] = prev[vflip((by + mvy + sy1 + i) * plinesize + bx + sx1 + mvx + j, hy, linesize)];
}
}
} else {
@@ -607,7 +617,7 @@ static int decompress_p(AVCodecContext *avctx,
if (by >= avctx->height)
return AVERROR_INVALIDDATA;
- dst[by * linesize + bx] = clr;
+ dst[vflip(by * linesize + bx, hy, linesize)] = clr;
bx++;
if (bx >= x * 16 + sx2 || bx >= avctx->width) {
bx = x * 16 + sx1;
@@ -628,8 +638,8 @@ static int decompress_p(AVCodecContext *avctx,
if (by >= avctx->height)
return AVERROR_INVALIDDATA;
- clr = dst[by * linesize + bx - 1 - z];
- dst[by * linesize + bx] = clr;
+ clr = dst[vflip(by * linesize + bx - 1 - z, hy, linesize)];
+ dst[vflip(by * linesize + bx, hy, linesize)] = clr;
bx++;
if (bx >= x * 16 + sx2 || bx >= avctx->width) {
bx = x * 16 + sx1;
@@ -642,8 +652,8 @@ static int decompress_p(AVCodecContext *avctx,
if (by < 1 || by >= avctx->height)
return AVERROR_INVALIDDATA;
- clr = dst[(by - 1) * linesize + bx];
- dst[by * linesize + bx] = clr;
+ clr = dst[vflip((by - 1) * linesize + bx, hy, linesize)];
+ dst[vflip(by * linesize + bx, hy, linesize)] = clr;
bx++;
if (bx >= x * 16 + sx2 || bx >= avctx->width) {
bx = x * 16 + sx1;
@@ -656,8 +666,8 @@ static int decompress_p(AVCodecContext *avctx,
if (by >= avctx->height)
return AVERROR_INVALIDDATA;
- clr = prev[by * plinesize + bx];
- dst[by * linesize + bx] = clr;
+ clr = prev[vflip(by * plinesize + bx, hy, plinesize)];
+ dst[vflip(by * linesize + bx, hy, linesize)] = clr;
bx++;
if (bx >= x * 16 + sx2 || bx >= avctx->width) {
bx = x * 16 + sx1;
@@ -678,17 +688,17 @@ static int decompress_p(AVCodecContext *avctx,
z = 0;
}
- r = odst[((by - 1) * linesize + bx) * 4] +
- odst[(by * linesize + bx - 1 - z) * 4] -
- odst[((by - 1) * linesize + bx - 1 - z) * 4];
- g = odst[((by - 1) * linesize + bx) * 4 + 1] +
- odst[(by * linesize + bx - 1 - z) * 4 + 1] -
- odst[((by - 1) * linesize + bx - 1 - z) * 4 + 1];
- b = odst[((by - 1) * linesize + bx) * 4 + 2] +
- odst[(by * linesize + bx - 1 - z) * 4 + 2] -
- odst[((by - 1) * linesize + bx - 1 - z) * 4 + 2];
+ r = odst[vflip(((by - 1) * linesize + bx) * 4, hy, linesize * 4)] +
+ odst[vflip((by * linesize + bx - 1 - z) * 4, hy, linesize * 4)] -
+ odst[vflip(((by - 1) * linesize + bx - 1 - z) * 4, hy, linesize * 4)];
+ g = odst[vflip(((by - 1) * linesize + bx) * 4 + 1, hy, linesize * 4)] +
+ odst[vflip((by * linesize + bx - 1 - z) * 4 + 1, hy, linesize * 4)] -
+ odst[vflip(((by - 1) * linesize + bx - 1 - z) * 4 + 1, hy, linesize * 4)];
+ b = odst[vflip(((by - 1) * linesize + bx) * 4 + 2, hy, linesize * 4)] +
+ odst[vflip((by * linesize + bx - 1 - z) * 4 + 2, hy, linesize * 4)] -
+ odst[vflip(((by - 1) * linesize + bx - 1 - z) * 4 + 2, hy, linesize * 4)];
clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF);
- dst[by * linesize + bx] = clr;
+ dst[vflip(by * linesize + bx, hy, linesize)] = clr;
bx++;
if (bx >= x * 16 + sx2 || bx >= avctx->width) {
bx = x * 16 + sx1;
@@ -707,8 +717,8 @@ static int decompress_p(AVCodecContext *avctx,
z = 0;
}
- clr = dst[(by - 1) * linesize + bx - 1 - z];
- dst[by * linesize + bx] = clr;
+ clr = dst[vflip((by - 1) * linesize + bx - 1 - z, hy, linesize)];
+ dst[vflip(by * linesize + bx, hy, linesize)] = clr;
bx++;
if (bx >= x * 16 + sx2 || bx >= avctx->width) {
bx = x * 16 + sx1;
@@ -830,9 +840,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
FFSWAP(AVFrame *, s->current_frame, s->last_frame);
- frame->data[0] += frame->linesize[0] * (avctx->height - 1);
- frame->linesize[0] *= -1;
-
*got_frame = 1;
return avpkt->size;
--
2.9.3
More information about the ffmpeg-devel
mailing list