[FFmpeg-devel] [PATCH v3 2/3] libavcodec/jpeg2000dec.c: Functional changes to support PPT marker
gautamramk at gmail.com
gautamramk at gmail.com
Sat Mar 28 06:19:18 EET 2020
From: Gautam Ramakrishnan <gautamramk at gmail.com>
This patch adds functional changes to support the PPT marker. It
allows the PPT marker to be read in jpeg2000_read_main_headers().
---
libavcodec/jpeg2000dec.c | 270 ++++++++++++---------------------------
1 file changed, 82 insertions(+), 188 deletions(-)
diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
index 001bc8d057..44b3e7e41b 100644
--- a/libavcodec/jpeg2000dec.c
+++ b/libavcodec/jpeg2000dec.c
@@ -1173,179 +1173,6 @@ static int jpeg2000_decode_packet_data(Jpeg2000DecoderContext *s, Jpeg2000Tile *
return 0;
}
-static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, int *tp_index,
- Jpeg2000CodingStyle *codsty,
- Jpeg2000ResLevel *rlevel, int precno,
- int layno, uint8_t *expn, int numgbits)
-{
- int bandno, cblkno, ret, nb_code_blocks;
- int cwsno;
-
- if (layno < rlevel->band[0].prec[precno].decoded_layers)
- return 0;
- rlevel->band[0].prec[precno].decoded_layers = layno + 1;
-
- if (bytestream2_get_bytes_left(&s->g) == 0 && s->bit_index == 8) {
- if (*tp_index < FF_ARRAY_ELEMS(tile->tile_part) - 1) {
- s->g = tile->tile_part[++(*tp_index)].tpg;
- }
- }
-
- 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;
- } else if (ret < 0)
- return ret;
-
- for (bandno = 0; bandno < rlevel->nbands; bandno++) {
- Jpeg2000Band *band = rlevel->band + bandno;
- Jpeg2000Prec *prec = band->prec + precno;
-
- if (band->coord[0][0] == band->coord[0][1] ||
- band->coord[1][0] == band->coord[1][1])
- continue;
- 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;
- void *tmp;
-
- 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) {
- int v = expn[bandno] + numgbits - 1 -
- tag_tree_decode(s, prec->zerobits + cblkno, 100);
- if (v < 0 || v > 30) {
- av_log(s->avctx, AV_LOG_ERROR,
- "nonzerobits %d invalid or unsupported\n", v);
- return AVERROR_INVALIDDATA;
- }
- cblk->nonzerobits = v;
- }
- if ((newpasses = getnpasses(s)) < 0)
- return newpasses;
- av_assert2(newpasses > 0);
- if (cblk->npasses + newpasses >= JPEG2000_MAX_PASSES) {
- avpriv_request_sample(s->avctx, "Too many passes");
- return AVERROR_PATCHWELCOME;
- }
- if ((llen = getlblockinc(s)) < 0)
- return llen;
- if (cblk->lblock + llen + av_log2(newpasses) > 16) {
- avpriv_request_sample(s->avctx,
- "Block with length beyond 16 bits");
- return AVERROR_PATCHWELCOME;
- }
-
- cblk->lblock += llen;
-
- cblk->nb_lengthinc = 0;
- cblk->nb_terminationsinc = 0;
- av_free(cblk->lengthinc);
- cblk->lengthinc = av_mallocz_array(newpasses , sizeof(*cblk->lengthinc));
- if (!cblk->lengthinc)
- return AVERROR(ENOMEM);
- tmp = av_realloc_array(cblk->data_start, cblk->nb_terminations + newpasses + 1, sizeof(*cblk->data_start));
- if (!tmp)
- return AVERROR(ENOMEM);
- cblk->data_start = tmp;
- do {
- int newpasses1 = 0;
-
- while (newpasses1 < newpasses) {
- newpasses1 ++;
- if (needs_termination(codsty->cblk_style, cblk->npasses + newpasses1 - 1)) {
- cblk->nb_terminationsinc ++;
- break;
- }
- }
-
- if ((ret = get_bits(s, av_log2(newpasses1) + cblk->lblock)) < 0)
- return ret;
- if (ret > cblk->data_allocated) {
- size_t new_size = FFMAX(2*cblk->data_allocated, ret);
- void *new = av_realloc(cblk->data, new_size);
- if (new) {
- cblk->data = new;
- cblk->data_allocated = new_size;
- }
- }
- if (ret > cblk->data_allocated) {
- avpriv_request_sample(s->avctx,
- "Block with lengthinc greater than %"SIZE_SPECIFIER"",
- cblk->data_allocated);
- return AVERROR_PATCHWELCOME;
- }
- cblk->lengthinc[cblk->nb_lengthinc++] = ret;
- cblk->npasses += newpasses1;
- newpasses -= newpasses1;
- } while(newpasses);
- }
- }
- jpeg2000_flush(s);
-
- if (codsty->csty & JPEG2000_CSTY_EPH) {
- if (bytestream2_peek_be16(&s->g) == JPEG2000_EPH)
- bytestream2_skip(&s->g, 2);
- else
- av_log(s->avctx, AV_LOG_ERROR, "EPH marker not found. instead %X\n", bytestream2_peek_be32(&s->g));
- }
-
- for (bandno = 0; bandno < rlevel->nbands; bandno++) {
- Jpeg2000Band *band = rlevel->band + bandno;
- 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 (!cblk->nb_terminationsinc && !cblk->lengthinc)
- continue;
- for (cwsno = 0; cwsno < cblk->nb_lengthinc; cwsno ++) {
- if (cblk->data_allocated < cblk->length + cblk->lengthinc[cwsno] + 4) {
- size_t new_size = FFMAX(2*cblk->data_allocated, cblk->length + cblk->lengthinc[cwsno] + 4);
- void *new = av_realloc(cblk->data, new_size);
- if (new) {
- cblk->data = new;
- cblk->data_allocated = new_size;
- }
- }
- if ( bytestream2_get_bytes_left(&s->g) < cblk->lengthinc[cwsno]
- || cblk->data_allocated < cblk->length + cblk->lengthinc[cwsno] + 4
- ) {
- av_log(s->avctx, AV_LOG_ERROR,
- "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;
- }
-
- bytestream2_get_bufferu(&s->g, cblk->data + cblk->length, cblk->lengthinc[cwsno]);
- cblk->length += cblk->lengthinc[cwsno];
- cblk->lengthinc[cwsno] = 0;
- if (cblk->nb_terminationsinc) {
- cblk->nb_terminationsinc--;
- cblk->nb_terminations++;
- cblk->data[cblk->length++] = 0xFF;
- cblk->data[cblk->length++] = 0xFF;
- cblk->data_start[cblk->nb_terminations] = cblk->length;
- }
- }
- av_freep(&cblk->lengthinc);
- }
- }
- return 0;
-}
-
static int jpeg2000_decode_packets_po_iteration(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
int RSpoc, int CSpoc,
int LYEpoc, int REpoc, int CEpoc,
@@ -1370,13 +1197,25 @@ static int jpeg2000_decode_packets_po_iteration(Jpeg2000DecoderContext *s, Jpeg2
Jpeg2000ResLevel *rlevel = tile->comp[compno].reslevel +
reslevelno;
ok_reslevel = 1;
- for (precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++)
- if ((ret = jpeg2000_decode_packet(s, tile, tp_index,
+ for (precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++) {
+ int process_data = 1;
+ if ((ret = jpeg2000_decode_packet_header(s, tile, tp_index,
+ codsty, rlevel,
+ precno, layno,
+ qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
+ qntsty->nguardbits, &process_data)) < 0)
+ return ret;
+
+ if (!process_data)
+ continue;
+
+ if ((ret = jpeg2000_decode_packet_data(s, tile, tp_index,
codsty, rlevel,
precno, layno,
qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
qntsty->nguardbits)) < 0)
return ret;
+ }
}
}
}
@@ -1396,13 +1235,25 @@ static int jpeg2000_decode_packets_po_iteration(Jpeg2000DecoderContext *s, Jpeg2
Jpeg2000ResLevel *rlevel = tile->comp[compno].reslevel +
reslevelno;
ok_reslevel = 1;
- for (precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++)
- if ((ret = jpeg2000_decode_packet(s, tile, tp_index,
+ for (precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++) {
+ int process_data = 1;
+ if ((ret = jpeg2000_decode_packet_header(s, tile, tp_index,
+ codsty, rlevel,
+ precno, layno,
+ qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
+ qntsty->nguardbits, &process_data)) < 0)
+ return ret;
+
+ if (!process_data)
+ continue;
+
+ if ((ret = jpeg2000_decode_packet_data(s, tile, tp_index,
codsty, rlevel,
precno, layno,
qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
qntsty->nguardbits)) < 0)
return ret;
+ }
}
}
}
@@ -1464,7 +1315,19 @@ static int jpeg2000_decode_packets_po_iteration(Jpeg2000DecoderContext *s, Jpeg2
}
for (layno = 0; layno < LYEpoc; layno++) {
- if ((ret = jpeg2000_decode_packet(s, tile, tp_index, codsty, rlevel,
+ int process_data = 1;
+ if ((ret = jpeg2000_decode_packet_header(s, tile, tp_index,
+ codsty, rlevel,
+ precno, layno,
+ qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
+ qntsty->nguardbits, &process_data)) < 0)
+ return ret;
+
+ if (!process_data)
+ continue;
+
+ if ((ret = jpeg2000_decode_packet_data(s, tile, tp_index,
+ codsty, rlevel,
precno, layno,
qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
qntsty->nguardbits)) < 0)
@@ -1534,14 +1397,25 @@ static int jpeg2000_decode_packets_po_iteration(Jpeg2000DecoderContext *s, Jpeg2
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++) {
+ int process_data = 1;
+ if ((ret = jpeg2000_decode_packet_header(s, tile, tp_index,
+ codsty, rlevel,
+ precno, layno,
+ qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
+ qntsty->nguardbits, &process_data)) < 0)
+ return ret;
+
+ if (!process_data)
+ continue;
+
+ if ((ret = jpeg2000_decode_packet_data(s, tile, tp_index,
+ codsty, rlevel,
+ precno, layno,
+ qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
+ qntsty->nguardbits)) < 0)
+ return ret;
+ }
}
}
}
@@ -1605,7 +1479,19 @@ static int jpeg2000_decode_packets_po_iteration(Jpeg2000DecoderContext *s, Jpeg2
}
for (layno = 0; layno < LYEpoc; layno++) {
- if ((ret = jpeg2000_decode_packet(s, tile, tp_index, codsty, rlevel,
+ int process_data = 1;
+ if ((ret = jpeg2000_decode_packet_header(s, tile, tp_index,
+ codsty, rlevel,
+ precno, layno,
+ qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
+ qntsty->nguardbits, &process_data)) < 0)
+ return ret;
+
+ if (!process_data)
+ continue;
+
+ if ((ret = jpeg2000_decode_packet_data(s, tile, tp_index,
+ codsty, rlevel,
precno, layno,
qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
qntsty->nguardbits)) < 0)
@@ -2175,6 +2061,11 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
av_log(s->avctx, AV_LOG_ERROR, "Invalid tpend\n");
return AVERROR_INVALIDDATA;
}
+
+ if (tile->has_ppt && tile->tp_idx == 0) {
+ bytestream2_init(&tile->packed_headers_stream, tile->packed_headers, tile->packed_headers_size);
+ }
+
bytestream2_init(&tp->tpg, s->g.buffer, tp->tp_end - s->g.buffer);
bytestream2_skip(&s->g, tp->tp_end - s->g.buffer);
@@ -2237,6 +2128,10 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
// Packet length, tile-part header
ret = get_plt(s, len);
break;
+ case JPEG2000_PPT:
+ // Packed headers, tile-part header
+ ret = get_ppt(s, len);
+ break;
default:
av_log(s->avctx, AV_LOG_ERROR,
"unsupported marker 0x%.4"PRIX16" at pos 0x%X\n",
@@ -2266,7 +2161,6 @@ static int jpeg2000_read_bitstream_packets(Jpeg2000DecoderContext *s)
if ((ret = init_tile(s, tileno)) < 0)
return ret;
- s->g = tile->tile_part[0].tpg;
if ((ret = jpeg2000_decode_packets(s, tile)) < 0)
return ret;
}
--
2.17.1
More information about the ffmpeg-devel
mailing list