X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Frtjpeg.c;h=4c48f25b2cde26b58e30146b40f471b82d5a9c0d;hb=ecc1f8c3c8875e31e7cb9b7d9229b1674e1be736;hp=d9ca035158b7b0f34c915b8857b8690a1118fe67;hpb=9106a698e726c041128a05db0a011caae755d10b;p=ffmpeg diff --git a/libavcodec/rtjpeg.c b/libavcodec/rtjpeg.c index d9ca035158b..4c48f25b2cd 100644 --- a/libavcodec/rtjpeg.c +++ b/libavcodec/rtjpeg.c @@ -38,6 +38,7 @@ * \param block where data is written to * \param scan array containing the mapping stream address -> block position * \param quant quantization factors + * \return 0 means the block is not coded, < 0 means an error occurred. * * Note: GetBitContext is used to make the code simpler, since all data is * aligned this could be done faster in a different way, e.g. as it is done @@ -55,6 +56,9 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *sc // number of non-zero coefficients coeff = get_bits(gb, 6); + if (get_bits_count(gb) + (coeff << 1) >= gb->size_in_bits) + return -1; + // normally we would only need to clear the (63 - coeff) last values, // but since we do not know where they are we just clear the whole block memset(block, 0, 64 * sizeof(DCTELEM)); @@ -69,6 +73,8 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *sc // 4 bits per coefficient ALIGN(4); + if (get_bits_count(gb) + (coeff << 2) >= gb->size_in_bits) + return -1; while (coeff) { ac = get_sbits(gb, 4); if (ac == -8) @@ -78,6 +84,8 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *sc // 8 bits per coefficient ALIGN(8); + if (get_bits_count(gb) + (coeff << 3) >= gb->size_in_bits) + return -1; while (coeff) { ac = get_sbits(gb, 8); PUT_COEFF(ac); @@ -98,7 +106,6 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *sc */ int rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f, const uint8_t *buf, int buf_size) { - DECLARE_ALIGNED_16(DCTELEM, block[64]); GetBitContext gb; int w = c->w / 16, h = c->h / 16; int x, y; @@ -107,22 +114,23 @@ int rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f, init_get_bits(&gb, buf, buf_size * 8); for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { - if (get_block(&gb, block, c->scan, c->lquant)) + DCTELEM *block = c->block; + if (get_block(&gb, block, c->scan, c->lquant) > 0) c->dsp->idct_put(y1, f->linesize[0], block); y1 += 8; - if (get_block(&gb, block, c->scan, c->lquant)) + if (get_block(&gb, block, c->scan, c->lquant) > 0) c->dsp->idct_put(y1, f->linesize[0], block); y1 += 8; - if (get_block(&gb, block, c->scan, c->lquant)) + if (get_block(&gb, block, c->scan, c->lquant) > 0) c->dsp->idct_put(y2, f->linesize[0], block); y2 += 8; - if (get_block(&gb, block, c->scan, c->lquant)) + if (get_block(&gb, block, c->scan, c->lquant) > 0) c->dsp->idct_put(y2, f->linesize[0], block); y2 += 8; - if (get_block(&gb, block, c->scan, c->cquant)) + if (get_block(&gb, block, c->scan, c->cquant) > 0) c->dsp->idct_put(u, f->linesize[1], block); u += 8; - if (get_block(&gb, block, c->scan, c->cquant)) + if (get_block(&gb, block, c->scan, c->cquant) > 0) c->dsp->idct_put(v, f->linesize[2], block); v += 8; }