X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fgdv.c;h=132ec7288add7709a6f065a5cdc957149244c8b4;hb=2e8b0446c6798947dac77fee4a06f9c4e8131ab5;hp=e52a637610a54067c6633d79f9a385d79e3dda04;hpb=99cc3cf7a26cd4113e5047034577027d8c6f07a2;p=ffmpeg diff --git a/libavcodec/gdv.c b/libavcodec/gdv.c index e52a637610a..132ec7288ad 100644 --- a/libavcodec/gdv.c +++ b/libavcodec/gdv.c @@ -74,53 +74,55 @@ static av_cold int gdv_decode_init(AVCodecContext *avctx) static void rescale(GDVContext *gdv, uint8_t *dst, int w, int h, int scale_v, int scale_h) { - int i, j, y, x; + int j, y, x; if ((gdv->scale_v == scale_v) && (gdv->scale_h == scale_h)) { return; } - if (gdv->scale_h && gdv->scale_v) { + if (gdv->scale_v) { for (j = 0; j < h; j++) { int y = h - j - 1; - for (i = 0; i < w; i++) { - int x = w - i - 1; - dst[PREAMBLE_SIZE + x + y * w] = dst[PREAMBLE_SIZE + x/2 + (y/2) * (w/2)]; + uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w; + uint8_t *src1 = dst + PREAMBLE_SIZE + (y>>!!gdv->scale_h) * (w>>1); + + for (x = w - 1; x >= 0 && !(x&1); x--) { + dst1[x] = src1[(x>>1)]; } - } - } else if (gdv->scale_h) { - for (j = 0; j < h; j++) { - int y = h - j - 1; - for (x = 0; x < w; x++) { - dst[PREAMBLE_SIZE + x + y * w] = dst[PREAMBLE_SIZE + x + (y/2) * w]; + + for (x--; x >= 0; x-=2) { + dst1[x ] = + dst1[x+1] = src1[(x>>1)]; } } - } else if (gdv->scale_v) { + } else if (gdv->scale_h) { for (j = 0; j < h; j++) { int y = h - j - 1; - for (i = 0; i < w; i++) { - int x = w - i - 1; - dst[PREAMBLE_SIZE + x + y * w] = dst[PREAMBLE_SIZE + x/2 + y * (w/2)]; - } + uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w; + uint8_t *src1 = dst + PREAMBLE_SIZE + (y>>1) * w; + memcpy(dst1, src1, w); } } if (scale_h && scale_v) { - for (y = 0; y < h/2; y++) { - for (x = 0; x < w/2; x++) { - dst[PREAMBLE_SIZE + x + y * (w/2)] = dst[PREAMBLE_SIZE + x*2 + y*2 * w]; + for (y = 0; y < (h>>1); y++) { + uint8_t *dst1 = dst + PREAMBLE_SIZE + y * (w>>1); + uint8_t *src1 = dst + PREAMBLE_SIZE + y*2 * w; + for (x = 0; x < (w>>1); x++) { + dst1[x] = src1[x*2]; } } } else if (scale_h) { - for (y = 0; y < h/2; y++) { - for (x = 0; x < w; x++) { - dst[PREAMBLE_SIZE + x + y * w] = dst[PREAMBLE_SIZE + x + y*2 * w]; - } + for (y = 0; y < (h>>1); y++) { + uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w; + uint8_t *src1 = dst + PREAMBLE_SIZE + y*2 * w; + memcpy(dst1, src1, w); } } else if (scale_v) { for (y = 0; y < h; y++) { - for (x = 0; x < w/2; x++) { - dst[PREAMBLE_SIZE + x + y * w] = dst[PREAMBLE_SIZE + x*2 + y * w]; + uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w; + for (x = 0; x < (w>>1); x++) { + dst1[x] = dst1[x*2]; } } } @@ -228,6 +230,10 @@ static int decompress_2(AVCodecContext *avctx) break; } } + + if (bytestream2_get_bytes_left_p(pb) > 0) + return AVERROR_INVALIDDATA; + return 0; } @@ -456,18 +462,18 @@ static int gdv_decode_frame(AVCodecContext *avctx, void *data, default: av_assert0(0); } + if (ret < 0) + return ret; memcpy(frame->data[1], gdv->pal, AVPALETTE_SIZE); dst = frame->data[0]; if (!gdv->scale_v && !gdv->scale_h) { int sidx = PREAMBLE_SIZE, didx = 0; - int y, x; + int y; for (y = 0; y < avctx->height; y++) { - for (x = 0; x < avctx->width; x++) { - dst[x+didx] = gdv->frame[x+sidx]; - } + memcpy(dst + didx, gdv->frame + sidx, avctx->width); sidx += avctx->width; didx += frame->linesize[0]; } @@ -477,12 +483,14 @@ static int gdv_decode_frame(AVCodecContext *avctx, void *data, for (y = 0; y < avctx->height; y++) { if (!gdv->scale_v) { - for (x = 0; x < avctx->width; x++) { - dst[didx + x] = gdv->frame[sidx + x]; - } + memcpy(dst + didx, gdv->frame + sidx, avctx->width); } else { - for (x = 0; x < avctx->width; x++) { - dst[didx + x] = gdv->frame[sidx + x/2]; + for (x = 0; x < avctx->width - 1; x+=2) { + dst[didx + x ] = + dst[didx + x + 1] = gdv->frame[sidx + (x>>1)]; + } + for (; x < avctx->width; x++) { + dst[didx + x] = gdv->frame[sidx + (x>>1)]; } } if (!gdv->scale_h || ((y & 1) == 1)) {