Repository navigation
Add ImageInfo.CanDecode and UnsupportedImageFeatureException for PNG Adam7 interlacing - #18
Merged
Merged
Conversation
…Adam7 interlacing Adds ImageInfo.CanDecode (init-only, default true) so GetInfo can report that a well-formed file declares a feature Load cannot decode, without requiring a caller to call Load and catch an exception just to find out. PNG is currently the only codec where this applies: Adam7-interlaced files are well-formed PNG per the specification, but PngCodec.Load has no interlaced-scanline reconstruction logic. Adds UnsupportedImageFeatureException, thrown by PngCodec.Load instead of InvalidDataException for the Adam7 case, so callers can distinguish well-formed-but-unsupported from malformed input without string-matching Exception.Message. Because System.IO.InvalidDataException is sealed, this new type derives from IOException (InvalidDataException's own base) instead - a deliberate, documented behavior change: an existing catch (InvalidDataException) around PngCodec.Load no longer catches the Adam7 case. - ImageInfo.cs: add CanDecode as an init-only property outside the primary constructor, to avoid a binary-incompatible change to the record struct's generated constructor/Deconstruct signature. - UnsupportedImageFeatureException.cs (new): sealed exception type with a Feature token identifying the specific unsupported feature. - PngCodec.cs: ParseIhdr/PngHeader carry InterlaceMethod; Load throws UnsupportedImageFeatureException for Adam7; GetInfo sets CanDecode accordingly. - Tests: renamed/added PngCodec and PngSuite tests for the new exception type and CanDecode; new ImageInfoTests.cs and UnsupportedImageFeatureExceptionTests.cs. - Companion artifacts: reqstream/design/verification docs, README, user guide, and .reviewmark.yaml updated to match. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Unresolved moderate issues remain in exception guidance and ImageInfo default-state behavior.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 5
Open (8)
Correct exception hierarchy guidance · New Fix malformed PNG exception handling guidance · New Define ImageInfo default semantics and test zero initialization · New Document explicit handling for both exception types · New Preserve InvalidDataException compatibility for unsupported features · New Preserve feature token in unsupported PNG exception · New Document unsupported feature exception on string overload · New Correct validateDecodability exception contract · New
What changed in this PR
Adds PNG Adam7 capability detection via ImageInfo.CanDecode and a dedicated unsupported-feature exception.
Changes:
- Adds Adam7 detection and
UnsupportedImageFeatureException. - Updates PNG tests and conformance expectations.
- Updates documentation, requirements, verification, and traceability mappings.
Review identified unresolved API/documentation and default-value issues.
| File | Summary |
|---|---|
test/DemaConsulting.CanvasNet.Tests/Codecs/UnsupportedImageFeatureExceptionTests.cs |
Tests the new exception behavior. |
test/DemaConsulting.CanvasNet.Tests/Codecs/PngSuiteTests.cs |
Updates PNG conformance expectations. |
test/DemaConsulting.CanvasNet.Tests/Codecs/PngCodecTests.cs |
Tests Adam7 handling. |
test/DemaConsulting.CanvasNet.Tests/Codecs/ImageInfoTests.cs |
Tests CanDecode. |
src/DemaConsulting.CanvasNet/Codecs/UnsupportedImageFeatureException.cs |
Defines the unsupported-feature exception. |
src/DemaConsulting.CanvasNet/Codecs/PngCodec.cs |
Detects Adam7 and reports decode capability. |
src/DemaConsulting.CanvasNet/Codecs/ImageInfo.cs |
Adds decode-capability metadata. |
README.md |
Documents pre-decode checks. |
docs/verification/canvas-net/codecs/png-codec.md |
Updates PNG verification records. |
docs/user_guide/introduction.md |
Documents API behavior and usage. |
docs/reqstream/canvas-net/codecs/png-codec.yaml |
Updates PNG requirements. |
docs/reqstream/canvas-net/codecs.yaml |
Updates codec requirements. |
docs/reqstream/canvas-net.yaml |
Updates system requirements. |
docs/design/canvas-net/codecs/png-codec.md |
Updates PNG design details. |
docs/design/canvas-net/codecs.md |
Updates shared codec design guidance. |
docs/design/canvas-net.md |
Updates public API design documentation. |
.reviewmark.yaml |
Registers reviewed artifacts. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…from review - Correct the repeated claim that IOException is a common base for InvalidDataException and UnsupportedImageFeatureException: InvalidDataException derives directly from SystemException, not IOException. A caller that wants to handle both malformed (InvalidDataException) and well-formed-but-unsupported (UnsupportedImageFeatureException) cases together must add two explicit catch clauses, not a single catch (IOException). Fixed in UnsupportedImageFeatureException.cs, docs/design/canvas-net/codecs.md, and docs/user_guide/introduction.md. - Document that default(ImageInfo) (or an uninitialized array element) has CanDecode == false, not true, because a struct's property initializers only run when a declared constructor runs; default(ImageInfo) zero-initializes every field directly. Added ImageInfoTests.ImageInfo_DefaultValue_HasCanDecodeFalse to cover this explicitly. - PngCodec.cs: add the missing UnsupportedImageFeatureException documentation to the Load(string path) overload, and correct the validateDecodability parameter doc on the private ParseIhdr helper (said InvalidDataException, throws UnsupportedImageFeatureException). - README.md: use the feature-and-message UnsupportedImageFeatureException constructor overload in the untrusted-file-triage example, so the example preserves the Feature token instead of discarding it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
One or more issues must be addressed before approval.
Review effort: Lite
Findings: None
Resolved since last review (8)
Preserve InvalidDataException compatibility for unsupported features Document explicit handling for both exception types Define ImageInfo default semantics and test zero initialization Fix malformed PNG exception handling guidance Correct exception hierarchy guidance Correct validateDecodability exception contract Document unsupported feature exception on string overload Preserve feature token in unsupported PNG exception
This was referenced Oct 16, 2026
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.


Summary
Implements Part 1 of the signed-off feedback-driven backlog (well-formed-but-unsupported PNG detection).
Why IOException and not InvalidDataException?
System.IO.InvalidDataException is sealed in .NET, so a new exception type cannot derive from it. UnsupportedImageFeatureException instead derives from IOException, InvalidDataException's own base class.
This is a deliberate, narrow, documented behavior change: an existing catch (InvalidDataException) around PngCodec.Load will no longer catch the Adam7-interlacing case. Callers that want to handle both malformed and well-formed-but-unsupported input together should catch IOException, or add an explicit catch (UnsupportedImageFeatureException).
Scope
Scoped to PNG only. Investigation across all four raster codecs (BMP/PNG/TIFF/JPEG) found Adam7 interlacing is the only case where a codec's Load refuses a file that is otherwise well-formed per its format's own specification; the others already conflate malformed/unsupported at GetInfo time.
Changes
Testing
Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com