Version
0.8.0
Describe the bug.
The nvjpeg lossless JPEG decoder (NVJPEG_BACKEND_LOSSLESS_JPEG) silently produces zero-filled output buffers for two classes of JPEG Lossless (SOF3) stream. nvjpegDecodeBatchedSupported incorrectly returns isSupported == 0 ("supported") for both, making the failures silent — no error is returned, the decode appears to succeed, but the output buffer contains only zeros.
These bugs were discovered when testing MAPs built using MONAI Deploy App SDK - CT and MR DICOM studies from Philips scanners were identified that produced zero-filled images that propagated silently through model inference, manifesting as empty segmentations. See PR on App SDK for additional background.
Expected behaviour: canDecode should return PROCESSING_STATUS_SAMPLE_TYPE_UNSUPPORTED or PROCESSING_STATUS_CODEC_UNSUPPORTED for these streams, allowing the framework to fall back to a capable CPU decoder (e.g. libjpeg-turbo) that handles them correctly.
Two independent bugs:
Bug 1 — Sub-16-bit SOF3 precision (P in [9,15]):
When the SOF3 P byte encodes a precision of 9–15 (e.g. a Philips scanner writing P=12 for a 12-bit series), nvjpegDecodeBatched silently zero-fills the output buffer. The GPU kernel appears to assume P=16 for all UINT16 lossless streams and misreads the Huffman-coded bitstream when P is smaller.
Bug 2 — DHT segment before SOF3:
When a DHT (0xFFC4) segment appears before the SOF3 marker (0xFFC3) — non-standard ordering that is technically valid per ITU-T T.81 Annex B, but emitted by some Philips scanners — nvjpegDecodeBatched fails to build decode tables correctly and silently zero-fills.
In both cases nvjpegDecodeBatchedSupported returns "supported", which is the core defect.
The issue is isolated to lossless_decoder.cpp / NVJPEG_BACKEND_LOSSLESS_JPEG. The baseline JPEG decoder (cuda_decoder.cpp) and the JPEG 2000 decoder (nvjpeg2k_ext) do not seem to be affected.
Minimum reproducible example
Three JPEG Lossless frames extracted from DICOM files reproduce the two bugs. All have BitsStored=12 in their DICOM tags but differ in JPEG stream encoding. Anonymized test frames and a proposed fix (with passing tests) are available in the linked PR (below).
| File |
Manufacturer |
SOF3 P byte |
Segment order |
Result |
bad_sequence_frame.jpg |
Siemens SOMATOM |
16 |
SOI → SOF3(P=16) → DHT → SOS |
✅ Correct |
MR_frame.jpg |
Philips Ingenia |
12 |
SOI → SOF3(P=12) → DHT → SOS |
❌ Silent zeros (Bug 1) |
CT_frame.jpg |
Philips iCT SP |
16 |
SOI → COM → DHT → SOF3(P=16) → SOS |
❌ Silent zeros (Bug 2) |
Environment details
$ ./tools/print_env.sh
<details><summary>Click here to see environment details</summary><pre>
**git***
commit 36b4ee8c91de66070a09fa08fa1abbdc1a89144f (HEAD -> bl/jpeglossless_DHT_bugfix, origin/main, origin/HEAD, main)
Merge: 89500f3 3a7ac73
Author: Sebastian Matysik <146925399+smatysik-nv@users.noreply.github.com>
Date: Tue Apr 14 15:19:37 2026 +0200
Merge pull request #49 from NVIDIA/release_v0.8
Adding code for release v0.8.0 (commit 93bcb05)
**git submodules***
e170594ac7cf1dac584da473d4ca9301087090c1 external/NVTX (e170594)
cd1b1bd03900b68505822cfa25cb16851bd6caf1 external/boost/preprocessor (boost-1.89.0)
93c8f2a3c774b84af6f652b1992c48164fae60fc external/dlpack (93c8f2a)
52eb8108c5bdec04579160ae17225d66034bd723 external/googletest (52eb810)
f5fbe867d2d26e4a0a9177a51f6e568868ad3dc8 external/pybind11 (f5fbe86)
***OS Information***
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.5 LTS"
PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.5 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
Linux EW22-04661 5.15.146.1-microsoft-standard-WSL2 #1 SMP Thu Jan 11 04:09:03 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
***GPU Information***
Wed May 6 13:47:59 2026
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 575.64.04 Driver Version: 577.00 CUDA Version: 12.9 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA GeForce RTX 3090 On | 00000000:01:00.0 Off | N/A |
| 0% 42C P8 18W / 350W | 1335MiB / 24576MiB | 6% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| No running processes found |
+-----------------------------------------------------------------------------------------+
***CPU***
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Address sizes: 39 bits physical, 48 bits virtual
Byte Order: Little Endian
CPU(s): 16
On-line CPU(s) list: 0-15
Vendor ID: GenuineIntel
Model name: 11th Gen Intel(R) Core(TM) i7-11700 @ 2.50GHz
CPU family: 6
Model: 167
Thread(s) per core: 2
Core(s) per socket: 8
Socket(s): 1
Stepping: 1
BogoMIPS: 4991.99
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology tsc_reliable nonstop_tsc cpuid pni pclmulqdq vmx ssse3 fma cx16 pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid avx512f avx512dq rdseed adx smap avx512ifma clflushopt avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves avx512vbmi umip avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid fsrm md_clear flush_l1d arch_capabilities
Virtualization: VT-x
Hypervisor vendor: Microsoft
Virtualization type: full
L1d cache: 384 KiB (8 instances)
L1i cache: 256 KiB (8 instances)
L2 cache: 4 MiB (8 instances)
L3 cache: 16 MiB (1 instance)
Vulnerability Gather data sampling: Unknown: Dependent on hypervisor status
Vulnerability Itlb multihit: Not affected
Vulnerability L1tf: Not affected
Vulnerability Mds: Not affected
Vulnerability Meltdown: Not affected
Vulnerability Mmio stale data: Vulnerable: Clear CPU buffers attempted, no microcode; SMT Host state unknown
Vulnerability Retbleed: Mitigation; Enhanced IBRS
Vulnerability Spec rstack overflow: Not affected
Vulnerability Spec store bypass: Mitigation; Speculative Store Bypass disabled via prctl and seccomp
Vulnerability Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointer sanitization
Vulnerability Spectre v2: Mitigation; Enhanced IBRS, IBPB conditional, RSB filling, PBRSB-eIBRS SW sequence
Vulnerability Srbds: Not affected
Vulnerability Tsx async abort: Not affected
***CMake***
/usr/bin/cmake
cmake: /home/bluna301/miniconda3/envs/nvimgcodec/lib/libcurl.so.4: no version information available (required by cmake)
cmake version 3.22.1
CMake suite maintained and supported by Kitware (kitware.com/cmake).
***g++***
/usr/bin/g++
g++ (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
***nvcc***
/usr/local/cuda/bin/nvcc
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2024 NVIDIA Corporation
Built on Thu_Jun__6_02:18:23_PDT_2024
Cuda compilation tools, release 12.5, V12.5.82
Build cuda_12.5.r12.5/compiler.34385749_0
***Python***
/home/bluna301/miniconda3/envs/nvimgcodec/bin/python
Python 3.10.20
***Environment Variables***
PATH : /usr/local/cuda/bin:/home/bluna301/.vscode-server/data/User/globalStorage/github.copilot-chat/debugCommand:/home/bluna301/.vscode-server/data/User/globalStorage/github.copilot-chat/copilotCli:/home/bluna301/.vscode-server/bin/10c8e557c8b9f9ed0a87f61f1c9a44bde731c409/bin/remote-cli:/home/bluna301/.local/bin:/home/bluna301/miniconda3/envs/nvimgcodec/bin:/home/bluna301/miniconda3/condabin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/mnt/c/Program
Files/NVIDIA : GPU
Computing : Toolkit/CUDA/v12.0/bin:/mnt/c/Program
Files/NVIDIA : GPU
Computing : Toolkit/CUDA/v12.0/libnvvp:/mnt/c/Program
Files : (x86)/Common
Files/Oracle/Java/javapath:/mnt/c/ProgramData/Oracle/Java/javapath:/mnt/c/WINDOWS/system32:/mnt/c/WINDOWS:/mnt/c/WINDOWS/System32/Wbem:/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0:/mnt/c/WINDOWS/System32/OpenSSH:/mnt/c/PROGRA~2/CMWeb/bin:/mnt/c/Program: Files/MATLAB/MATLAB
Compiler : Runtime/v84/runtime/win64:/mnt/c/Users/mahfq2/AppData/Local/Programs/Python/Python310:/mnt/c/Users/mahfq2/AppData/Local/pip:/mnt/c/Users/mahfq2/AppData/Local/Programs/Python/Python310/Scripts:/mnt/c/Program
Files/Plastimatch/bin:/mnt/c/Program: Files/Plastimatch:/mnt/c/Program
Files/NVIDIA : Corporation/Nsight
Compute : 2022.4.0:/mnt/c/Program
Files : (x86)/NVIDIA
Corporation/PhysX/Common:/mnt/c/Program: Files/NVIDIA
Corporation/NVIDIA : NvDLISR:/mnt/c/Program
Files/Git/cmd:/mnt/c/Program : Files/dotnet:/Docker/host/bin:/mnt/c/Users/LUNPB9/AppData/Local/anaconda3:/mnt/c/Users/LUNPB9/AppData/Local/anaconda3/Library/mingw-w64/bin:/mnt/c/Users/LUNPB9/AppData/Local/anaconda3/Library/usr/bin:/mnt/c/Users/LUNPB9/AppData/Local/anaconda3/Library/bin:/mnt/c/Users/LUNPB9/AppData/Local/anaconda3/Scripts:/mnt/c/Users/LUNPB9/AppData/Local/Programs/Python/Python312/Scripts:/mnt/c/Users/LUNPB9/AppData/Local/Programs/Python/Python312:/mnt/c/Users/LUNPB9/AppData/Local/Microsoft/WindowsApps:/mnt/c/Users/LUNPB9/AppData/Local/Programs/Microsoft
VS : Code/bin:/snap/bin:/home/bluna301/.vscode-server/extensions/ms-python.debugpy-2026.6.0-linux-x64/bundled/scripts/noConfigScripts
LD_LIBRARY_PATH : /home/bluna301/miniconda3/envs/nvimgcodec/lib/python3.10/site-packages/nvidia/libnvcomp/lib64:/home/bluna301/miniconda3/envs/nvimgcodec/lib/python3.10/site-packages/nvidia/nvjpeg2k/lib:/home/bluna301/miniconda3/envs/nvimgcodec/lib/python3.10/site-packages/nvidia/nvtiff/lib:/home/bluna301/miniconda3/envs/nvimgcodec/lib:/usr/lib/llvm-14/lib:/usr/local/cuda/lib64:/home/bluna301/nvImageCodec/build_feature/bin/lib64:/home/bluna301/nvImageCodec/build_feature/bin/lib:/home/bluna301/nvImageCodec/build_feature/src:/home/bluna301/nvImageCodec/build_feature/extensions/nvjpeg:/home/bluna301/nvImageCodec/build_feature/extensions/nvjpeg2k:/home/bluna301/nvImageCodec/build_feature/extensions/nvtiff:/home/bluna301/nvImageCodec/build_feature/extensions/opencv:/home/bluna301/nvImageCodec/build_feature/extensions/nvbmp:/home/bluna301/nvImageCodec/build_feature/extensions/nvpnm:/home/bluna301/nvImageCodec/build_feature/extensions/libjpeg_turbo:/home/bluna301/nvImageCodec/build_feature/extensions/libtiff
NUMBAPRO_NVVM :
NUMBAPRO_LIBDEVICE :
CONDA_PREFIX : /home/bluna301/miniconda3/envs/nvimgcodec
PYTHON_PATH :
***conda packages***
/home/bluna301/miniconda3/condabin/conda
# packages in environment at /home/bluna301/miniconda3/envs/nvimgcodec:
#
# Name Version Build Channel
_openmp_mutex 4.5 20_gnu conda-forge
alabaster 0.7.16 pyhd8ed1ab_0 conda-forge
alsa-lib 1.2.15.3 hb03c661_0 conda-forge
aom 3.9.1 hac33072_0 conda-forge
aws-c-auth 0.10.1 ha62d5e7_3 conda-forge
aws-c-cal 0.9.13 h2c9d079_1 conda-forge
aws-c-common 0.12.6 hb03c661_0 conda-forge
aws-c-compression 0.3.2 h8b1a151_0 conda-forge
aws-c-http 0.10.13 h4bacb7b_0 conda-forge
aws-c-io 0.26.3 h692f434_1 conda-forge
aws-c-s3 0.12.2 he6ee468_1 conda-forge
aws-c-sdkutils 0.2.4 h8b1a151_4 conda-forge
aws-checksums 0.2.10 h8b1a151_0 conda-forge
babel 2.18.0 pyhcf101f3_1 conda-forge
backports.zstd 1.4.0 py310h69bd2ac_0 conda-forge
binutils_impl_linux-64 2.45.1 default_hfdba357_102 conda-forge
blas 1.0 openblas
breathe 4.35.0 pyhd8ed1ab_4 conda-forge
brotli-python 1.2.0 py310hba01987_1 conda-forge
bzip2 1.0.8 hda65f42_9 conda-forge
c-ares 1.34.6 hb03c661_0 conda-forge
ca-certificates 2026.4.22 hbd8a1cb_0 conda-forge
cairo 1.18.4 he90730b_1 conda-forge
certifi 2026.4.22 pyhd8ed1ab_0 conda-forge
charset-normalizer 3.4.7 pyhd8ed1ab_0 conda-forge
clang 14.0.6 pypi_0 pypi
clang-14 14.0.6 default_h7634d5b_1 conda-forge
colorama 0.4.6 pyhd8ed1ab_1 conda-forge
cyrus-sasl 2.1.28 hac629b4_1 conda-forge
dav1d 1.2.1 hd590300_0 conda-forge
dbus 1.16.2 h24cb091_1 conda-forge
docutils 0.17.1 py310hff52083_7 conda-forge
double-conversion 3.4.0 hecca717_0 conda-forge
exceptiongroup 1.3.1 pypi_0 pypi
ffmpeg 8.1.1 gpl_hee00b0e_901 conda-forge
flake8 7.3.0 pyhd8ed1ab_0 conda-forge
font-ttf-dejavu-sans-mono 2.37 hab24e00_0 conda-forge
font-ttf-inconsolata 3.000 h77eed37_0 conda-forge
font-ttf-source-code-pro 2.038 h77eed37_0 conda-forge
font-ttf-ubuntu 0.83 h77eed37_3 conda-forge
fontconfig 2.17.1 h27c8c51_0 conda-forge
fonts-conda-ecosystem 1 0 conda-forge
fonts-conda-forge 1 hc364b38_1 conda-forge
fribidi 1.0.16 hb03c661_0 conda-forge
future 1.0.0 pyhd8ed1ab_2 conda-forge
gcc_impl_linux-64 15.2.0 he420e7e_18 conda-forge
gdk-pixbuf 2.44.6 h2b0a6b4_0 conda-forge
glslang 16.3.0 h96af755_0 conda-forge
gmp 6.3.0 hac33072_2 conda-forge
graphite2 1.3.14 hecca717_2 conda-forge
h2 4.3.0 pyhcf101f3_0 conda-forge
harfbuzz 14.2.0 h6083320_0 conda-forge
hdf5 2.1.0 nompi_h87a9417_105 conda-forge
hpack 4.1.0 pyhd8ed1ab_0 conda-forge
hyperframe 6.1.0 pyhd8ed1ab_0 conda-forge
icu 78.3 h33c6efd_0 conda-forge
idna 3.13 pyhcf101f3_0 conda-forge
imageio 2.37.3 pypi_0 pypi
imagesize 2.0.0 pyhd8ed1ab_0 conda-forge
imath 3.2.2 hde8ca8f_0 conda-forge
importlib-metadata 8.8.0 pyhcf101f3_0 conda-forge
iniconfig 2.3.0 pypi_0 pypi
intel-gmmlib 22.10.0 hb700be7_0 conda-forge
intel-media-driver 26.1.6 hecca717_0 conda-forge
jinja2 3.1.6 pyhcf101f3_1 conda-forge
kernel-headers_linux-64 5.14.0 he073ed8_3 conda-forge
keyutils 1.6.3 hb9d3cd8_0 conda-forge
krb5 1.22.2 ha1258a1_0 conda-forge
lame 3.100 h166bdaf_1003 conda-forge
lcms2 2.19 h0c24ade_0 conda-forge
ld_impl_linux-64 2.45.1 default_hbd61a6d_102 conda-forge
lerc 4.1.0 hdb68285_0 conda-forge
level-zero 1.28.4 hb700be7_0 conda-forge
libabseil 20260107.1 cxx17_h7b12aa8_0 conda-forge
libaec 1.1.5 h088129d_0 conda-forge
libass 0.17.4 h96ad9f0_0 conda-forge
libavif16 1.4.1 hcfa2d63_0 conda-forge
libblas 3.9.0 1_h86c2bf4_netlib conda-forge
libbrotlicommon 1.2.0 hb03c661_1 conda-forge
libbrotlidec 1.2.0 hb03c661_1 conda-forge
libbrotlienc 1.2.0 hb03c661_1 conda-forge
libcap 2.77 hd0affe5_1 conda-forge
libcblas 3.9.0 13_h8e06fc2_netlib conda-forge
libclang 14.0.6 default_h7634d5b_1 conda-forge
libclang-cpp14 14.0.6 default_h7634d5b_1 conda-forge
libclang13 14.0.6 default_h9986a30_1 conda-forge
libcups 2.3.3 h7a8fb5f_6 conda-forge
libcurl 8.20.0 hcf29cc6_0 conda-forge
libdeflate 1.25 h17f619e_0 conda-forge
libdovi 3.3.2 ha23c83e_4 conda-forge
libdrm 2.4.125 hb03c661_1 conda-forge
libedit 3.1.20250104 pl5321h7949ede_0 conda-forge
libegl 1.7.0 ha4b6fd6_2 conda-forge
libegl-devel 1.7.0 ha4b6fd6_2 conda-forge
libev 4.33 hd590300_2 conda-forge
libexpat 2.8.0 hecca717_0 conda-forge
libffi 3.5.2 h3435931_0 conda-forge
libflac 1.5.0 he200343_1 conda-forge
libfreetype 2.14.3 ha770c72_0 conda-forge
libfreetype6 2.14.3 h73754d4_0 conda-forge
libgcc 15.2.0 he0feb66_18 conda-forge
libgcc-devel_linux-64 15.2.0 hcc6f6b0_118 conda-forge
libgcc-ng 15.2.0 h69a702a_18 conda-forge
libgfortran 15.2.0 h166f726_7
libgfortran-ng 15.2.0 h166f726_7
libgfortran5 15.2.0 hc633d37_7
libgl 1.7.0 ha4b6fd6_2 conda-forge
libgl-devel 1.7.0 ha4b6fd6_2 conda-forge
libglib 2.88.1 h0d30a3d_1 conda-forge
libglvnd 1.7.0 ha4b6fd6_2 conda-forge
libglx 1.7.0 ha4b6fd6_2 conda-forge
libglx-devel 1.7.0 ha4b6fd6_2 conda-forge
libgomp 15.2.0 he0feb66_18 conda-forge
libhwloc 2.12.2 default_hafda6a7_1000 conda-forge
libhwy 1.4.0 h10be129_0 conda-forge
libiconv 1.18 h3b78370_2 conda-forge
libjpeg-turbo 3.1.4.1 hb03c661_0 conda-forge
libjxl 0.11.2 h174a0a3_1 conda-forge
liblapack 3.9.0 13_h8876d29_netlib conda-forge
liblapacke 3.9.0 13_hb041515_netlib conda-forge
libllvm14 14.0.6 hcd5def8_4 conda-forge
liblzma 5.8.3 hb03c661_0 conda-forge
libnghttp2 1.68.1 h877daf1_0 conda-forge
libnsl 2.0.1 hb9d3cd8_1 conda-forge
libntlm 1.8 hb9d3cd8_0 conda-forge
libogg 1.3.5 hd0c01bc_1 conda-forge
libopenblas 0.3.31 hf7dbefb_2
libopencv 4.13.0 qt6_py310h7d3a38c_608 conda-forge
libopenvino 2026.0.0 hb56ce9e_1 conda-forge
libopenvino-auto-batch-plugin 2026.0.0 hd85de46_1 conda-forge
libopenvino-auto-plugin 2026.0.0 hd85de46_1 conda-forge
libopenvino-hetero-plugin 2026.0.0 hd41364c_1 conda-forge
libopenvino-intel-cpu-plugin 2026.0.0 hb56ce9e_1 conda-forge
libopenvino-intel-gpu-plugin 2026.0.0 hb56ce9e_1 conda-forge
libopenvino-intel-npu-plugin 2026.0.0 hb56ce9e_1 conda-forge
libopenvino-ir-frontend 2026.0.0 hd41364c_1 conda-forge
libopenvino-onnx-frontend 2026.0.0 h7a07914_1 conda-forge
libopenvino-paddle-frontend 2026.0.0 h7a07914_1 conda-forge
libopenvino-pytorch-frontend 2026.0.0 hecca717_1 conda-forge
libopenvino-tensorflow-frontend 2026.0.0 h78e8023_1 conda-forge
libopenvino-tensorflow-lite-frontend 2026.0.0 hecca717_1 conda-forge
libopus 1.6.1 h280c20c_0 conda-forge
libpciaccess 0.18 hb9d3cd8_0 conda-forge
libplacebo 7.360.1 h9eeb4b2_0 conda-forge
libpng 1.6.58 h421ea60_0 conda-forge
libpq 18.3 h9abb657_0 conda-forge
libprotobuf 6.33.5 h2b00c02_0 conda-forge
librsvg 2.62.1 h4c96295_0 conda-forge
libsanitizer 15.2.0 h90f66d4_18 conda-forge
libsndfile 1.2.2 hc7d488a_2 conda-forge
libsqlite 3.53.1 h0c1763c_0 conda-forge
libssh2 1.11.1 hcf80075_0 conda-forge
libstdcxx 15.2.0 h934c35e_18 conda-forge
libstdcxx-devel_linux-64 15.2.0 hd446a21_118 conda-forge
libstdcxx-ng 15.2.0 hdf11a46_18 conda-forge
libsystemd0 260.1 h6569c3e_0 conda-forge
libtiff 4.7.1 h9d88235_1 conda-forge
libudev1 260.1 h6569c3e_0 conda-forge
libunwind 1.8.3 h65a8314_0 conda-forge
liburing 2.14 hb700be7_0 conda-forge
libusb 1.0.29 h73b1eb8_0 conda-forge
libuuid 2.42 h5347b49_0 conda-forge
libva 2.23.0 he1eb515_0 conda-forge
libvorbis 1.3.7 h54a6638_2 conda-forge
libvpl 2.16.0 h54a6638_0 conda-forge
libvpx 1.15.2 hecca717_0 conda-forge
libvulkan-loader 1.4.341.0 h5279c79_0 conda-forge
libwebp-base 1.6.0 hd42ef1d_0 conda-forge
libxcb 1.17.0 h8a09558_0 conda-forge
libxcrypt 4.4.36 hd590300_1 conda-forge
libxkbcommon 1.13.1 hca5e8e5_0 conda-forge
libxml2 2.15.3 h49c6c72_0 conda-forge
libxml2-16 2.15.3 hca6bf5a_0 conda-forge
libzlib 1.3.2 h25fd6f3_2 conda-forge
markupsafe 3.0.3 py310h3406613_1 conda-forge
mccabe 0.7.0 pyhd8ed1ab_1 conda-forge
mpg123 1.32.9 hc50e24c_0 conda-forge
ncurses 6.6 hdb14827_0 conda-forge
numpy 2.2.5 py310h35d6838_3
numpy-base 2.2.5 py310h4bc27c9_3
nvidia-libnvcomp-cu12 5.2.0.13 pypi_0 pypi
nvidia-nvjpeg2k-cu12 0.10.0.49 pypi_0 pypi
nvidia-nvtiff-cu12 0.7.0.79 pypi_0 pypi
ocl-icd 2.3.3 hb9d3cd8_0 conda-forge
opencl-headers 2025.06.13 hecca717_0 conda-forge
opencv 4.13.0 qt6_py310h1a5f3ab_608 conda-forge
openexr 3.4.11 h9f1635d_0 conda-forge
openh264 2.6.0 hc22cd8d_0 conda-forge
openjpeg 2.5.4 h55fea9a_0 conda-forge
openjph 0.27.0 h8d634f6_0 conda-forge
openldap 2.6.13 hbde042b_0 conda-forge
openssl 3.6.2 h35e630c_0 conda-forge
packaging 26.2 pyhc364b38_0 conda-forge
pango 1.56.4 hda50119_1 conda-forge
pcre2 10.47 haa7fec5_0 conda-forge
pillow 12.2.0 pypi_0 pypi
pip 26.1.1 pyh8b19718_0 conda-forge
pixman 0.46.4 h54a6638_1 conda-forge
pkg-config 0.29.2 h4bc722e_1009 conda-forge
pluggy 1.6.0 pypi_0 pypi
pthread-stubs 0.4 hb9d3cd8_1002 conda-forge
pugixml 1.15 h3f63f65_0 conda-forge
pulseaudio-client 17.0 h9a6aba3_3 conda-forge
py-opencv 4.13.0 qt6_py310h510e9db_608 conda-forge
pycodestyle 2.14.0 pyhd8ed1ab_0 conda-forge
pydicom 3.0.2 pypi_0 pypi
pyflakes 3.4.0 pyhd8ed1ab_0 conda-forge
pygments 2.20.0 pyhd8ed1ab_0 conda-forge
pylibjpeg 2.1.0 pypi_0 pypi
pylibjpeg-libjpeg 2.4.0 pypi_0 pypi
pylibjpeg-openjpeg 2.5.0 pypi_0 pypi
pysocks 1.7.1 pyha55dd90_7 conda-forge
pytest 9.0.3 pypi_0 pypi
python 3.10.20 h3c07f61_0_cpython conda-forge
python-clang 14.0.6 default_hccd1708_1 conda-forge
python_abi 3.10 8_cp310 conda-forge
qt6-main 6.11.0 pl5321h16c4a6b_4 conda-forge
rav1e 0.8.1 h1fbca29_0 conda-forge
readline 8.3 h853b02a_0 conda-forge
requests 2.33.1 pyhcf101f3_1 conda-forge
s2n 1.7.2 hc5a330e_1 conda-forge
sdl2 2.32.56 h54a6638_0 conda-forge
sdl3 3.4.8 hdeec2a5_0 conda-forge
setuptools 82.0.1 pyh332efcf_0 conda-forge
shaderc 2026.2 h718be3e_0 conda-forge
snappy 1.2.2 h03e3b7b_1 conda-forge
snowballstemmer 3.0.1 pyhd8ed1ab_0 conda-forge
sphinx 4.5.0 pyh6c4a22f_0 conda-forge
sphinx_rtd_theme 1.3.0 pyha770c72_0 conda-forge
sphinxcontrib-applehelp 1.0.4 pyhd8ed1ab_0 conda-forge
sphinxcontrib-devhelp 1.0.2 py_0 conda-forge
sphinxcontrib-htmlhelp 2.0.1 pyhd8ed1ab_0 conda-forge
sphinxcontrib-jquery 4.1 pyhd8ed1ab_1 conda-forge
sphinxcontrib-jsmath 1.0.1 pyhd8ed1ab_1 conda-forge
sphinxcontrib-qthelp 1.0.3 py_0 conda-forge
sphinxcontrib-serializinghtml 1.1.5 pyhd8ed1ab_2 conda-forge
spirv-tools 2026.1 hb700be7_0 conda-forge
svt-av1 4.0.1 hecca717_0 conda-forge
sysroot_linux-64 2.34 h087de78_3 conda-forge
tbb 2023.0.0 h51de99f_1 conda-forge
tk 8.6.13 noxft_h366c992_103 conda-forge
tomli 2.4.1 pypi_0 pypi
typing-extensions 4.15.0 pypi_0 pypi
tzdata 2025c hc9c84f9_1 conda-forge
urllib3 2.6.3 pyhd8ed1ab_0 conda-forge
wayland 1.25.0 hd6090a7_0 conda-forge
wayland-protocols 1.47 hd8ed1ab_0 conda-forge
wheel 0.47.0 pyhd8ed1ab_0 conda-forge
x264 1!164.3095 h166bdaf_2 conda-forge
x265 3.5 h924138e_3 conda-forge
xcb-util 0.4.1 h4f16b4b_2 conda-forge
xcb-util-cursor 0.1.6 hb03c661_0 conda-forge
xcb-util-image 0.4.0 hb711507_2 conda-forge
xcb-util-keysyms 0.4.1 hb711507_0 conda-forge
xcb-util-renderutil 0.3.10 hb711507_0 conda-forge
xcb-util-wm 0.4.2 hb711507_0 conda-forge
xkeyboard-config 2.47 hb03c661_0 conda-forge
xorg-libice 1.1.2 hb9d3cd8_0 conda-forge
xorg-libsm 1.2.6 he73a12e_0 conda-forge
xorg-libx11 1.8.13 he1eb515_0 conda-forge
xorg-libxau 1.0.12 hb03c661_1 conda-forge
xorg-libxcomposite 0.4.7 hb03c661_0 conda-forge
xorg-libxcursor 1.2.3 hb9d3cd8_0 conda-forge
xorg-libxdamage 1.1.6 hb9d3cd8_0 conda-forge
xorg-libxdmcp 1.1.5 hb03c661_1 conda-forge
xorg-libxext 1.3.7 hb03c661_0 conda-forge
xorg-libxfixes 6.0.2 hb03c661_0 conda-forge
xorg-libxi 1.8.2 hb9d3cd8_0 conda-forge
xorg-libxrandr 1.5.5 hb03c661_0 conda-forge
xorg-libxrender 0.9.12 hb9d3cd8_0 conda-forge
xorg-libxscrnsaver 1.2.4 hb9d3cd8_0 conda-forge
xorg-libxtst 1.2.5 hb9d3cd8_3 conda-forge
xorg-libxxf86vm 1.1.7 hb03c661_0 conda-forge
xorg-xorgproto 2025.1 hb03c661_0 conda-forge
zipp 3.23.1 pyhcf101f3_0 conda-forge
zlib 1.3.2 h25fd6f3_2 conda-forge
zstd 1.5.7 hb78ec9c_6 conda-forge
</pre></details>
Relevant log output
I created a script that attempts to use nvImageCodec, GDCM, and decoder_nvimgcodec.py (attempts to use nvImageCodec decoders first before falling back to any others present, like GDCM) to handle these compressed DICOM cases, and then compares GDCM to decoder_nvimgcodec outputs. Results for 3 files of interest shown below:
bad_sequence.dcm (no issues):
File : bad_sequence.dcm
TS=1.2.840.10008.1.2.4.70 BitsAllocated=16 BitsStored=12
[nvimgcodec decoder] decoded shape=(512, 512, 1) dtype=uint16 all_zero=False
[gdcm decoder ] decoded shape=(512, 512) dtype=uint16 all_zero=False
[decoder pipeline ] decoded shape=(512, 512) dtype=uint16 all_zero=False [via nvimgcodec]
[comparison ] MATCH (decoder pipeline pixel-identical to GDCM)
MR (SOF3 P = 12):
File : MR.dcm
TS=1.2.840.10008.1.2.4.70 BitsAllocated=16 BitsStored=12
[nvimgcodec decoder] decoded shape=(320, 320, 1) dtype=uint16 all_zero=True <-- SILENT ZERO-FILL BUG
[gdcm decoder ] decoded shape=(320, 320) dtype=uint16 all_zero=False
[decoder pipeline ] decoded shape=(320, 320) dtype=uint16 all_zero=True [via nvimgcodec] <-- ALL ZERO
[comparison ] MISMATCH <-- PIXEL CORRUPTION max_diff=1092 mean_diff=75.5825
CT (DHT before SOF3):
File : CT.dcm
TS=1.2.840.10008.1.2.4.70 BitsAllocated=16 BitsStored=12
[nvimgcodec decoder] decoded shape=(512, 512, 1) dtype=uint16 all_zero=True <-- SILENT ZERO-FILL BUG
[gdcm decoder ] decoded shape=(512, 512) dtype=uint16 all_zero=False
[decoder pipeline ] decoded shape=(512, 512) dtype=uint16 all_zero=True [via nvimgcodec] <-- ALL ZERO
[comparison ] MISMATCH <-- PIXEL CORRUPTION max_diff=2540 mean_diff=467.2943
Other/Misc.
A fix is implemented in extensions/nvjpeg/lossless_decoder.cpp in canDecode, adding:
- A precision check using
cs_image_info.plane_info[0].precision (the SOF3 P byte read by the nvimgcodec JPEG parser) to reject P in [9,15]
- A
has_dht_before_sof3() pre-scan of the raw bitstream before calling nvjpegJpegStreamParse to reject DHT-before-SOF3 streams
The three aforementioned anonymized DICOM files were converted to .jpeg and used for testing - test/extensions/nvjpeg_ext_lossless_decoder_test.cpp was updated to include these new tests.
References:
- ITU-T T.81 (ISO/IEC 10918-1), Annex B — JPEG interchange format syntax
- MONAI Deploy App SDK PR
Check for duplicates
Version
0.8.0
Describe the bug.
The nvjpeg lossless JPEG decoder (
NVJPEG_BACKEND_LOSSLESS_JPEG) silently produces zero-filled output buffers for two classes of JPEG Lossless (SOF3) stream.nvjpegDecodeBatchedSupportedincorrectly returnsisSupported == 0("supported") for both, making the failures silent — no error is returned, the decode appears to succeed, but the output buffer contains only zeros.These bugs were discovered when testing MAPs built using MONAI Deploy App SDK - CT and MR DICOM studies from Philips scanners were identified that produced zero-filled images that propagated silently through model inference, manifesting as empty segmentations. See PR on App SDK for additional background.
Expected behaviour:
canDecodeshould returnPROCESSING_STATUS_SAMPLE_TYPE_UNSUPPORTEDorPROCESSING_STATUS_CODEC_UNSUPPORTEDfor these streams, allowing the framework to fall back to a capable CPU decoder (e.g.libjpeg-turbo) that handles them correctly.Two independent bugs:
Bug 1 — Sub-16-bit SOF3 precision (P in [9,15]):
When the SOF3
Pbyte encodes a precision of 9–15 (e.g. a Philips scanner writingP=12for a 12-bit series),nvjpegDecodeBatchedsilently zero-fills the output buffer. The GPU kernel appears to assumeP=16for all UINT16 lossless streams and misreads the Huffman-coded bitstream whenPis smaller.Bug 2 — DHT segment before SOF3:
When a DHT (
0xFFC4) segment appears before the SOF3 marker (0xFFC3) — non-standard ordering that is technically valid per ITU-T T.81 Annex B, but emitted by some Philips scanners —nvjpegDecodeBatchedfails to build decode tables correctly and silently zero-fills.In both cases
nvjpegDecodeBatchedSupportedreturns "supported", which is the core defect.The issue is isolated to
lossless_decoder.cpp/NVJPEG_BACKEND_LOSSLESS_JPEG. The baseline JPEG decoder (cuda_decoder.cpp) and the JPEG 2000 decoder (nvjpeg2k_ext) do not seem to be affected.Minimum reproducible example
Three JPEG Lossless frames extracted from DICOM files reproduce the two bugs. All have
BitsStored=12in their DICOM tags but differ in JPEG stream encoding. Anonymized test frames and a proposed fix (with passing tests) are available in the linked PR (below).bad_sequence_frame.jpgMR_frame.jpgCT_frame.jpgEnvironment details
Relevant log output
I created a script that attempts to use
nvImageCodec,GDCM, and decoder_nvimgcodec.py (attempts to usenvImageCodecdecoders first before falling back to any others present, likeGDCM) to handle these compressed DICOM cases, and then comparesGDCMtodecoder_nvimgcodecoutputs. Results for 3 files of interest shown below:bad_sequence.dcm(no issues):File : bad_sequence.dcm TS=1.2.840.10008.1.2.4.70 BitsAllocated=16 BitsStored=12 [nvimgcodec decoder] decoded shape=(512, 512, 1) dtype=uint16 all_zero=False [gdcm decoder ] decoded shape=(512, 512) dtype=uint16 all_zero=False [decoder pipeline ] decoded shape=(512, 512) dtype=uint16 all_zero=False [via nvimgcodec] [comparison ] MATCH (decoder pipeline pixel-identical to GDCM)MR (SOF3 P = 12):
CT (DHT before SOF3):
Other/Misc.
A fix is implemented in
extensions/nvjpeg/lossless_decoder.cppincanDecode, adding:cs_image_info.plane_info[0].precision(the SOF3 P byte read by the nvimgcodec JPEG parser) to reject P in [9,15]has_dht_before_sof3()pre-scan of the raw bitstream before callingnvjpegJpegStreamParseto reject DHT-before-SOF3 streamsThe three aforementioned anonymized DICOM files were converted to
.jpegand used for testing -test/extensions/nvjpeg_ext_lossless_decoder_test.cppwas updated to include these new tests.References:
Check for duplicates