From: Gautam Ramakrishnan <gautamr...@gmail.com> This patch adds functional changes to support the PPT marker. --- libavcodec/jpeg2000dec.c | 209 ++++++++++++++++++++++++++++++--------- 1 file changed, 162 insertions(+), 47 deletions(-)
diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 9d52969821..23e43ff052 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); // Zppt is skipped and not used + if (!tile->packed_headers) { + tile->packed_headers = av_malloc_array(n - 3, 1); + memcpy(tile->packed_headers, s->g.buffer, n - 3); + tile->packed_headers_size = n - 3; + } else { + tile->packed_headers = av_realloc_array(tile->packed_headers, + tile->packed_headers_size + n - 3, + 1); + memcpy(tile->packed_headers + tile->packed_headers_size, + s->g.buffer, 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 state of stream 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) { @@ -1158,13 +1198,27 @@ 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, - codsty, rlevel, - precno, layno, - qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0), - qntsty->nguardbits)) < 0) + 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,27 @@ 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, - codsty, rlevel, - precno, layno, - qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0), - qntsty->nguardbits)) < 0) + 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,10 +1320,24 @@ 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, - precno, layno, - qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0), - qntsty->nguardbits)) < 0) + 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; } } @@ -1322,14 +1404,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,10 +1486,24 @@ 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, - precno, layno, - qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0), - qntsty->nguardbits)) < 0) + 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; } } @@ -1963,6 +2070,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 +2137,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 +2170,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 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".