From f7a8e89e0e59285553c6d3fcf383e8fd28a81e36 Mon Sep 17 00:00:00 2001 From: Chris Hafey Date: Tue, 19 May 2020 17:35:17 +0000 Subject: [PATCH 01/11] added support for partial bitstream decoding --- src/lib/openjp2/j2k.c | 2 +- src/lib/openjp2/t2.c | 37 ++++++++++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/lib/openjp2/j2k.c b/src/lib/openjp2/j2k.c index 8e343ab2..68cbca31 100644 --- a/src/lib/openjp2/j2k.c +++ b/src/lib/openjp2/j2k.c @@ -4908,7 +4908,7 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k, opj_stream_get_number_byte_left(p_stream)) { opj_event_msg(p_manager, EVT_ERROR, "Tile part length size inconsistent with stream length\n"); - return OPJ_FALSE; + //return OPJ_FALSE; } if (p_j2k->m_specific_param.m_decoder.m_sot_length > UINT_MAX - OPJ_COMMON_CBLK_DATA_EXTRA) { diff --git a/src/lib/openjp2/t2.c b/src/lib/openjp2/t2.c index 1481e16f..34c78c56 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; @@ -1348,6 +1347,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_UINT32 partial_buffer = 0; OPJ_ARG_NOT_USED(p_t2); OPJ_ARG_NOT_USED(pack_info); @@ -1367,6 +1367,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; @@ -1389,12 +1395,29 @@ 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)) { + (l_current_data + l_seg->newlen > p_src_data + p_max_length) || + (partial_buffer)) { 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; + // NOTE - originall we would return OPJ_FALSE here when we encountered partial bitstream + //return OPJ_FALSE; + + // skip this codeblock since it is a partial read + partial_buffer = 1; + 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; + } + if(l_cblk->numnewpasses > 0) { + break; + } + continue; } #ifdef USE_JPWL @@ -1456,8 +1479,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; } From e984e13bd6175333f5ea5364dc82572f2127e567 Mon Sep 17 00:00:00 2001 From: Chris Hafey Date: Tue, 19 May 2020 19:50:36 +0000 Subject: [PATCH 02/11] fixed bug where packet skipping wasn't working with partial bitstream --- src/lib/openjp2/t2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/openjp2/t2.c b/src/lib/openjp2/t2.c index 34c78c56..723ef970 100644 --- a/src/lib/openjp2/t2.c +++ b/src/lib/openjp2/t2.c @@ -1550,7 +1550,7 @@ static OPJ_BOOL opj_t2_skip_packet_data(opj_t2_t* p_t2, "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; + //return OPJ_FALSE; } #ifdef USE_JPWL From 746bd4529041b58e0a87c6cd12f9b1efcc61cef7 Mon Sep 17 00:00:00 2001 From: Chris Hafey Date: Wed, 20 May 2020 19:09:15 +0000 Subject: [PATCH 03/11] changed ERROR->WARNING for log messages --- src/lib/openjp2/j2k.c | 3 +-- src/lib/openjp2/t2.c | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/lib/openjp2/j2k.c b/src/lib/openjp2/j2k.c index 68cbca31..e244362b 100644 --- a/src/lib/openjp2/j2k.c +++ b/src/lib/openjp2/j2k.c @@ -4906,9 +4906,8 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k, /* Check enough bytes left in stream before allocation */ if ((OPJ_OFF_T)p_j2k->m_specific_param.m_decoder.m_sot_length > opj_stream_get_number_byte_left(p_stream)) { - opj_event_msg(p_manager, EVT_ERROR, + opj_event_msg(p_manager, EVT_WARNING, "Tile part length size inconsistent with stream length\n"); - //return OPJ_FALSE; } if (p_j2k->m_specific_param.m_decoder.m_sot_length > UINT_MAX - OPJ_COMMON_CBLK_DATA_EXTRA) { diff --git a/src/lib/openjp2/t2.c b/src/lib/openjp2/t2.c index 723ef970..f4c6714c 100644 --- a/src/lib/openjp2/t2.c +++ b/src/lib/openjp2/t2.c @@ -1397,13 +1397,10 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2, (OPJ_SIZE_T)l_current_data) || (l_current_data + l_seg->newlen > p_src_data + p_max_length) || (partial_buffer)) { - opj_event_msg(p_manager, EVT_ERROR, + 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); - // NOTE - originall we would return OPJ_FALSE here when we encountered partial bitstream - //return OPJ_FALSE; - // skip this codeblock since it is a partial read partial_buffer = 1; l_cblk->numchunks = 0; From 4dfd5633e6dec24033d78a38c563f1c7f00e7250 Mon Sep 17 00:00:00 2001 From: Chris Hafey Date: Sat, 9 Oct 2021 10:42:50 +0000 Subject: [PATCH 04/11] added devcontainer and build.sh --- .devcontainer/Dockerfile | 9 +++++++++ .devcontainer/devcontainer.json | 28 ++++++++++++++++++++++++++++ build.sh | 4 ++++ 3 files changed, 41 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100755 build.sh diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..b8e92aff --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,9 @@ +# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.194.3/containers/cpp/.devcontainer/base.Dockerfile + +# [Choice] Debian / Ubuntu version: debian-11, debian-10, debian-9, ubuntu-20.04, ubuntu-18.04 +ARG VARIANT="buster" +FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-${VARIANT} + +# [Optional] Uncomment this section to install additional packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..8f73c987 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,28 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.194.3/containers/cpp +{ + "name": "C++", + "build": { + "dockerfile": "Dockerfile", + // Update 'VARIANT' to pick an Debian / Ubuntu OS version: debian-11, debian-10, debian-9, ubuntu-20.04, ubuntu-18.04 + "args": { "VARIANT": "debian-10" } + }, + "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"], + + // Set *default* container specific settings.json values on container create. + "settings": {}, + + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "ms-vscode.cpptools" + ], + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "gcc -v", + + // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "vscode" +} \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100755 index 00000000..6ccc6cd9 --- /dev/null +++ b/build.sh @@ -0,0 +1,4 @@ +#!/bin/sh +mkdir -p build +(cd build && cmake ..) +(cd build && make VERBOSE=1 -j ${nprocs}) \ No newline at end of file From 700871a9081288093e9e3f3db73d1ef467aa042f Mon Sep 17 00:00:00 2001 From: Chris Hafey Date: Tue, 19 May 2020 17:35:17 +0000 Subject: [PATCH 05/11] added support for partial bitstream decoding --- src/lib/openjp2/j2k.c | 2 +- src/lib/openjp2/t2.c | 37 ++++++++++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/lib/openjp2/j2k.c b/src/lib/openjp2/j2k.c index c45e4dbd..f9495ad8 100644 --- a/src/lib/openjp2/j2k.c +++ b/src/lib/openjp2/j2k.c @@ -4966,7 +4966,7 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k, opj_stream_get_number_byte_left(p_stream)) { opj_event_msg(p_manager, EVT_ERROR, "Tile part length size inconsistent with stream length\n"); - return OPJ_FALSE; + //return OPJ_FALSE; } if (p_j2k->m_specific_param.m_decoder.m_sot_length > UINT_MAX - OPJ_COMMON_CBLK_DATA_EXTRA) { diff --git a/src/lib/openjp2/t2.c b/src/lib/openjp2/t2.c index 48f8949b..9a47e938 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_UINT32 partial_buffer = 0; 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,29 @@ 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)) { + (l_current_data + l_seg->newlen > p_src_data + p_max_length) || + (partial_buffer)) { 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; + // NOTE - originall we would return OPJ_FALSE here when we encountered partial bitstream + //return OPJ_FALSE; + + // skip this codeblock since it is a partial read + partial_buffer = 1; + 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; + } + if(l_cblk->numnewpasses > 0) { + break; + } + continue; } #ifdef USE_JPWL @@ -1486,8 +1509,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; } From f48401972be080cecbc9dd98a706dcdf752a7fbe Mon Sep 17 00:00:00 2001 From: Chris Hafey Date: Tue, 19 May 2020 19:50:36 +0000 Subject: [PATCH 06/11] fixed bug where packet skipping wasn't working with partial bitstream --- src/lib/openjp2/t2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/openjp2/t2.c b/src/lib/openjp2/t2.c index 9a47e938..23f6c9d0 100644 --- a/src/lib/openjp2/t2.c +++ b/src/lib/openjp2/t2.c @@ -1580,7 +1580,7 @@ static OPJ_BOOL opj_t2_skip_packet_data(opj_t2_t* p_t2, "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; + //return OPJ_FALSE; } #ifdef USE_JPWL From de5b9317ae9e91274411af7479ab92fcd1737981 Mon Sep 17 00:00:00 2001 From: Chris Hafey Date: Wed, 20 May 2020 19:09:15 +0000 Subject: [PATCH 07/11] changed ERROR->WARNING for log messages --- src/lib/openjp2/j2k.c | 3 +-- src/lib/openjp2/t2.c | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/lib/openjp2/j2k.c b/src/lib/openjp2/j2k.c index f9495ad8..bcecb4b1 100644 --- a/src/lib/openjp2/j2k.c +++ b/src/lib/openjp2/j2k.c @@ -4964,9 +4964,8 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k, /* Check enough bytes left in stream before allocation */ if ((OPJ_OFF_T)p_j2k->m_specific_param.m_decoder.m_sot_length > opj_stream_get_number_byte_left(p_stream)) { - opj_event_msg(p_manager, EVT_ERROR, + opj_event_msg(p_manager, EVT_WARNING, "Tile part length size inconsistent with stream length\n"); - //return OPJ_FALSE; } if (p_j2k->m_specific_param.m_decoder.m_sot_length > UINT_MAX - OPJ_COMMON_CBLK_DATA_EXTRA) { diff --git a/src/lib/openjp2/t2.c b/src/lib/openjp2/t2.c index 23f6c9d0..b72c2e5a 100644 --- a/src/lib/openjp2/t2.c +++ b/src/lib/openjp2/t2.c @@ -1427,13 +1427,10 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2, (OPJ_SIZE_T)l_current_data) || (l_current_data + l_seg->newlen > p_src_data + p_max_length) || (partial_buffer)) { - opj_event_msg(p_manager, EVT_ERROR, + 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); - // NOTE - originall we would return OPJ_FALSE here when we encountered partial bitstream - //return OPJ_FALSE; - // skip this codeblock since it is a partial read partial_buffer = 1; l_cblk->numchunks = 0; From 245b177a690c7783d07865835d5f897ebc60d1cb Mon Sep 17 00:00:00 2001 From: Chris Hafey Date: Sat, 9 Oct 2021 10:42:50 +0000 Subject: [PATCH 08/11] added devcontainer and build.sh --- .devcontainer/Dockerfile | 9 +++++++++ .devcontainer/devcontainer.json | 28 ++++++++++++++++++++++++++++ build.sh | 4 ++++ 3 files changed, 41 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100755 build.sh diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..b8e92aff --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,9 @@ +# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.194.3/containers/cpp/.devcontainer/base.Dockerfile + +# [Choice] Debian / Ubuntu version: debian-11, debian-10, debian-9, ubuntu-20.04, ubuntu-18.04 +ARG VARIANT="buster" +FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-${VARIANT} + +# [Optional] Uncomment this section to install additional packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..8f73c987 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,28 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.194.3/containers/cpp +{ + "name": "C++", + "build": { + "dockerfile": "Dockerfile", + // Update 'VARIANT' to pick an Debian / Ubuntu OS version: debian-11, debian-10, debian-9, ubuntu-20.04, ubuntu-18.04 + "args": { "VARIANT": "debian-10" } + }, + "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"], + + // Set *default* container specific settings.json values on container create. + "settings": {}, + + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "ms-vscode.cpptools" + ], + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "gcc -v", + + // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "vscode" +} \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100755 index 00000000..6ccc6cd9 --- /dev/null +++ b/build.sh @@ -0,0 +1,4 @@ +#!/bin/sh +mkdir -p build +(cd build && cmake ..) +(cd build && make VERBOSE=1 -j ${nprocs}) \ No newline at end of file From b233d0780937cf8323632338cbd47d96e5db03bf Mon Sep 17 00:00:00 2001 From: Chris Hafey Date: Sat, 9 Oct 2021 11:08:17 +0000 Subject: [PATCH 09/11] removed .devcontainer and build.sh --- .devcontainer/Dockerfile | 9 --------- .devcontainer/devcontainer.json | 28 ---------------------------- build.sh | 4 ---- 3 files changed, 41 deletions(-) delete mode 100644 .devcontainer/Dockerfile delete mode 100644 .devcontainer/devcontainer.json delete mode 100755 build.sh diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index b8e92aff..00000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.194.3/containers/cpp/.devcontainer/base.Dockerfile - -# [Choice] Debian / Ubuntu version: debian-11, debian-10, debian-9, ubuntu-20.04, ubuntu-18.04 -ARG VARIANT="buster" -FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-${VARIANT} - -# [Optional] Uncomment this section to install additional packages. -# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ -# && apt-get -y install --no-install-recommends diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index 8f73c987..00000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,28 +0,0 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: -// https://github.com/microsoft/vscode-dev-containers/tree/v0.194.3/containers/cpp -{ - "name": "C++", - "build": { - "dockerfile": "Dockerfile", - // Update 'VARIANT' to pick an Debian / Ubuntu OS version: debian-11, debian-10, debian-9, ubuntu-20.04, ubuntu-18.04 - "args": { "VARIANT": "debian-10" } - }, - "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"], - - // Set *default* container specific settings.json values on container create. - "settings": {}, - - // Add the IDs of extensions you want installed when the container is created. - "extensions": [ - "ms-vscode.cpptools" - ], - - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], - - // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "gcc -v", - - // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. - "remoteUser": "vscode" -} \ No newline at end of file diff --git a/build.sh b/build.sh deleted file mode 100755 index 6ccc6cd9..00000000 --- a/build.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -mkdir -p build -(cd build && cmake ..) -(cd build && make VERBOSE=1 -j ${nprocs}) \ No newline at end of file From ab4a40d62c01d411c789e3e50d1446b7d8e199e6 Mon Sep 17 00:00:00 2001 From: Chris Hafey Date: Sat, 9 Oct 2021 10:11:55 -0500 Subject: [PATCH 10/11] Added opj_decoder_set_strict_mode() to control whether or not partial decoding is enabled --- src/lib/openjp2/j2k.c | 18 +++++++++-- src/lib/openjp2/j2k.h | 4 +++ src/lib/openjp2/jp2.c | 5 ++++ src/lib/openjp2/jp2.h | 9 ++++++ src/lib/openjp2/openjpeg.c | 27 +++++++++++++++++ src/lib/openjp2/openjpeg.h | 13 ++++++++ src/lib/openjp2/opj_codec.h | 3 ++ src/lib/openjp2/t2.c | 59 +++++++++++++++++++++++-------------- 8 files changed, 114 insertions(+), 24 deletions(-) diff --git a/src/lib/openjp2/j2k.c b/src/lib/openjp2/j2k.c index bcecb4b1..2c7da6f0 100644 --- a/src/lib/openjp2/j2k.c +++ b/src/lib/openjp2/j2k.c @@ -4964,8 +4964,14 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k, /* Check enough bytes left in stream before allocation */ if ((OPJ_OFF_T)p_j2k->m_specific_param.m_decoder.m_sot_length > opj_stream_get_number_byte_left(p_stream)) { - opj_event_msg(p_manager, EVT_WARNING, - "Tile part length size inconsistent with stream length\n"); + if(p_j2k->m_cp.strict) { + opj_event_msg(p_manager, EVT_ERROR, + "Tile part length size inconsistent with stream length\n"); + return OPJ_FALSE; + } else { + opj_event_msg(p_manager, EVT_WARNING, + "Tile part length size inconsistent with stream length\n"); + } } if (p_j2k->m_specific_param.m_decoder.m_sot_length > UINT_MAX - OPJ_COMMON_CBLK_DATA_EXTRA) { @@ -6684,6 +6690,7 @@ void opj_j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters) if (j2k && parameters) { j2k->m_cp.m_specific_param.m_dec.m_layer = parameters->cp_layer; j2k->m_cp.m_specific_param.m_dec.m_reduce = parameters->cp_reduce; + j2k->m_cp.strict = OPJ_TRUE; j2k->dump_state = (parameters->flags & OPJ_DPARAMETERS_DUMP_FLAG); #ifdef USE_JPWL @@ -6694,6 +6701,13 @@ void opj_j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters) } } +void opj_j2k_decoder_set_strict_mode(opj_j2k_t *j2k, OPJ_BOOL strict) +{ + if (j2k) { + j2k->m_cp.strict = strict; + } +} + OPJ_BOOL opj_j2k_set_threads(opj_j2k_t *j2k, OPJ_UINT32 num_threads) { /* Currently we pass the thread-pool to the tcd, so we cannot re-set it */ diff --git a/src/lib/openjp2/j2k.h b/src/lib/openjp2/j2k.h index 2b08e840..2cd8d38c 100644 --- a/src/lib/openjp2/j2k.h +++ b/src/lib/openjp2/j2k.h @@ -402,6 +402,8 @@ typedef struct opj_cp { } m_specific_param; + /** OPJ_TRUE if entire bit stream must be decoded, OPJ_FALSE if partial bitstream decoding allowed */ + OPJ_BOOL strict; /* UniPG>> */ #ifdef USE_JPWL @@ -622,6 +624,8 @@ Decoding parameters are returned in j2k->cp. */ void opj_j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters); +void opj_j2k_decoder_set_strict_mode(opj_j2k_t *j2k, OPJ_BOOL strict); + OPJ_BOOL opj_j2k_set_threads(opj_j2k_t *j2k, OPJ_UINT32 num_threads); /** diff --git a/src/lib/openjp2/jp2.c b/src/lib/openjp2/jp2.c index 7c065ba7..6e41f18f 100644 --- a/src/lib/openjp2/jp2.c +++ b/src/lib/openjp2/jp2.c @@ -1901,6 +1901,11 @@ void opj_jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters) OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG; } +void opj_jp2_decoder_set_strict_mode(opj_jp2_t *jp2, OPJ_BOOL strict) +{ + opj_j2k_decoder_set_strict_mode(jp2->j2k, strict); +} + OPJ_BOOL opj_jp2_set_threads(opj_jp2_t *jp2, OPJ_UINT32 num_threads) { return opj_j2k_set_threads(jp2->j2k, num_threads); diff --git a/src/lib/openjp2/jp2.h b/src/lib/openjp2/jp2.h index 9e7fa566..408d9037 100644 --- a/src/lib/openjp2/jp2.h +++ b/src/lib/openjp2/jp2.h @@ -235,6 +235,15 @@ Decoding parameters are returned in jp2->j2k->cp. */ void opj_jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters); +/** +Set the strict mode parameter. When strict mode is enabled, the entire +bitstream must be decoded or an error is returned. When it is disabled, +the decoder will decode partial bitstreams. +@param jp2 JP2 decompressor handle +@param strict JPH_TRUE for strict mode +*/ +void opj_jp2_decoder_set_strict_mode(opj_jp2_t *jp2, OPJ_BOOL strict); + /** Allocates worker threads for the compressor/decompressor. * * @param jp2 JP2 decompressor handle diff --git a/src/lib/openjp2/openjpeg.c b/src/lib/openjp2/openjpeg.c index 0c5f2d5f..de5a1d04 100644 --- a/src/lib/openjp2/openjpeg.c +++ b/src/lib/openjp2/openjpeg.c @@ -219,6 +219,10 @@ opj_codec_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT p_format) l_codec->m_codec_data.m_decompression.opj_setup_decoder = (void (*)(void *, opj_dparameters_t *)) opj_j2k_setup_decoder; + l_codec->m_codec_data.m_decompression.opj_decoder_set_strict_mode = + (void (*)(void *, OPJ_BOOL)) opj_j2k_decoder_set_strict_mode; + + l_codec->m_codec_data.m_decompression.opj_read_tile_header = (OPJ_BOOL(*)(void *, OPJ_UINT32*, @@ -326,6 +330,9 @@ opj_codec_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT p_format) l_codec->m_codec_data.m_decompression.opj_setup_decoder = (void (*)(void *, opj_dparameters_t *)) opj_jp2_setup_decoder; + l_codec->m_codec_data.m_decompression.opj_decoder_set_strict_mode = + (void (*)(void *, OPJ_BOOL)) opj_jp2_decoder_set_strict_mode; + l_codec->m_codec_data.m_decompression.opj_set_decode_area = (OPJ_BOOL(*)(void *, opj_image_t*, @@ -426,6 +433,26 @@ OPJ_BOOL OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_codec, return OPJ_FALSE; } + OPJ_API OPJ_BOOL OPJ_CALLCONV opj_decoder_set_strict_mode(opj_codec_t *p_codec, OPJ_BOOL strict) + { + if (p_codec) { + opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; + + if (! l_codec->is_decompressor) { + opj_event_msg(&(l_codec->m_event_mgr), EVT_ERROR, + "Codec provided to the opj_decoder_set_strict_mode function is not a decompressor handler.\n"); + return OPJ_FALSE; + } + + l_codec->m_codec_data.m_decompression.opj_decoder_set_strict_mode(l_codec->m_codec, + strict); + return OPJ_TRUE; + } + return OPJ_FALSE; + + } + + OPJ_BOOL OPJ_CALLCONV opj_read_header(opj_stream_t *p_stream, opj_codec_t *p_codec, opj_image_t **p_image) diff --git a/src/lib/openjp2/openjpeg.h b/src/lib/openjp2/openjpeg.h index 8829963f..c24ee933 100644 --- a/src/lib/openjp2/openjpeg.h +++ b/src/lib/openjp2/openjpeg.h @@ -1339,6 +1339,19 @@ OPJ_API void OPJ_CALLCONV opj_set_default_decoder_parameters( OPJ_API OPJ_BOOL OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_codec, opj_dparameters_t *parameters); +/** + * Set strict decoding parameter for this decoder. If strict decoding is enabled, partial bit + * streams will fail to decode. If strict decoding is disabled, the decoder will decode partial + * bitstreams as much as possible without erroring + * + * @param p_codec decompressor handler + * @param strict OBJ_TRUE to enable strict decoding, OBJ_FALSE to disable + * + * @return true if the decoder is correctly set + */ + + OPJ_API OPJ_BOOL OPJ_CALLCONV opj_decoder_set_strict_mode(opj_codec_t *p_codec, OPJ_BOOL strict); + /** * Allocates worker threads for the compressor/decompressor. * diff --git a/src/lib/openjp2/opj_codec.h b/src/lib/openjp2/opj_codec.h index 8a8af911..7cff6708 100644 --- a/src/lib/openjp2/opj_codec.h +++ b/src/lib/openjp2/opj_codec.h @@ -90,6 +90,9 @@ typedef struct opj_codec_private { /** Setup decoder function handler */ void (*opj_setup_decoder)(void * p_codec, opj_dparameters_t * p_param); + /** Strict mode function handler */ + void (*opj_decoder_set_strict_mode)(void * p_codec, OPJ_BOOL strict); + /** Set decode area function handler */ OPJ_BOOL(*opj_set_decode_area)(void * p_codec, opj_image_t * p_image, diff --git a/src/lib/openjp2/t2.c b/src/lib/openjp2/t2.c index b72c2e5a..7169750b 100644 --- a/src/lib/openjp2/t2.c +++ b/src/lib/openjp2/t2.c @@ -1377,7 +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_UINT32 partial_buffer = 0; + OPJ_BOOL partial_buffer = OPJ_FALSE; OPJ_ARG_NOT_USED(p_t2); OPJ_ARG_NOT_USED(pack_info); @@ -1427,24 +1427,32 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2, (OPJ_SIZE_T)l_current_data) || (l_current_data + l_seg->newlen > p_src_data + p_max_length) || (partial_buffer)) { - 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 = 1; - l_cblk->numchunks = 0; + if(p_t2->cp->strict) { + 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); + 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; + l_seg->numpasses += l_seg->numnewpasses; + l_cblk->numnewpasses -= l_seg->numnewpasses; + if (l_cblk->numnewpasses > 0) { + ++l_seg; + ++l_cblk->numsegs; + } + if(l_cblk->numnewpasses > 0) { + break; + } + continue; } - if(l_cblk->numnewpasses > 0) { - break; - } - continue; } #ifdef USE_JPWL @@ -1573,11 +1581,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 From 900e703e54ada6fb32801500667cd76142deee20 Mon Sep 17 00:00:00 2001 From: Chris Hafey Date: Sat, 9 Oct 2021 10:32:34 -0500 Subject: [PATCH 11/11] Removed .devcontainer and build.sh AGAIN --- .devcontainer/Dockerfile | 9 --------- .devcontainer/devcontainer.json | 28 ---------------------------- build.sh | 4 ---- 3 files changed, 41 deletions(-) delete mode 100644 .devcontainer/Dockerfile delete mode 100644 .devcontainer/devcontainer.json delete mode 100755 build.sh diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index b8e92aff..00000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.194.3/containers/cpp/.devcontainer/base.Dockerfile - -# [Choice] Debian / Ubuntu version: debian-11, debian-10, debian-9, ubuntu-20.04, ubuntu-18.04 -ARG VARIANT="buster" -FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-${VARIANT} - -# [Optional] Uncomment this section to install additional packages. -# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ -# && apt-get -y install --no-install-recommends diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index 8f73c987..00000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,28 +0,0 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: -// https://github.com/microsoft/vscode-dev-containers/tree/v0.194.3/containers/cpp -{ - "name": "C++", - "build": { - "dockerfile": "Dockerfile", - // Update 'VARIANT' to pick an Debian / Ubuntu OS version: debian-11, debian-10, debian-9, ubuntu-20.04, ubuntu-18.04 - "args": { "VARIANT": "debian-10" } - }, - "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"], - - // Set *default* container specific settings.json values on container create. - "settings": {}, - - // Add the IDs of extensions you want installed when the container is created. - "extensions": [ - "ms-vscode.cpptools" - ], - - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], - - // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "gcc -v", - - // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. - "remoteUser": "vscode" -} \ No newline at end of file diff --git a/build.sh b/build.sh deleted file mode 100755 index 6ccc6cd9..00000000 --- a/build.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -mkdir -p build -(cd build && cmake ..) -(cd build && make VERBOSE=1 -j ${nprocs}) \ No newline at end of file