InsightSoftwareConsortium / InsightSoftwareConsortium/ITK

BUG: GDCMImageIO mis-decodes single-bit pixel data for DICOM Segmentation Storage (SEG) objects

Open
#6,641 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
1.7k
Forks
748
Avg merge
1d 1h
Merged PRs (30d)
64

Description

`GDCMImageIO` mis-decodes single-bit pixel data for DICOM SEG (Segmentation Storage) objects: instead of unpacked binary 0/1 values it returns unscaled `uint8` values spanning the full 0-255 range. Found while cross-validating against `pydicom` using real-world fixtures from the [highdicom](https://github.com/ImagingDataCommons/highdicom) test suite, during triage of #6639 (the fix for #6629's single-bit row-padding bug) — confirmed this is a **separate, unrelated** bug: identical mismatch reproduces both before and after the #6639 fix.

Reproduction

Fixtures (from `ImagingDataCommons/highdicom` `data/test_files/`, MIT licensed): `seg_image_cr_binary.dcm`, `seg_image_ct_binary.dcm`, `seg_image_ct_binary_overlap.dcm`, `seg_image_ct_binary_single_frame.dcm` — all `SOPClassUID = 1.2.840.10008.5.1.4.1.1.66.4` (Segmentation Storage), `BitsAllocated=1`.

```python
import itk, pydicom
ds = pydicom.dcmread("seg_image_ct_binary_single_frame.dcm")
pa = ds.pixel_array # sum=1832, values are 0/1
img = itk.imread("seg_image_ct_binary_single_frame.dcm", imageio=itk.GDCMImageIO.New())
arr = itk.array_from_image(img) # sum=467160, dtype=uint8, min=0, max=255
```

467160 far exceeds the maximum possible sum (16384) for a 128x128 binary mask — GDCM is not treating the pixel data as single-bit for this SOP Class at all.

Two further SEG fixtures fail outright with `ITK ERROR GDCMImageIO(...): Cannot read requested file` (`seg_image_sm_control_labelmap.dcm`, `_palette_color.dcm`), and four more throw `An invalid logic behavior occurred b1 && cosines.size() == 6` (`seg_image_sm_control.dcm`, `_dots.dcm`, `_numbers.dcm`, `_dots_tiled_full.dcm`) — these are multi-frame SEG objects whose orientation lives only in `PerFrameFunctionalGroupsSequence`, not a top-level `ImageOrientationPatient`. May be the same root cause as the byte-range bug, or a separate one.

Environment

- ITK 6.0.0 (built from `main` post-#6639, and independently reproduced against the 5.4.6 pip wheel)
- pydicom 3.0.2 as ground truth
- macOS (Darwin 25.5.0)

Contributor guide

Open the contributing guide

Research direction

Start with Modules/IO/GDCM/src/itkGDCMImageIO.cxx and reproduce the mismatch using .devlocal/pr6639-triage/highdicom-crossval/crossval.py and the listed highdicom fixtures. Compare single-bit SEG output with pydicom, then investigate the reported multi-frame failures separately. Done means single-bit SEG data yields unpacked 0/1 values and the affected fixtures no longer fail as described.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
computer-vision
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.