|
|
|
@ -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) |
|
|
|
|
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) |
|
|
|
|
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 + 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); |
|
|
|
|
|
|
|
|
|