summaryrefslogtreecommitdiff
path: root/src/lib/openjp2/t2.c
diff options
context:
space:
mode:
authorRobert Gabriel Jakabosky <rjakabosky+github@neoawareness.com>2022-02-10 21:27:17 +0800
committerGitHub <noreply@github.com>2022-02-10 14:27:17 +0100
commit883c31dbe09771aab043744ac2b490d7386878e3 (patch)
tree254f62d7e8158b28eea45e6ff6a58b212a380371 /src/lib/openjp2/t2.c
parent99d555c0f1818277645a0c79a5199f2e827d68cc (diff)
Add support for partial bitstream decoding (#1407) (fixes #715)
Add a -allow-partial option to opj_decompress utility and a opj_decoder_set_strict_mode() option to the API Co-authored-by: Chris Hafey <chafey@gmail.com>
Diffstat (limited to 'src/lib/openjp2/t2.c')
-rw-r--r--src/lib/openjp2/t2.c65
1 files changed, 51 insertions, 14 deletions
diff --git a/src/lib/openjp2/t2.c b/src/lib/openjp2/t2.c
index 06603892..ebda0052 100644
--- a/src/lib/openjp2/t2.c
+++ b/src/lib/openjp2/t2.c
@@ -502,7 +502,6 @@ OPJ_BOOL opj_t2_decode_packets(opj_tcd_t* tcd,
l_current_pi->precno, l_current_pi->layno, skip_packet ? "skipped" : "kept");
*/
}
-
if (!skip_packet) {
l_nb_bytes_read = 0;
@@ -1378,6 +1377,7 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
opj_tcd_cblk_dec_t* l_cblk = 00;
opj_tcd_resolution_t* l_res =
&p_tile->comps[p_pi->compno].resolutions[p_pi->resno];
+ OPJ_BOOL partial_buffer = OPJ_FALSE;
OPJ_ARG_NOT_USED(p_t2);
OPJ_ARG_NOT_USED(pack_info);
@@ -1397,6 +1397,12 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
opj_tcd_seg_t *l_seg = 00;
+ // if we have a partial data stream, set numchunks to zero
+ // since we have no data to actually decode.
+ if (partial_buffer) {
+ l_cblk->numchunks = 0;
+ }
+
if (!l_cblk->numnewpasses) {
/* nothing to do */
++l_cblk;
@@ -1419,12 +1425,32 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
/* Check possible overflow (on l_current_data only, assumes input args already checked) then size */
if ((((OPJ_SIZE_T)l_current_data + (OPJ_SIZE_T)l_seg->newlen) <
(OPJ_SIZE_T)l_current_data) ||
- (l_current_data + l_seg->newlen > p_src_data + p_max_length)) {
- opj_event_msg(p_manager, EVT_ERROR,
- "read: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
- l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno,
- p_pi->compno);
- return OPJ_FALSE;
+ (l_current_data + l_seg->newlen > p_src_data + p_max_length) ||
+ (partial_buffer)) {
+ if (p_t2->cp->strict) {
+ opj_event_msg(p_manager, EVT_ERROR,
+ "read: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
+ l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno,
+ p_pi->compno);
+ return OPJ_FALSE;
+ } else {
+ opj_event_msg(p_manager, EVT_WARNING,
+ "read: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
+ l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno,
+ p_pi->compno);
+ // skip this codeblock since it is a partial read
+ partial_buffer = OPJ_TRUE;
+ l_cblk->numchunks = 0;
+
+ l_seg->numpasses += l_seg->numnewpasses;
+ l_cblk->numnewpasses -= l_seg->numnewpasses;
+ if (l_cblk->numnewpasses > 0) {
+ ++l_seg;
+ ++l_cblk->numsegs;
+ break;
+ }
+ continue;
+ }
}
#ifdef USE_JPWL
@@ -1486,8 +1512,12 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
++l_band;
}
- *(p_data_read) = (OPJ_UINT32)(l_current_data - p_src_data);
-
+ // return the number of bytes read
+ if (partial_buffer) {
+ *(p_data_read) = p_max_length;
+ } else {
+ *(p_data_read) = (OPJ_UINT32)(l_current_data - p_src_data);
+ }
return OPJ_TRUE;
}
@@ -1549,11 +1579,18 @@ static OPJ_BOOL opj_t2_skip_packet_data(opj_t2_t* p_t2,
/* Check possible overflow then size */
if (((*p_data_read + l_seg->newlen) < (*p_data_read)) ||
((*p_data_read + l_seg->newlen) > p_max_length)) {
- opj_event_msg(p_manager, EVT_ERROR,
- "skip: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
- l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno,
- p_pi->compno);
- return OPJ_FALSE;
+ if (p_t2->cp->strict) {
+ opj_event_msg(p_manager, EVT_ERROR,
+ "skip: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
+ l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno,
+ p_pi->compno);
+ return OPJ_FALSE;
+ } else {
+ opj_event_msg(p_manager, EVT_WARNING,
+ "skip: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
+ l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno,
+ p_pi->compno);
+ }
}
#ifdef USE_JPWL