diff options
author | Paul B Mahol <onemda@gmail.com> | 2022-12-02 09:00:55 +0100 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2022-12-03 20:11:43 +0100 |
commit | 0c6e40c17497f74a5a8e8df4aa71515135153e1b (patch) | |
tree | 62910e1f587e70402570574c29433d6fa84321df | |
parent | 1ba4f3c8668502957e15496fc8950f259da365ae (diff) | |
download | ffmpeg-0c6e40c17497f74a5a8e8df4aa71515135153e1b.tar.gz |
avcodec/cfhdenc: stop crashing on heights not multiple of 8
Fixes overreads and artifacts for some heights not multiple of 16.
-rw-r--r-- | libavcodec/cfhdenc.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/libavcodec/cfhdenc.c b/libavcodec/cfhdenc.c index 6003c83237..29fb56f25a 100644 --- a/libavcodec/cfhdenc.c +++ b/libavcodec/cfhdenc.c @@ -272,22 +272,21 @@ static av_cold int cfhd_encode_init(AVCodecContext *avctx) for (int i = 0; i < s->planes; i++) { int w8, h8, w4, h4, w2, h2; - int width = i ? avctx->width >> s->chroma_h_shift : avctx->width; - int height = i ? FFALIGN(avctx->height >> s->chroma_v_shift, 8) : - FFALIGN(avctx->height >> s->chroma_v_shift, 8); - ptrdiff_t stride = (FFALIGN(width / 8, 8) + 64) * 8; + const int a_height = FFALIGN(avctx->height, 8); + int width = i ? AV_CEIL_RSHIFT(avctx->width, s->chroma_h_shift) : avctx->width; + int height = i ? a_height >> s->chroma_v_shift: a_height; - w8 = FFALIGN(width / 8, 8) + 64; - h8 = FFALIGN(height, 8) / 8; + w8 = width / 8 + 64; + h8 = height / 8; w4 = w8 * 2; h4 = h8 * 2; w2 = w4 * 2; h2 = h4 * 2; s->plane[i].dwt_buf = - av_calloc(height * stride, sizeof(*s->plane[i].dwt_buf)); + av_calloc(h8 * 8 * w8 * 8, sizeof(*s->plane[i].dwt_buf)); s->plane[i].dwt_tmp = - av_malloc_array(height * stride, sizeof(*s->plane[i].dwt_tmp)); + av_malloc_array(h8 * 8 * w8 * 8, sizeof(*s->plane[i].dwt_tmp)); if (!s->plane[i].dwt_buf || !s->plane[i].dwt_tmp) return AVERROR(ENOMEM); @@ -305,7 +304,7 @@ static av_cold int cfhd_encode_init(AVCodecContext *avctx) for (int j = 0; j < DWT_LEVELS; j++) { for (int k = 0; k < FF_ARRAY_ELEMS(s->plane[i].band[j]); k++) { s->plane[i].band[j][k].width = (width / 8) << j; - s->plane[i].band[j][k].height = (height / 8) << j; + s->plane[i].band[j][k].height = height >> (DWT_LEVELS - j); s->plane[i].band[j][k].a_width = w8 << j; s->plane[i].band[j][k].a_height = h8 << j; } @@ -438,6 +437,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, int ret; for (int plane = 0; plane < s->planes; plane++) { + const int h_shift = plane ? s->chroma_h_shift : 0; int width = s->plane[plane].band[2][0].width; int a_width = s->plane[plane].band[2][0].a_width; int height = s->plane[plane].band[2][0].height; @@ -458,7 +458,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, dsp->horiz_filter(input, low, high, in_stride, a_width, a_width, - width * 2, height * 2); + avctx->width >> h_shift, avctx->height); input = s->plane[plane].l_h[7]; low = s->plane[plane].subband[7]; @@ -596,6 +596,9 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, bytestream2_put_be16(pby, avctx->width); bytestream2_put_be16(pby, ImageHeight); + bytestream2_put_be16(pby, FFALIGN(avctx->height, 8)); + + bytestream2_put_be16(pby, -DisplayHeight); bytestream2_put_be16(pby, avctx->height); bytestream2_put_be16(pby, -FrameNumber); |