[FFmpeg-devel] [PATCH v7 2/3] libavcodec/jpeg2000dec.c: Add support for PPT marker
gautamramk at gmail.com
gautamramk at gmail.com
Mon Mar 30 08:06:31 EEST 2020
From: Gautam Ramakrishnan <gautamramk at gmail.com>
This patch adds functional changes to support the
PPT marker.
---
libavcodec/jpeg2000dec.c | 178 +++++++++++++++++++++++++++++++--------
1 file changed, 144 insertions(+), 34 deletions(-)
diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
index 4ee20e41b1..71f1245fc1 100644
--- a/libavcodec/jpeg2000dec.c
+++ b/libavcodec/jpeg2000dec.c
@@ -859,6 +859,39 @@ static int get_plt(Jpeg2000DecoderContext *s, int n)
return 0;
}
+static int get_ppt(Jpeg2000DecoderContext *s, int n)
+{
+ Jpeg2000Tile *tile;
+
+ if (s->curtileno < 0)
+ return AVERROR_INVALIDDATA;
+
+ tile = &s->tile[s->curtileno];
+ if (tile->tp_idx != 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "PPT marker can occur only on first tile part of a tile.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ tile->has_ppt = 1; // this tile has a ppt marker
+/* Zppt = */ bytestream2_get_byte(&s->g);
+ if (!tile->packed_headers) {
+ tile->packed_headers = av_malloc_array(n - 3, sizeof(uint8_t));
+ memcpy(tile->packed_headers, s->g.buffer, sizeof(uint8_t)*(n - 3));
+ tile->packed_headers_size = n - 3;
+ } else {
+ tile->packed_headers = av_realloc_array(tile->packed_headers,
+ tile->packed_headers_size + n - 3,
+ sizeof(uint8_t));
+ memcpy(tile->packed_headers + tile->packed_headers_size,
+ s->g.buffer, sizeof(uint8_t)*(n - 3));
+ tile->packed_headers_size += n - 3;
+ }
+ bytestream2_skip(&s->g, n - 3);
+
+ return 0;
+}
+
static int init_tile(Jpeg2000DecoderContext *s, int tileno)
{
int compno;
@@ -931,20 +964,21 @@ static int getlblockinc(Jpeg2000DecoderContext *s)
return res;
}
-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)
+static int jpeg2000_decode_packet_header(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
+ int *tp_index,
+ Jpeg2000CodingStyle *codsty,
+ Jpeg2000ResLevel *rlevel, int precno,
+ int layno, uint8_t *expn, int numgbits,
+ int *process_data)
{
int bandno, cblkno, ret, nb_code_blocks;
- int cwsno;
-// This part decodes the packet header
-
- if (layno < rlevel->band[0].prec[precno].decoded_layers)
+ if (layno < rlevel->band[0].prec[precno].decoded_layers) {
+ *process_data = 0;
return 0;
+ }
rlevel->band[0].prec[precno].decoded_layers = layno + 1;
- // Select appropriate stream to read from
+ // Select stream to read from
if (tile->has_ppt) {
s->g = tile->packed_headers_stream;
} else {
@@ -960,12 +994,8 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
if (!(ret = get_bits(s, 1))) {
jpeg2000_flush(s);
- // Save state of stream
- if (tile->has_ppt)
- tile->packed_headers_stream = s->g;
- else
- tile->tile_part[*tp_index].tpg = s->g;
- return 0;
+ *process_data = 0;
+ goto end;
} else if (ret < 0)
return ret;
@@ -1070,14 +1100,24 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
else
av_log(s->avctx, AV_LOG_ERROR, "EPH marker not found. instead %X\n", bytestream2_peek_be32(&s->g));
}
-
+end:
+ // Save stream state
if (tile->has_ppt)
tile->packed_headers_stream = s->g;
else
tile->tile_part[*tp_index].tpg = s->g;
+ return 0;
+}
+
+static int jpeg2000_decode_packet_data(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
+ int *tp_index,
+ Jpeg2000CodingStyle *codsty,
+ Jpeg2000ResLevel *rlevel, int precno,
+ int layno, uint8_t *expn, int numgbits)
+{
+ int bandno, cblkno, nb_code_blocks;
+ int cwsno;
-// This part decodes the packet data.
- // Select appropriate stream to read from
s->g = tile->tile_part[*tp_index].tpg;
if (tile->has_ppt) {
if (bytestream2_get_bytes_left(&s->g) == 0 && s->bit_index == 8) {
@@ -1088,6 +1128,8 @@ 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);
}
+
+
for (bandno = 0; bandno < rlevel->nbands; bandno++) {
Jpeg2000Band *band = rlevel->band + bandno;
Jpeg2000Prec *prec = band->prec + precno;
@@ -1129,7 +1171,7 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
av_freep(&cblk->lengthinc);
}
}
- // Save state of stream
+ // Save stream state
tile->tile_part[*tp_index].tpg = s->g;
return 0;
}
@@ -1158,13 +1200,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;
+ }
}
}
}
@@ -1184,13 +1238,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;
+ }
}
}
}
@@ -1252,7 +1318,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)
@@ -1322,14 +1400,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;
+ }
}
}
}
@@ -1393,7 +1482,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)
@@ -1419,6 +1520,7 @@ static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile
int tp_index = 0;
s->bit_index = 8;
+
if (tile->poc.nb_poc) {
for (i=0; i<tile->poc.nb_poc; i++) {
Jpeg2000POCEntry *e = &tile->poc.poc[i];
@@ -1963,6 +2065,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);
@@ -2025,6 +2132,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",
@@ -2054,7 +2165,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