diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-07-03 13:00:57 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-07-03 13:07:45 +0200 |
commit | 7c71ef4f1727e6a59b7266ef04be1076b6363b61 (patch) | |
tree | 88be960832b039edfa307d09f1d5779d87ecc934 | |
parent | ffed7227c3313fa8d1ac2b6e36d4867348437508 (diff) | |
parent | 57bc64e235fde80c8e543a6e7f9b4439c36633bb (diff) | |
download | ffmpeg-7c71ef4f1727e6a59b7266ef04be1076b6363b61.tar.gz |
Merge commit '57bc64e'
* commit '57bc64e':
jpeg2000: Use bytestream2
jpeg2000: Clean up return paths and error messages
jpeg2000: Define the maximum decomposition levels
jpeg2000: Check code-block size
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/jpeg2000.h | 8 | ||||
-rw-r--r-- | libavcodec/jpeg2000dec.c | 94 |
2 files changed, 56 insertions, 46 deletions
diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h index 2ef29239a9..acdba62a07 100644 --- a/libavcodec/jpeg2000.h +++ b/libavcodec/jpeg2000.h @@ -67,7 +67,9 @@ enum Jpeg2000Quantsty { // quantization style #define JPEG2000_MAX_CBLKW 64 #define JPEG2000_MAX_CBLKH 64 -#define JPEG2000_MAX_RESLEVELS 33 + +#define JPEG2000_MAX_DECLEVELS 32 +#define JPEG2000_MAX_RESLEVELS (JPEG2000_MAX_DECLEVELS + 1) // T1 flags // flags determining significance of neighbor coefficients @@ -143,8 +145,8 @@ typedef struct Jpeg2000CodingStyle { } Jpeg2000CodingStyle; typedef struct Jpeg2000QuantStyle { - uint8_t expn[32 * 3]; // quantization exponent - uint16_t mant[32 * 3]; // quantization mantissa + uint8_t expn[JPEG2000_MAX_DECLEVELS * 3]; // quantization exponent + uint16_t mant[JPEG2000_MAX_DECLEVELS * 3]; // quantization mantissa uint8_t quantsty; // quantization style uint8_t nguardbits; // number of guard bits } Jpeg2000QuantStyle; diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 043ec03a2e..da0bd9cede 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -163,7 +163,7 @@ static int get_siz(Jpeg2000DecoderContext *s) int ncomponents; if (bytestream2_get_bytes_left(&s->g) < 36) - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; s->avctx->profile = bytestream2_get_be16u(&s->g); // Rsiz s->width = bytestream2_get_be32u(&s->g); // Width @@ -178,18 +178,18 @@ static int get_siz(Jpeg2000DecoderContext *s) if (ncomponents <= 0 || ncomponents > 4) { av_log(s->avctx, AV_LOG_ERROR, "unsupported/invalid ncomponents: %d\n", ncomponents); - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; } s->ncomponents = ncomponents; if (s->tile_width<=0 || s->tile_height<=0) - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; if (bytestream2_get_bytes_left(&s->g) < 3 * s->ncomponents) - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; for (i = 0; i < s->ncomponents; i++) { // Ssiz_i XRsiz_i, YRsiz_i - uint8_t x = bytestream2_get_byteu(&s->g); + uint8_t x = bytestream2_get_byteu(&s->g); s->cbps[i] = (x & 0x7f) + 1; s->precision = FFMAX(s->cbps[i], s->precision); s->sgnd[i] = !!(x & 0x80); @@ -265,7 +265,8 @@ static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c) uint8_t byte; if (bytestream2_get_bytes_left(&s->g) < 5) - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; + /* nreslevels = number of resolution levels = number of decomposition level +1 */ c->nreslevels = bytestream2_get_byteu(&s->g) + 1; @@ -284,7 +285,7 @@ static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c) c->log2_cblk_height = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk height if (c->log2_cblk_width > 10 || c->log2_cblk_height > 10 || - c->log2_cblk_width + c->log2_cblk_height > 14) { + c->log2_cblk_width + c->log2_cblk_height > 12) { av_log(s->avctx, AV_LOG_ERROR, "cblk size invalid\n"); return AVERROR_INVALIDDATA; } @@ -320,15 +321,15 @@ static int get_cod(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c, int compno, ret; if (bytestream2_get_bytes_left(&s->g) < 5) - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; tmp.csty = bytestream2_get_byteu(&s->g); // get progression order tmp.prog_order = bytestream2_get_byteu(&s->g); - tmp.nlayers = bytestream2_get_be16u(&s->g); - tmp.mct = bytestream2_get_byteu(&s->g); // multiple component transformation + tmp.nlayers = bytestream2_get_be16u(&s->g); + tmp.mct = bytestream2_get_byteu(&s->g); // multiple component transformation if (tmp.mct && s->ncomponents < 3) { av_log(s->avctx, AV_LOG_ERROR, "MCT %d with too few components (%d)\n", tmp.mct, s->ncomponents); @@ -352,7 +353,7 @@ static int get_coc(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c, int compno, ret; if (bytestream2_get_bytes_left(&s->g) < 2) - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; compno = bytestream2_get_byteu(&s->g); @@ -377,7 +378,7 @@ static int get_qcx(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q) int i, x; if (bytestream2_get_bytes_left(&s->g) < 1) - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; x = bytestream2_get_byteu(&s->g); // Sqcd @@ -386,25 +387,27 @@ static int get_qcx(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q) if (q->quantsty == JPEG2000_QSTY_NONE) { n -= 3; - if (bytestream2_get_bytes_left(&s->g) < n || 32*3 < n) - return AVERROR(EINVAL); + if (bytestream2_get_bytes_left(&s->g) < n || + n > JPEG2000_MAX_DECLEVELS*3) + return AVERROR_INVALIDDATA; for (i = 0; i < n; i++) q->expn[i] = bytestream2_get_byteu(&s->g) >> 3; } else if (q->quantsty == JPEG2000_QSTY_SI) { if (bytestream2_get_bytes_left(&s->g) < 2) - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; x = bytestream2_get_be16u(&s->g); q->expn[0] = x >> 11; q->mant[0] = x & 0x7ff; - for (i = 1; i < 32 * 3; i++) { + for (i = 1; i < JPEG2000_MAX_DECLEVELS * 3; i++) { int curexpn = FFMAX(0, q->expn[0] - (i - 1) / 3); q->expn[i] = curexpn; q->mant[i] = q->mant[0]; } } else { n = (n - 3) >> 1; - if (bytestream2_get_bytes_left(&s->g) < 2 * n || 32*3 < n) - return AVERROR(EINVAL); + if (bytestream2_get_bytes_left(&s->g) < 2 * n || + n > JPEG2000_MAX_DECLEVELS*3) + return AVERROR_INVALIDDATA; for (i = 0; i < n; i++) { x = bytestream2_get_be16u(&s->g); q->expn[i] = x >> 11; @@ -419,10 +422,10 @@ static int get_qcd(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q, uint8_t *properties) { Jpeg2000QuantStyle tmp; - int compno; + int compno, ret; - if (get_qcx(s, n, &tmp)) - return -1; + if ((ret = get_qcx(s, n, &tmp)) < 0) + return ret; for (compno = 0; compno < s->ncomponents; compno++) if (!(properties[compno] & HAD_QCC)) memcpy(q + compno, &tmp, sizeof(tmp)); @@ -437,7 +440,7 @@ static int get_qcc(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q, int compno; if (bytestream2_get_bytes_left(&s->g) < 1) - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; compno = bytestream2_get_byteu(&s->g); if (compno >= s->ncomponents) { @@ -458,12 +461,12 @@ static int get_sot(Jpeg2000DecoderContext *s, int n) uint8_t TPsot; if (bytestream2_get_bytes_left(&s->g) < 8) - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; s->curtileno = Isot = bytestream2_get_be16u(&s->g); // Isot if ((unsigned)s->curtileno >= s->numXtiles * s->numYtiles) { s->curtileno=0; - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; } Psot = bytestream2_get_be32u(&s->g); // Psot TPsot = bytestream2_get_byteu(&s->g); // TPsot @@ -675,7 +678,7 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, if ( bytestream2_get_bytes_left(&s->g) < cblk->lengthinc || sizeof(cblk->data) < cblk->length + cblk->lengthinc + 2 ) - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; bytestream2_get_bufferu(&s->g, cblk->data + cblk->length, cblk->lengthinc); cblk->length += cblk->lengthinc; @@ -687,7 +690,7 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile) { - int layno, reslevelno, compno, precno, ok_reslevel; + int layno, reslevelno, compno, precno, ok_reslevel, ret; int x, y; s->bit_index = 8; @@ -706,12 +709,12 @@ static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile reslevelno; ok_reslevel = 1; for (precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++) - if (jpeg2000_decode_packet(s, - codsty, rlevel, - precno, layno, - qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0), - qntsty->nguardbits)) - return -1; + if ((ret = jpeg2000_decode_packet(s, + codsty, rlevel, + precno, layno, + qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0), + qntsty->nguardbits)) < 0) + return ret; } } } @@ -754,11 +757,11 @@ static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile prcy = ff_jpeg2000_ceildivpow2(y, reducedresno) >> rlevel->log2_prec_height; precno = prcx + rlevel->num_precincts_x * prcy; for (layno = 0; layno < tile->codsty[0].nlayers; layno++) { - if (jpeg2000_decode_packet(s, codsty, rlevel, - precno, layno, - qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0), - qntsty->nguardbits)) - return -1; + if ((ret = jpeg2000_decode_packet(s, codsty, rlevel, + precno, layno, + qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0), + qntsty->nguardbits)) < 0) + return ret; } } } @@ -1253,7 +1256,7 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s) len = bytestream2_get_be16(&s->g); if (len < 2 || bytestream2_get_bytes_left(&s->g) < len - 2) - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; switch (marker) { case JPEG2000_SIZ: ret = get_siz(s); @@ -1329,7 +1332,9 @@ static int jp2_find_codestream(Jpeg2000DecoderContext *s) uint32_t atom_size, atom; int found_codestream = 0, search_range = 10; - while (!found_codestream && search_range && bytestream2_get_bytes_left(&s->g) >= 8) { + while (!found_codestream && search_range + && + bytestream2_get_bytes_left(&s->g) >= 8) { atom_size = bytestream2_get_be32u(&s->g); atom = bytestream2_get_be32u(&s->g); if (atom == JP2_CODESTREAM) { @@ -1363,7 +1368,7 @@ static int jpeg2000_decode_frame(AVCodecContext *avctx, void *data, s->reduction_factor = s->lowres; if (bytestream2_get_bytes_left(&s->g) < 2) { - ret = AVERROR(EINVAL); + ret = AVERROR_INVALIDDATA; goto end; } @@ -1374,17 +1379,19 @@ static int jpeg2000_decode_frame(AVCodecContext *avctx, void *data, (bytestream2_get_be32u(&s->g) == JP2_SIG_VALUE)) { if (!jp2_find_codestream(s)) { av_log(avctx, AV_LOG_ERROR, - "couldn't find jpeg2k codestream atom\n"); - ret = -1; + "Could not find Jpeg2000 codestream atom.\n"); + ret = AVERROR_INVALIDDATA; goto end; } } else { bytestream2_seek(&s->g, 0, SEEK_SET); + if (bytestream2_peek_be16(&s->g) != JPEG2000_SOC) + bytestream2_skip(&s->g, 8); } if (bytestream2_get_be16u(&s->g) != JPEG2000_SOC) { av_log(avctx, AV_LOG_ERROR, "SOC marker not present\n"); - ret = -1; + ret = AVERROR_INVALIDDATA; goto end; } if (ret = jpeg2000_read_main_headers(s)) @@ -1408,6 +1415,7 @@ static int jpeg2000_decode_frame(AVCodecContext *avctx, void *data, *got_frame = 1; return bytestream2_tell(&s->g); + end: jpeg2000_dec_cleanup(s); return ret; |