Skip to content

[V4] Recover JPEG restart markers through the shared reader - #3258

Draft
JimBobSquarePants wants to merge 3 commits into
release/4.1.xfrom
fix/jpeg-marker-recovery-v4
Draft

JimBobSquarePants wants to merge 3 commits into
release/4.1.xfrom
fix/jpeg-marker-recovery-v4

Conversation

@JimBobSquarePants

Copy link
Copy Markdown
Member

Prerequisites

  • I have written a descriptive pull-request title
  • I have verified that there are no overlapping pull-requests open
  • I have verified that I am following the existing coding patterns and practice as demonstrated in the repository. These follow strict Stylecop rules 👮.
  • I have provided test coverage for my change (where applicable)

Description

Backports #3225 to release/4.1.x.

JPEG header parsing now skips standalone TEM markers without reading the next marker as a segment length. At restart boundaries, the shared reader recovers from TEM and reserved marker codes only with SegmentIntegrityHandling.IgnoreImageData. Strict and IgnoreAncillary reject that damaged scan data. Both Huffman and arithmetic scans use the shared recovery. Arithmetic restart handling also checks the detected marker before resetting the reader.

The cases extend the existing JpegDecoderTests.cs. Stored inputs replace runtime encoding and byte modification. Native libjpeg-turbo produces identical pixels for the clean and recoverable files, with warnings for the damaged files. Tests require exact pixel equality and verify the integrity policies. Invalid required header lengths remain fatal under every policy.

The arithmetic fixtures declare their conditioning tables explicitly. The separate existing failure for progressive arithmetic files that rely on standard AC conditioning defaults remains outside this fix.

Validation: Release JPEG and TIFF tests pass on .NET 8 and .NET 10: 1,449 passed, one existing debug-only skip, zero failed on each target. No public API, tolerances, reference images, or BufferedReadStream code changed.

Fixes #3237

jafin and others added 3 commits October 27, 2026 17:19
…en decoding jpegs

A TEM marker (FF 01) between header segments was read as a marker with a
length field, so the next segment header was consumed as its length and
decoding failed. TEM stands alone like RSTn, so skip it the same way.

Some producers write extraneous bytes before restart markers. Those that
form a TEM or reserved marker (FF 01 to FF BF) were taken as the end of the
scan, which corrupted the rest of the image or made the marker parser fail.
Skip them while looking for the marker that ends a restart interval and
resync at the next marker, as libjpeg does.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JPEG decoder fails or corrupts the image when a stray TEM marker or reserved marker bytes appear in the stream

2 participants