From 369422db0c6dafa08c9b22f676eb4c480bee72fb Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 27 May 2013 10:05:21 +0200 Subject: [PATCH] j2kdec: merge cblk restructuring from jpeg2000 Signed-off-by: Michael Niedermayer --- libavcodec/j2kdec.c | 97 +++++++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 42 deletions(-) diff --git a/libavcodec/j2kdec.c b/libavcodec/j2kdec.c index 219353958c..41b109a6c9 100644 --- a/libavcodec/j2kdec.c +++ b/libavcodec/j2kdec.c @@ -469,10 +469,12 @@ static int getlblockinc(Jpeg2000DecoderContext *s) return res; } -static int decode_packet(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty, Jpeg2000ResLevel *rlevel, int precno, +static int decode_packet(Jpeg2000DecoderContext *s, + Jpeg2000CodingStyle *codsty, + Jpeg2000ResLevel *rlevel, int precno, int layno, uint8_t *expn, int numgbits) { - int bandno, cblkny, cblknx, cblkno, ret; + int bandno, cblkno, ret, nb_code_blocks; if (!(ret = get_bits(s, 1))) { j2k_flush(s); @@ -483,64 +485,71 @@ static int decode_packet(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty, for (bandno = 0; bandno < rlevel->nbands; bandno++) { Jpeg2000Band *band = rlevel->band + bandno; Jpeg2000Prec *prec = band->prec + precno; - int pos = 0; if (band->coord[0][0] == band->coord[0][1] || band->coord[1][0] == band->coord[1][1]) continue; - for (cblkny = prec->yi0; cblkny < prec->yi1; cblkny++) - for (cblknx = prec->xi0, cblkno = cblkny * band->cblknx + cblknx; cblknx < prec->xi1; cblknx++, cblkno++, pos++) { - Jpeg2000Cblk *cblk = band->cblk + cblkno; - int incl, newpasses, llen; + nb_code_blocks = prec->nb_codeblocks_height * + prec->nb_codeblocks_width; + for (cblkno = 0; cblkno < nb_code_blocks; cblkno++) { + Jpeg2000Cblk *cblk = prec->cblk + cblkno; + int incl, newpasses, llen; - if (cblk->npasses) - incl = get_bits(s, 1); - else - incl = tag_tree_decode(s, prec->cblkincl + pos, layno+1) == layno; - if (!incl) - continue; - else if (incl < 0) - return incl; + if (cblk->npasses) + incl = get_bits(s, 1); + else + incl = tag_tree_decode(s, prec->cblkincl + cblkno, layno + 1) == layno; + if (!incl) + continue; + else if (incl < 0) + return incl; - if (!cblk->npasses) - cblk->nonzerobits = expn[bandno] + numgbits - 1 - tag_tree_decode(s, prec->zerobits + pos, 100); - if ((newpasses = getnpasses(s)) < 0) - return newpasses; - if ((llen = getlblockinc(s)) < 0) - return llen; - cblk->lblock += llen; - if ((ret = get_bits(s, av_log2(newpasses) + cblk->lblock)) < 0) - return ret; - cblk->lengthinc = ret; - cblk->npasses += newpasses; - } + if (!cblk->npasses) + cblk->nonzerobits = expn[bandno] + numgbits - 1 - + tag_tree_decode(s, prec->zerobits + cblkno, + 100); + if ((newpasses = getnpasses(s)) < 0) + return newpasses; + if ((llen = getlblockinc(s)) < 0) + return llen; + cblk->lblock += llen; + if ((ret = get_bits(s, av_log2(newpasses) + cblk->lblock)) < 0) + return ret; + cblk->lengthinc = ret; + cblk->npasses += newpasses; + } } j2k_flush(s); if (codsty->csty & JPEG2000_CSTY_EPH) { - if (bytestream2_peek_be16(&s->g) == JPEG2000_EPH) { + if (bytestream2_peek_be16(&s->g) == JPEG2000_EPH) bytestream2_skip(&s->g, 2); - } else { + else av_log(s->avctx, AV_LOG_ERROR, "EPH marker not found.\n"); - } } for (bandno = 0; bandno < rlevel->nbands; bandno++) { Jpeg2000Band *band = rlevel->band + bandno; - int yi, cblknw = band->prec[precno].xi1 - band->prec[precno].xi0; - for (yi = band->prec[precno].yi0; yi < band->prec[precno].yi1; yi++) { - int xi; - for (xi = band->prec[precno].xi0; xi < band->prec[precno].xi1; xi++) { - Jpeg2000Cblk *cblk = band->cblk + yi * cblknw + xi; - if ( bytestream2_get_bytes_left(&s->g) < cblk->lengthinc - || sizeof(cblk->data) < cblk->lengthinc - ) - return AVERROR(EINVAL); - bytestream2_get_bufferu(&s->g, cblk->data, cblk->lengthinc); - cblk->length += cblk->lengthinc; - cblk->lengthinc = 0; + Jpeg2000Prec *prec = band->prec + precno; + + nb_code_blocks = prec->nb_codeblocks_height * prec->nb_codeblocks_width; + for (cblkno = 0; cblkno < nb_code_blocks; cblkno++) { + Jpeg2000Cblk *cblk = prec->cblk + cblkno; + if ( bytestream2_get_bytes_left(&s->g) < cblk->lengthinc + || sizeof(cblk->data) < cblk->lengthinc + ) + return AVERROR(EINVAL); + /* Code-block data can be empty. In that case initialize data + * with 0xFFFF. */ + if (cblk->lengthinc > 0) { + bytestream2_get_bufferu(&s->g, cblk->data, cblk->lengthinc); + } else { + cblk->data[0] = 0xFF; + cblk->data[1] = 0xFF; } + cblk->length += cblk->lengthinc; + cblk->lengthinc = 0; } } return 0; @@ -767,12 +776,15 @@ static int decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile) uint8_t *line; Jpeg2000T1Context t1; + /* Loop on tile components */ for (compno = 0; compno < s->ncomponents; compno++) { Jpeg2000Component *comp = tile->comp + compno; Jpeg2000CodingStyle *codsty = tile->codsty + compno; + /* Loop on resolution levels */ for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) { Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; + /* Loop on bands */ for (bandno = 0; bandno < rlevel->nbands; bandno++) { Jpeg2000Band *band = rlevel->band + bandno; int cblkx, cblky, cblkno=0, xx0, x0, xx1, y0, yy0, yy1, bandpos; @@ -827,6 +839,7 @@ static int decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile) ff_j2k_dwt_decode(&comp->dwt, comp->data); src[compno] = comp->data; } + /* inverse MCT transformation */ if (tile->codsty[0].mct) mct_decode(s, tile);