* markers. Parsing the TLM header is needed to increment the input header
* buffer.
* This marker is mandatory for DCI. */
-static uint8_t get_tlm(Jpeg2000DecoderContext *s, int n)
+static int get_tlm(Jpeg2000DecoderContext *s, int n)
{
uint8_t Stlm, ST, SP, tile_tlm, i;
bytestream2_get_byte(&s->g); /* Ztlm: skipped */
// too complex ? ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02);
ST = (Stlm >> 4) & 0x03;
- // TODO: Manage case of ST = 0b11 --> raise error
+ if (ST == 0x03) {
+ av_log(s->avctx, AV_LOG_ERROR, "TLM marker contains invalid ST value.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
SP = (Stlm >> 6) & 0x01;
tile_tlm = (n - 4) / ((SP + 1) * 2 + ST);
for (i = 0; i < tile_tlm; i++) {
return 0;
}
-static uint8_t get_plt(Jpeg2000DecoderContext *s, int n)
+static int get_plt(Jpeg2000DecoderContext *s, int n)
{
int i;
+ int v;
av_log(s->avctx, AV_LOG_DEBUG,
"PLT marker at pos 0x%X\n", bytestream2_tell(&s->g) - 4);
+ if (n < 4)
+ return AVERROR_INVALIDDATA;
+
/*Zplt =*/ bytestream2_get_byte(&s->g);
for (i = 0; i < n - 3; i++) {
- bytestream2_get_byte(&s->g);
+ v = bytestream2_get_byte(&s->g);
}
+ if (v & 0x80)
+ return AVERROR_INVALIDDATA;
return 0;
}
step_x = 32;
step_y = 32;
- if (RSpoc > FFMIN(codsty->nreslevels, REpoc))
+ if (RSpoc >= FFMIN(codsty->nreslevels, REpoc))
continue;
for (reslevelno = RSpoc; reslevelno < FFMIN(codsty->nreslevels, REpoc); reslevelno++) {
step_x = FFMIN(step_x, rlevel->log2_prec_width + reducedresno);
step_y = FFMIN(step_y, rlevel->log2_prec_height + reducedresno);
}
- av_assert0(step_x < 32 && step_y < 32);
+ if (step_x >= 31 || step_y >= 31){
+ avpriv_request_sample(s->avctx, "CPRL with large step");
+ return AVERROR_PATCHWELCOME;
+ }
step_x = 1<<step_x;
step_y = 1<<step_y;
continue;
}
- for (layno = 0; layno < LYEpoc; 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;
- }
+ for (layno = 0; layno < LYEpoc; 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;
+ }
}
}
}
cblk->data + cblk->length - 2*(term_cnt < cblk->nb_terminations) - t1->mqc.bp);
}
- return 0;
+ return 1;
}
/* TODO: Verify dequantization for lossless case
for (compno = 0; compno < s->ncomponents; compno++) {
Jpeg2000Component *comp = tile->comp + compno;
Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+ int coded = 0;
t1.stride = (1<<codsty->log2_cblk_width) + 2;
cblkno++) {
int x, y;
Jpeg2000Cblk *cblk = prec->cblk + cblkno;
- decode_cblk(s, codsty, &t1, cblk,
+ int ret = decode_cblk(s, codsty, &t1, cblk,
cblk->coord[0][1] - cblk->coord[0][0],
cblk->coord[1][1] - cblk->coord[1][0],
bandpos);
-
+ if (ret)
+ coded = 1;
+ else
+ continue;
x = cblk->coord[0][0] - band->coord[0][0];
y = cblk->coord[1][0] - band->coord[1][0];
} /* end reslevel */
/* inverse DWT */
- ff_dwt_decode(&comp->dwt, codsty->transform == FF_DWT97 ? (void*)comp->f_data : (void*)comp->i_data);
+ if (coded)
+ ff_dwt_decode(&comp->dwt, codsty->transform == FF_DWT97 ? (void*)comp->f_data : (void*)comp->i_data);
+
} /*end comp */
}
len = bytestream2_get_be16(&s->g);
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;
+ if (s->avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid len %d left=%d\n", len, bytestream2_get_bytes_left(&s->g));
+ return AVERROR_INVALIDDATA;
+ }
+ av_log(s->avctx, AV_LOG_WARNING, "Missing EOC Marker.\n");
+ break;
}
switch (marker) {