X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fjpeg2000dec.c;h=8f38c1d784acb55cb317b6d827504c98bb6cbc10;hb=0416b5e0330c5eb226f92cf6c150eb6b7daa8b92;hp=940fac3cd1ee55d5d2a89eb2cf73334c4d48e3ac;hpb=5b2f9790e6eb8440b6ff470cc4b43b155726884b;p=ffmpeg diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 940fac3cd1e..8f38c1d784a 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -60,7 +60,7 @@ typedef struct Jpeg2000Tile { uint8_t properties[4]; Jpeg2000CodingStyle codsty[4]; Jpeg2000QuantStyle qntsty[4]; - Jpeg2000TilePart tile_part[6]; + Jpeg2000TilePart tile_part[256]; uint16_t tp_idx; // Tile-part index } Jpeg2000Tile; @@ -133,8 +133,10 @@ static int tag_tree_decode(Jpeg2000DecoderContext *s, Jpeg2000TgtNode *node, Jpeg2000TgtNode *stack[30]; int sp = -1, curval = 0; - if (!node) + if (!node) { + av_log(s->avctx, AV_LOG_ERROR, "missing node\n"); return AVERROR_INVALIDDATA; + } while (node && !node->vis) { stack[++sp] = node; @@ -237,8 +239,10 @@ static int get_siz(Jpeg2000DecoderContext *s) const enum AVPixelFormat *possible_fmts = NULL; int possible_fmts_nb = 0; - if (bytestream2_get_bytes_left(&s->g) < 36) + if (bytestream2_get_bytes_left(&s->g) < 36) { + av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for SIZ\n"); return AVERROR_INVALIDDATA; + } s->avctx->profile = bytestream2_get_be16u(&s->g); // Rsiz s->width = bytestream2_get_be32u(&s->g); // Width @@ -276,8 +280,10 @@ static int get_siz(Jpeg2000DecoderContext *s) return AVERROR_INVALIDDATA; } - if (bytestream2_get_bytes_left(&s->g) < 3 * s->ncomponents) + if (bytestream2_get_bytes_left(&s->g) < 3 * s->ncomponents) { + av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for %d components in SIZ\n", s->ncomponents); return AVERROR_INVALIDDATA; + } for (i = 0; i < s->ncomponents; i++) { // Ssiz_i XRsiz_i, YRsiz_i uint8_t x = bytestream2_get_byteu(&s->g); @@ -352,16 +358,41 @@ static int get_siz(Jpeg2000DecoderContext *s) break; } } + + if (i == possible_fmts_nb) { + if (ncomponents == 4 && + s->cdy[0] == 1 && s->cdx[0] == 1 && + s->cdy[1] == 1 && s->cdx[1] == 1 && + s->cdy[2] == s->cdy[3] && s->cdx[2] == s->cdx[3]) { + if (s->precision == 8 && s->cdy[2] == 2 && s->cdx[2] == 2 && !s->pal8) { + s->avctx->pix_fmt = AV_PIX_FMT_YUVA420P; + s->cdef[0] = 0; + s->cdef[1] = 1; + s->cdef[2] = 2; + s->cdef[3] = 3; + i = 0; + } + } + } + + if (i == possible_fmts_nb) { av_log(s->avctx, AV_LOG_ERROR, "Unknown pix_fmt, profile: %d, colour_space: %d, " - "components: %d, precision: %d, " - "cdx[1]: %d, cdy[1]: %d, cdx[2]: %d, cdy[2]: %d\n", + "components: %d, precision: %d\n" + "cdx[0]: %d, cdy[0]: %d\n" + "cdx[1]: %d, cdy[1]: %d\n" + "cdx[2]: %d, cdy[2]: %d\n" + "cdx[3]: %d, cdy[3]: %d\n", s->avctx->profile, s->colour_space, ncomponents, s->precision, - ncomponents > 2 ? s->cdx[1] : 0, - ncomponents > 2 ? s->cdy[1] : 0, + s->cdx[0], + s->cdy[0], + ncomponents > 1 ? s->cdx[1] : 0, + ncomponents > 1 ? s->cdy[1] : 0, ncomponents > 2 ? s->cdx[2] : 0, - ncomponents > 2 ? s->cdy[2] : 0); + ncomponents > 2 ? s->cdy[2] : 0, + ncomponents > 3 ? s->cdx[3] : 0, + ncomponents > 3 ? s->cdy[3] : 0); return AVERROR_PATCHWELCOME; } s->avctx->bits_per_raw_sample = s->precision; @@ -373,8 +404,10 @@ static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c) { uint8_t byte; - if (bytestream2_get_bytes_left(&s->g) < 5) + if (bytestream2_get_bytes_left(&s->g) < 5) { + av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for COX\n"); return AVERROR_INVALIDDATA; + } /* nreslevels = number of resolution levels = number of decomposition level +1 */ @@ -443,8 +476,10 @@ static int get_cod(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c, Jpeg2000CodingStyle tmp; int compno, ret; - if (bytestream2_get_bytes_left(&s->g) < 5) + if (bytestream2_get_bytes_left(&s->g) < 5) { + av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for COD\n"); return AVERROR_INVALIDDATA; + } tmp.csty = bytestream2_get_byteu(&s->g); @@ -477,8 +512,10 @@ static int get_coc(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c, { int compno, ret; - if (bytestream2_get_bytes_left(&s->g) < 2) + if (bytestream2_get_bytes_left(&s->g) < 2) { + av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for COC\n"); return AVERROR_INVALIDDATA; + } compno = bytestream2_get_byteu(&s->g); @@ -590,7 +627,7 @@ static int get_sot(Jpeg2000DecoderContext *s, int n) Jpeg2000TilePart *tp; uint16_t Isot; uint32_t Psot; - uint8_t TPsot; + unsigned TPsot; if (bytestream2_get_bytes_left(&s->g) < 8) return AVERROR_INVALIDDATA; @@ -615,10 +652,7 @@ static int get_sot(Jpeg2000DecoderContext *s, int n) return AVERROR_INVALIDDATA; } - if (TPsot >= FF_ARRAY_ELEMS(s->tile[Isot].tile_part)) { - avpriv_request_sample(s->avctx, "Support for %"PRIu8" components", TPsot); - return AVERROR_PATCHWELCOME; - } + av_assert0(TPsot < FF_ARRAY_ELEMS(s->tile[Isot].tile_part)); s->tile[Isot].tp_idx = TPsot; tp = s->tile[Isot].tile_part + TPsot; @@ -682,7 +716,7 @@ static uint8_t get_plt(Jpeg2000DecoderContext *s, int n) { int i; - av_log(s->avctx, AV_LOG_ERROR, + av_log(s->avctx, AV_LOG_DEBUG, "PLT marker at pos 0x%X\n", bytestream2_tell(&s->g) - 4); /*Zplt =*/ bytestream2_get_byte(&s->g); @@ -775,6 +809,9 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, } } + if (bytestream2_peek_be32(&s->g) == JPEG2000_SOP_FIXED_BYTES) + bytestream2_skip(&s->g, JPEG2000_SOP_BYTE_LENGTH); + if (!(ret = get_bits(s, 1))) { jpeg2000_flush(s); return 0; @@ -878,8 +915,8 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, || sizeof(cblk->data) < cblk->length + cblk->lengthinc[cwsno] + 4 ) { av_log(s->avctx, AV_LOG_ERROR, - "Block length %"PRIu16" or lengthinc %d is too large\n", - cblk->length, cblk->lengthinc[cwsno]); + "Block length %"PRIu16" or lengthinc %d is too large, left %d\n", + cblk->length, cblk->lengthinc[cwsno], bytestream2_get_bytes_left(&s->g)); return AVERROR_INVALIDDATA; } @@ -905,6 +942,7 @@ static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile int layno, reslevelno, compno, precno, ok_reslevel; int x, y; int tp_index = 0; + int step_x, step_y; s->bit_index = 8; switch (tile->codsty[0].prog_order) { @@ -935,6 +973,7 @@ static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile break; case JPEG2000_PGOD_LRCP: + av_log(s->avctx, AV_LOG_DEBUG, "Progression order LRCP\n"); for (layno = 0; layno < tile->codsty[0].nlayers; layno++) { ok_reslevel = 1; for (reslevelno = 0; ok_reslevel; reslevelno++) { @@ -960,34 +999,49 @@ static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile break; case JPEG2000_PGOD_CPRL: + av_log(s->avctx, AV_LOG_DEBUG, "Progression order CPRL\n"); for (compno = 0; compno < s->ncomponents; compno++) { + Jpeg2000Component *comp = tile->comp + compno; Jpeg2000CodingStyle *codsty = tile->codsty + compno; Jpeg2000QuantStyle *qntsty = tile->qntsty + compno; + int maxlogstep_x = 0; + int maxlogstep_y = 0; + int start_x, start_y; + step_x = 32; + step_y = 32; + + for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) { + uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r + Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; + step_x = FFMIN(step_x, rlevel->log2_prec_width + reducedresno); + step_y = FFMIN(step_y, rlevel->log2_prec_height + reducedresno); + maxlogstep_x = FFMAX(maxlogstep_x, rlevel->log2_prec_width + reducedresno); + maxlogstep_y = FFMAX(maxlogstep_y, rlevel->log2_prec_height + reducedresno); + } + step_x = 1<height; y += 256) { - /* Position loop (y axis) - * TODO: automate computing of step 256. - * Fixed here, but to be computed before entering here. */ - for (x = 0; x < s->width; x += 256) { + start_y = comp->coord_o[1][0] >> maxlogstep_y << maxlogstep_y; + start_x = comp->coord_o[0][0] >> maxlogstep_x << maxlogstep_x; + for (y = start_y; y < comp->coord_o[1][1]; y += step_y) { + for (x = start_x; x < comp->coord_o[0][1]; x += step_x) { for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) { - uint16_t prcx, prcy; + unsigned prcx, prcy; uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r - Jpeg2000ResLevel *rlevel = tile->comp[compno].reslevel + reslevelno; + Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; - if (!((y % (1 << (rlevel->log2_prec_height + reducedresno)) == 0) || - (y == 0))) // TODO: 2nd condition simplified as try0 always =0 for dcinema + if (y % (1 << (rlevel->log2_prec_height + reducedresno))) continue; - if (!((x % (1 << (rlevel->log2_prec_width + reducedresno)) == 0) || - (x == 0))) // TODO: 2nd condition simplified as try0 always =0 for dcinema + if (x % (1 << (rlevel->log2_prec_width + reducedresno))) continue; // check if a precinct exists prcx = ff_jpeg2000_ceildivpow2(x, reducedresno) >> rlevel->log2_prec_width; prcy = ff_jpeg2000_ceildivpow2(y, reducedresno) >> rlevel->log2_prec_height; + prcx -= ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], reducedresno) >> rlevel->log2_prec_width; + prcy -= ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], reducedresno) >> rlevel->log2_prec_height; + precno = prcx + rlevel->num_precincts_x * prcy; if (prcx >= rlevel->num_precincts_x || prcy >= rlevel->num_precincts_y) { @@ -1010,13 +1064,144 @@ static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile break; case JPEG2000_PGOD_RPCL: - avpriv_request_sample(s->avctx, "Progression order RPCL"); - ret = AVERROR_PATCHWELCOME; + av_log(s->avctx, AV_LOG_WARNING, "Progression order RPCL\n"); + ok_reslevel = 1; + for (reslevelno = 0; ok_reslevel; reslevelno++) { + ok_reslevel = 0; + + step_x = 32; + step_y = 32; + for (compno = 0; compno < s->ncomponents; compno++) { + Jpeg2000Component *comp = tile->comp + compno; + Jpeg2000CodingStyle *codsty = tile->codsty + compno; + + if (reslevelno < codsty->nreslevels) { + uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r + Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; + step_x = FFMIN(step_x, rlevel->log2_prec_width + reducedresno); + step_y = FFMIN(step_y, rlevel->log2_prec_height + reducedresno); + } + } + step_x = 1<height; y += step_y) { + for (x = 0; x < s->width; x += step_x) { + for (compno = 0; compno < s->ncomponents; compno++) { + Jpeg2000Component *comp = tile->comp + compno; + Jpeg2000CodingStyle *codsty = tile->codsty + compno; + Jpeg2000QuantStyle *qntsty = tile->qntsty + compno; + uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r + Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; + unsigned prcx, prcy; + + int xc = x / s->cdx[compno]; + int yc = y / s->cdy[compno]; + + if (reslevelno >= codsty->nreslevels) + continue; + + if (yc % (1 << (rlevel->log2_prec_height + reducedresno))) + continue; + + if (xc % (1 << (rlevel->log2_prec_width + reducedresno))) + continue; + + // check if a precinct exists + prcx = ff_jpeg2000_ceildivpow2(xc, reducedresno) >> rlevel->log2_prec_width; + prcy = ff_jpeg2000_ceildivpow2(yc, reducedresno) >> rlevel->log2_prec_height; + prcx -= ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], reducedresno) >> rlevel->log2_prec_width; + prcy -= ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], reducedresno) >> rlevel->log2_prec_height; + + precno = prcx + rlevel->num_precincts_x * prcy; + + ok_reslevel = 1; + if (prcx >= rlevel->num_precincts_x || prcy >= rlevel->num_precincts_y) { + av_log(s->avctx, AV_LOG_WARNING, "prc %d %d outside limits %d %d\n", + prcx, prcy, rlevel->num_precincts_x, rlevel->num_precincts_y); + continue; + } + + for (layno = 0; layno < tile->codsty[0].nlayers; layno++) { + if ((ret = jpeg2000_decode_packet(s, tile, &tp_index, + codsty, rlevel, + precno, layno, + qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0), + qntsty->nguardbits)) < 0) + return ret; + } + } + } + } + } break; case JPEG2000_PGOD_PCRL: - avpriv_request_sample(s->avctx, "Progression order PCRL"); - ret = AVERROR_PATCHWELCOME; + av_log(s->avctx, AV_LOG_WARNING, "Progression order PCRL"); + step_x = 32; + step_y = 32; + for (compno = 0; compno < s->ncomponents; compno++) { + Jpeg2000Component *comp = tile->comp + compno; + Jpeg2000CodingStyle *codsty = tile->codsty + compno; + Jpeg2000QuantStyle *qntsty = tile->qntsty + compno; + + for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) { + uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r + Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; + step_x = FFMIN(step_x, rlevel->log2_prec_width + reducedresno); + step_y = FFMIN(step_y, rlevel->log2_prec_height + reducedresno); + } + } + step_x = 1<height; y += step_y) { + for (x = 0; x < s->width; x += step_x) { + for (compno = 0; compno < s->ncomponents; compno++) { + Jpeg2000Component *comp = tile->comp + compno; + Jpeg2000CodingStyle *codsty = tile->codsty + compno; + Jpeg2000QuantStyle *qntsty = tile->qntsty + compno; + int xc = x / s->cdx[compno]; + int yc = y / s->cdy[compno]; + + for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) { + unsigned prcx, prcy; + uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r + Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; + + if (yc % (1 << (rlevel->log2_prec_height + reducedresno))) + continue; + + if (xc % (1 << (rlevel->log2_prec_width + reducedresno))) + continue; + + // check if a precinct exists + prcx = ff_jpeg2000_ceildivpow2(xc, reducedresno) >> rlevel->log2_prec_width; + prcy = ff_jpeg2000_ceildivpow2(yc, reducedresno) >> rlevel->log2_prec_height; + prcx -= ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], reducedresno) >> rlevel->log2_prec_width; + prcy -= ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], reducedresno) >> rlevel->log2_prec_height; + + precno = prcx + rlevel->num_precincts_x * prcy; + + if (prcx >= rlevel->num_precincts_x || prcy >= rlevel->num_precincts_y) { + av_log(s->avctx, AV_LOG_WARNING, "prc %d %d outside limits %d %d\n", + prcx, prcy, rlevel->num_precincts_x, rlevel->num_precincts_y); + continue; + } + + for (layno = 0; layno < tile->codsty[0].nlayers; layno++) { + if ((ret = jpeg2000_decode_packet(s, tile, &tp_index, codsty, rlevel, + precno, layno, + qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0), + qntsty->nguardbits)) < 0) + return ret; + } + } + } + } + } break; default: @@ -1039,13 +1224,13 @@ static void decode_sigpass(Jpeg2000T1Context *t1, int width, int height, for (y0 = 0; y0 < height; y0 += 4) for (x = 0; x < width; x++) for (y = y0; y < height && y < y0 + 4; y++) { - if ((t1->flags[y+1][x+1] & JPEG2000_T1_SIG_NB) + int flags_mask = -1; + if (vert_causal_ctx_csty_symbol && y == y0 + 3) + flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE | JPEG2000_T1_SGN_S); + if ((t1->flags[y+1][x+1] & JPEG2000_T1_SIG_NB & flags_mask) && !(t1->flags[y+1][x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))) { - int flags_mask = -1; - if (vert_causal_ctx_csty_symbol && y == y0 + 3) - flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE); if (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_jpeg2000_getsigctxno(t1->flags[y+1][x+1] & flags_mask, bandno))) { - int xorbit, ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y+1][x+1], &xorbit); + int xorbit, ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y+1][x+1] & flags_mask, &xorbit); if (t1->mqc.raw) t1->data[y][x] = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ? -mask : mask; else @@ -1061,7 +1246,7 @@ static void decode_sigpass(Jpeg2000T1Context *t1, int width, int height, } static void decode_refpass(Jpeg2000T1Context *t1, int width, int height, - int bpno) + int bpno, int vert_causal_ctx_csty_symbol) { int phalf, nhalf; int y0, x, y; @@ -1073,7 +1258,9 @@ static void decode_refpass(Jpeg2000T1Context *t1, int width, int height, for (x = 0; x < width; x++) for (y = y0; y < height && y < y0 + 4; y++) if ((t1->flags[y + 1][x + 1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS)) == JPEG2000_T1_SIG) { - int ctxno = ff_jpeg2000_getrefctxno(t1->flags[y + 1][x + 1]); + int flags_mask = (vert_causal_ctx_csty_symbol && y == y0 + 3) ? + ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE | JPEG2000_T1_SGN_S) : -1; + int ctxno = ff_jpeg2000_getrefctxno(t1->flags[y + 1][x + 1] & flags_mask); int r = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ? phalf : nhalf; @@ -1090,11 +1277,14 @@ static void decode_clnpass(Jpeg2000DecoderContext *s, Jpeg2000T1Context *t1, for (y0 = 0; y0 < height; y0 += 4) { for (x = 0; x < width; x++) { + int flags_mask = -1; + if (vert_causal_ctx_csty_symbol) + flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE | JPEG2000_T1_SGN_S); if (y0 + 3 < height && !((t1->flags[y0 + 1][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) || (t1->flags[y0 + 2][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) || (t1->flags[y0 + 3][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) || - (t1->flags[y0 + 4][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)))) { + (t1->flags[y0 + 4][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG) & flags_mask))) { if (!ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_RL)) continue; runlen = ff_mqc_decode(&t1->mqc, @@ -1109,18 +1299,18 @@ static void decode_clnpass(Jpeg2000DecoderContext *s, Jpeg2000T1Context *t1, } for (y = y0 + runlen; y < y0 + 4 && y < height; y++) { + int flags_mask = -1; + if (vert_causal_ctx_csty_symbol && y == y0 + 3) + flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE | JPEG2000_T1_SGN_S); if (!dec) { if (!(t1->flags[y+1][x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))) { - int flags_mask = -1; - if (vert_causal_ctx_csty_symbol && y == y0 + 3) - flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE); dec = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_jpeg2000_getsigctxno(t1->flags[y+1][x+1] & flags_mask, bandno)); } } if (dec) { int xorbit; - int ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y + 1][x + 1], + int ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y + 1][x + 1] & flags_mask, &xorbit); t1->data[y][x] = (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ^ @@ -1179,7 +1369,7 @@ static int decode_cblk(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty, vert_causal_ctx_csty_symbol); break; case 1: - decode_refpass(t1, width, height, bpno + 1); + decode_refpass(t1, width, height, bpno + 1, vert_causal_ctx_csty_symbol); break; case 2: av_assert2(!t1->mqc.raw); @@ -1188,7 +1378,10 @@ static int decode_cblk(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty, vert_causal_ctx_csty_symbol); break; } - if ((coder_type = needs_termination(codsty->cblk_style, pass_cnt))) { + if (codsty->cblk_style & JPEG2000_CBLK_RESET) // XXX no testcase for just this + ff_mqc_init_contexts(&t1->mqc); + + if (passno && (coder_type = needs_termination(codsty->cblk_style, pass_cnt))) { if (term_cnt >= cblk->nb_terminations) { av_log(s->avctx, AV_LOG_ERROR, "Missing needed termination \n"); return AVERROR_INVALIDDATA; @@ -1203,6 +1396,12 @@ static int decode_cblk(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty, } pass_cnt ++; } + + if (cblk->data + cblk->length - 2*(term_cnt < cblk->nb_terminations) != t1->mqc.bp) { + av_log(s->avctx, AV_LOG_WARNING, "End mismatch %"PTRDIFF_SPECIFIER"\n", + cblk->data + cblk->length - 2*(term_cnt < cblk->nb_terminations) - t1->mqc.bp); + } + return 0; } @@ -1330,8 +1529,8 @@ static int jpeg2000_decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, cblk->coord[1][1] - cblk->coord[1][0], bandpos); - x = cblk->coord[0][0]; - y = cblk->coord[1][0]; + x = cblk->coord[0][0] - band->coord[0][0]; + y = cblk->coord[1][0] - band->coord[1][0]; if (codsty->transform == FF_DWT97) dequantization_float(x, y, cblk, comp, &t1, band); @@ -1525,8 +1724,10 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s) break; len = bytestream2_get_be16(&s->g); - if (len < 2 || bytestream2_get_bytes_left(&s->g) < len - 2) + if (len < 2 || bytestream2_get_bytes_left(&s->g) < len - 2) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid len %d left=%d\n", len, bytestream2_get_bytes_left(&s->g)); return AVERROR_INVALIDDATA; + } switch (marker) { case JPEG2000_SIZ: @@ -1592,11 +1793,11 @@ static int jpeg2000_read_bitstream_packets(Jpeg2000DecoderContext *s) for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++) { Jpeg2000Tile *tile = s->tile + tileno; - if (ret = init_tile(s, tileno)) + if ((ret = init_tile(s, tileno)) < 0) return ret; s->g = tile->tile_part[0].tpg; - if (ret = jpeg2000_decode_packets(s, tile)) + if ((ret = jpeg2000_decode_packets(s, tile)) < 0) return ret; }