diff options
author | Kostya Shishkov <kostya.shishkov@gmail.com> | 2013-05-18 07:06:19 +0200 |
---|---|---|
committer | Kostya Shishkov <kostya.shishkov@gmail.com> | 2013-05-21 09:58:59 +0200 |
commit | 03ece7b0404f0104b71adc9c69051689863c4e4a (patch) | |
tree | 81e26eceb33d42e58955f97c7d87ef38683fbf55 | |
parent | cfbd98abe82cfcb9984a18d08697251b72b110c8 (diff) | |
download | ffmpeg-03ece7b0404f0104b71adc9c69051689863c4e4a.tar.gz |
proresdec: simplify slice component offsets handling
-rw-r--r-- | libavcodec/proresdec.c | 54 |
1 files changed, 28 insertions, 26 deletions
diff --git a/libavcodec/proresdec.c b/libavcodec/proresdec.c index 0d1eb7ab38..c13b76969b 100644 --- a/libavcodec/proresdec.c +++ b/libavcodec/proresdec.c @@ -559,6 +559,7 @@ static int decode_slice(AVCodecContext *avctx, void *tdata) int slice_data_size, hdr_size; int y_data_size, u_data_size, v_data_size, a_data_size; int y_linesize, u_linesize, v_linesize, a_linesize; + int coff[4]; buf = ctx->slice_data[slice_num].index; slice_data_size = ctx->slice_data[slice_num + 1].index - buf; @@ -579,13 +580,19 @@ static int decode_slice(AVCodecContext *avctx, void *tdata) y_data += y_linesize; u_data += u_linesize; v_data += v_linesize; - a_data += a_linesize; + if (a_data) + a_data += a_linesize; } y_linesize <<= 1; u_linesize <<= 1; v_linesize <<= 1; a_linesize <<= 1; } + y_data += (mb_y_pos << 4) * y_linesize + (mb_x_pos << 5); + u_data += (mb_y_pos << 4) * u_linesize + (mb_x_pos << ctx->mb_chroma_factor); + v_data += (mb_y_pos << 4) * v_linesize + (mb_x_pos << ctx->mb_chroma_factor); + if (a_data) + a_data += (mb_y_pos << 4) * a_linesize + (mb_x_pos << 5); if (slice_data_size < 6) { av_log(avctx, AV_LOG_ERROR, "slice data too small\n"); @@ -594,15 +601,18 @@ static int decode_slice(AVCodecContext *avctx, void *tdata) /* parse slice header */ hdr_size = buf[0] >> 3; + coff[0] = hdr_size; y_data_size = AV_RB16(buf + 2); + coff[1] = coff[0] + y_data_size; u_data_size = AV_RB16(buf + 4); - v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) : - slice_data_size - y_data_size - u_data_size - hdr_size; - a_data_size = slice_data_size - y_data_size - u_data_size - - v_data_size - hdr_size; - - if (hdr_size + y_data_size + u_data_size + v_data_size > slice_data_size || - v_data_size < 0 || hdr_size < 6) { + coff[2] = coff[1] + u_data_size; + v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) : slice_data_size - coff[2]; + coff[3] = coff[2] + v_data_size; + a_data_size = slice_data_size - coff[3]; + + /* if V or alpha component size is negative that means that previous + component sizes are too large */ + if (v_data_size < 0 || a_data_size < 0 || hdr_size < 6) { av_log(avctx, AV_LOG_ERROR, "invalid data size\n"); return AVERROR_INVALIDDATA; } @@ -621,37 +631,29 @@ static int decode_slice(AVCodecContext *avctx, void *tdata) } /* decode luma plane */ - decode_slice_plane(ctx, td, buf + hdr_size, y_data_size, - (uint16_t*) (y_data + (mb_y_pos << 4) * y_linesize + - (mb_x_pos << 5)), y_linesize, + decode_slice_plane(ctx, td, buf + coff[0], y_data_size, + (uint16_t*) y_data, y_linesize, mbs_per_slice, 4, slice_width_factor + 2, td->qmat_luma_scaled, 0); /* decode U chroma plane */ - decode_slice_plane(ctx, td, buf + hdr_size + y_data_size, u_data_size, - (uint16_t*) (u_data + (mb_y_pos << 4) * u_linesize + - (mb_x_pos << ctx->mb_chroma_factor)), - u_linesize, mbs_per_slice, ctx->num_chroma_blocks, + decode_slice_plane(ctx, td, buf + coff[1], u_data_size, + (uint16_t*) u_data, u_linesize, + mbs_per_slice, ctx->num_chroma_blocks, slice_width_factor + ctx->chroma_factor - 1, td->qmat_chroma_scaled, 1); /* decode V chroma plane */ - decode_slice_plane(ctx, td, buf + hdr_size + y_data_size + u_data_size, - v_data_size, - (uint16_t*) (v_data + (mb_y_pos << 4) * v_linesize + - (mb_x_pos << ctx->mb_chroma_factor)), - v_linesize, mbs_per_slice, ctx->num_chroma_blocks, + decode_slice_plane(ctx, td, buf + coff[2], v_data_size, + (uint16_t*) v_data, v_linesize, + mbs_per_slice, ctx->num_chroma_blocks, slice_width_factor + ctx->chroma_factor - 1, td->qmat_chroma_scaled, 1); /* decode alpha plane if available */ if (a_data && a_data_size) - decode_alpha_plane(ctx, td, - buf + hdr_size + y_data_size + - u_data_size + v_data_size, - a_data_size, - (uint16_t*) (a_data + (mb_y_pos << 4) * a_linesize + - (mb_x_pos << 5)), a_linesize, + decode_alpha_plane(ctx, td, buf + coff[3], a_data_size, + (uint16_t*) a_data, a_linesize, mbs_per_slice); return 0; |