Repository navigation
Conversation
Long Primitive Point Index List (0066,0040) of POLYGON and POLYLINE annotation groups was encoded and decoded as the one-based index of the first coordinate value of each annotation in Point Coordinates Data, rather than the index of the first point (coordinate tuple), as intended by the standard (clarified on DICOM WG-26). For two 2D polygons where the first has 4 points, highdicom wrote [1, 9] instead of [1, 5]. - Encode point indices in AnnotationGroup - Decode point indices in get_graphic_data(), validating the values and detecting the legacy value-based encoding (with a warning) where the values cannot be valid point indices - Replace unused _get_coordinate_index() helper - Add tests asserting the raw encoded values, legacy decoding and rejection of invalid values - Add migration note to release notes Addresses #466 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses #466.
Problem
For POLYGON and POLYLINE annotation groups, Long Primitive Point Index List (0066,0040) has to give the one-based index of the first point (coordinate tuple) of each annotation. highdicom instead encoded and decoded the index of the first coordinate value. For two 2D polygons where the first has 4 points, highdicom wrote
[1, 9]; the standard requires[1, 5]. See #466 for the full analysis and the WG-26 clarification.Changes
AnnotationGroup.__init__):spansnow counts points per annotation instead of values. The unuseddimensionalityvariable is removed.AnnotationGroup.get_graphic_data()): goes through a new_get_point_offsets()helper, which:ValueErrorotherwise. Previously, invalid values silently produced wrong splits.(idx - 1) % d == 0andidx - 1 < N * d). It then emits aUserWarningand divides by the stored dimensionalityd, so existing files, including the 6,075 IDCpan_cancer_nuclei_seg_dicomseries, still decode correctly.ValueErrorif neither interpretation fits._get_coordinate_index(). It was never called and also assumed value-based indices.TestAnnotationGroupPointIndexListcovering:LongPrimitivePointIndexList([1, 5]) for 2D, 3D with common Z and explicit 3D, for both POLYGON and POLYLINE, followed by a decode check[1, 9],[1, 9],[1, 13]) with a warningdocs/release_notes.rst.Known limitation
The detection uses heuristics. In a legacy value-based file, if every value also happens to be a valid point index, it is decoded as point-based, which is wrong for that file. This happens only when the last annotation contains more than half of all points (2D or common Z) or more than two-thirds (explicit 3D). Single-annotation groups are encoded
[1]either way and are unaffected.Testing
master(13 failed) and pass with this change.2047 passed, 153 skipped(skips are optional codecs/libraries not installed locally).flake8is clean.1.2.826.0.1.3680043.10.511.3.61063851916899676364195955814616690(legacy index list[1 31 57 97 117 155 199 243], 138 points). The patched reader emits the legacy warning and returns 8 polygons with[15, 13, 20, 10, 19, 22, 22, 17]points, the same result as the unpatched reader.Follow-up outside this PR
🤖 Generated with Claude Code