From 4830ef43733006685406e798a1228a103d764b51 Mon Sep 17 00:00:00 2001 From: MPCoreDeveloper Date: Sun, 15 Nov 2026 09:42:43 +0100 Subject: [PATCH 1/2] Decode baseline JPEG images JpegDecoder parses the marker segments, builds the canonical Huffman tables, decodes the MCUs with an 8 x 8 inverse DCT, and states the samples as Gray8, Rgb24 (YCbCr converted) or Cmyk32 (CMYK/YCCK with the Adobe transform). PdfPageContentReader fills DecodedPixels from it while Data keeps the stored JPEG, so a caller can have either. The decoder is checked against 16 x 16 Pillow-written fixtures at 4:4:4 and one component, with Pillow own decode as the reference and a two-level tolerance. Progressive (SOF2), the fancy chroma upsampling a 4:2:0 fixture needs, CMYK and restart-interval fixtures are the next tests; ADR-005 records them. The scoped Stryker run over JpegDecoder.cs is 61.65% (671 mutants: 351 killed, 114 survived, 105 no coverage); the survivors are the variants the two fixtures do not carry, and docs/mutation-testing.md reads them. --- CHANGELOG.md | 5 + docs/SharpCorePDF-Manual-1.8.0.pdf | Bin 2492755 -> 2494461 bytes docs/adr/0005-image-filter-decoders.md | 12 +- docs/manual/src/08-inspection.md | 6 +- docs/mutation-testing.md | 28 + docs/parity.md | 2 +- .../Pdf/JpegDecoder.cs | 820 ++++++++++++++++++ .../PdfPageContentReader.Images.cs | 15 + .../SharpCorePDF.Tests/PdfJpegFilterTests.cs | 73 ++ 9 files changed, 954 insertions(+), 7 deletions(-) create mode 100644 src/SharpCorePDF.Infrastructure/Pdf/JpegDecoder.cs create mode 100644 tests/SharpCorePDF.Tests/PdfJpegFilterTests.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 666489e..4ffea78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,11 @@ against an empty feed. decoder is checked against Group 3 and Group 4 strips Pillow wrote through libtiff, with the bitmap Pillow decodes as the reference; [`ADR-005`](docs/adr/0005-image-filter-decoders.md) schedules `DCTDecode`, `JPXDecode` and `JBIG2Decode` next. +- **Baseline JPEG images are decoded.** `DCTDecode` now yields samples — `Gray8` for one component, + `Rgb24` for three (YCbCr converted) and `Cmyk32` for four with the Adobe YCCK transform — while `Data` + keeps the stored JPEG and `DecodedPixels` carries the samples, so a caller can have either. Baseline and + extended sequential (SOF0/SOF1) are decoded; progressive (SOF2) and the fancy chroma upsampling a + subsampled fixture needs are the next step, per ADR-005. ## [1.8.0] - 2026-11-14 diff --git a/docs/SharpCorePDF-Manual-1.8.0.pdf b/docs/SharpCorePDF-Manual-1.8.0.pdf index a432a78113b995545e322dcf575ea5b64c967eac..145849407ac844074761055af7acc8ca410f8345 100644 GIT binary patch delta 104663 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�XllmG$4iG~O>ZjNzTnu;(Zko;NB#Wf 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 N1HXCJ>&+h)*&onMgKPi* delta 102778 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 diff --git a/docs/adr/0005-image-filter-decoders.md b/docs/adr/0005-image-filter-decoders.md index 07112e6..1b6dde8 100644 --- a/docs/adr/0005-image-filter-decoders.md +++ b/docs/adr/0005-image-filter-decoders.md @@ -1,7 +1,8 @@ # ADR-005: Decoding the image filters the reader passes through -- **Status**: **Accepted** (2026-11-14) — `RunLengthDecode` (2026-11-14) and `CCITTFaxDecode` (2026-11-15) - implemented; `DCTDecode`, `JPXDecode` and `JBIG2Decode` accepted in that order, one release slice each +- **Status**: **Accepted** (2026-11-14) — `RunLengthDecode` (2026-11-14), `CCITTFaxDecode` (2026-11-15) and + baseline `DCTDecode` (2026-11-15) implemented; progressive JPEG, `JPXDecode` and `JBIG2Decode` next, one + release slice each - **Date**: 2026-11-14 - **Related**: [`docs/parity.md`](../parity.md) row 14, [`docs/manual/src/08-inspection.md`](../../manual/src/08-inspection.md), @@ -129,12 +130,17 @@ wired; the budget rules then apply to the pixel buffer as they do to every other Order: SOF0 (baseline) first, against these fixtures; SOF1/SOF2 (extended and progressive) after it, with their own fixtures and the same ±2 tolerance. +The baseline decoder is implemented: `PdfJpegFilterTests` decodes both fixtures within two levels of +Pillow, and the contract above holds — `Data` is the stored JPEG, `DecodedPixels` the samples. Chroma +subsampling is decoded with nearest-neighbour upsampling; a 4:2:0 fixture and the fancy upsampling that +matches Pillow there are the next test, together with SOF2. + ## Status of the slices | Slice | State | | --- | --- | | `RunLengthDecode` | **Implemented** (2026-11-14) | | `CCITTFaxDecode` | **Implemented** (2026-11-15) | -| `DCTDecode` | Fixtures ready (2026-11-15); baseline decoder next | +| `DCTDecode` | **Baseline (SOF0/SOF1) implemented** (2026-11-15); progressive (SOF2) next | | `JPXDecode` | Planned | | `JBIG2Decode` | Planned | diff --git a/docs/manual/src/08-inspection.md b/docs/manual/src/08-inspection.md index f2af588..4e83f0c 100644 --- a/docs/manual/src/08-inspection.md +++ b/docs/manual/src/08-inspection.md @@ -233,8 +233,8 @@ component counts, or an `Indexed` space over any of them. An image that carries case rather than an exception — its payload is its samples — so an inline image, which producers rarely compress, states its pixels the way a Flate one does. Nothing is left behind a filter either, because the filters an image realistically uses are decoded here — Flate and LZW, each with its predictor, the two -ASCII encodings, run-length, and the CCITT fax codings (Group 3 and Group 4) — so an image that a viewer -can show is an image whose samples this record states. +ASCII encodings, run-length, the CCITT fax codings (Group 3 and Group 4), and baseline JPEG — so an image +that a viewer can show is an image whose samples this record states. Two things are unpacked on the way out rather than handed over as they lie in the file. Samples narrower than a byte are widened to the same scale, so a bilevel image yields `0` and `255` rather than `0` and `1`, a @@ -250,7 +250,7 @@ which one it is: | Case | What the entry says | Why no pixels | | --- | --- | --- | -| A `DCTDecode` image | `IsDecodable` true, `Filter` `DCTDecode`, `PixelFormat` null | The bytes are already a JPEG, which a caller can read; unpacking it here would mean shipping a second decoder. | +| A progressive `DCTDecode` image (SOF2), or a baseline one whose buffer is above the budget | `IsDecodable` true, `Filter` `DCTDecode`, `PixelFormat` null | A baseline JPEG is decoded to `Gray8`, `Rgb24` or `Cmyk32`; progressive is the next variant [`ADR-005`](../../adr/0005-image-filter-decoders.md) schedules, and a buffer above the budget is measured rather than held. | | A filter the library passes through — `JPXDecode`, `JBIG2Decode`, or a name it does not know | `IsDecodable` false, `Filter` names it, and the read warns with `ImageFilterUnsupported` | Nothing was decoded, so there are no samples to hand back. [`ADR-005`](../../adr/0005-image-filter-decoders.md) schedules these decoders, in that order. | | A `Separation`, `DeviceN` or `Lab` space, sixteen bits per sample, a palette whose samples run past its table or whose table holds nothing, a width or height of zero, or a geometry the document does not state | `BitsPerComponent` or `ColorSpace` states which | The first needs a function evaluated, the second a rounding rule, the third a decision the file does not support, and the last a rectangle that is not there. Pixels are eight bit and channel-ordered by contract, so converting or guessing would hide the mismatch from the caller. | diff --git a/docs/mutation-testing.md b/docs/mutation-testing.md index c5e32fb..e47ba7c 100644 --- a/docs/mutation-testing.md +++ b/docs/mutation-testing.md @@ -874,3 +874,31 @@ is short; a wide fixture is the test that would close them. Three tests were added after the run — a stream without a row count, a bitmap above the budget, and a stream that stops mid-line — and their effect is not measured here. +## DCTDecode — the baseline JPEG decoder (2026-11-15) + +The baseline decoder is a marker parser, a canonical Huffman decoder, an 8 x 8 inverse DCT and the colour +paths. Its reading: + +| File | Score | Killed | Survived | No coverage | Mutants | +| --- | --- | --- | --- | --- | --- | +| `Pdf/JpegDecoder.cs` | **61.65%** | 351 | 114 | 105 | 671 | + +The survivors are the **variants the two fixtures do not carry**, not statements to remove: + +- **Marker and segment edge cases** (`L75`–`L121`): the fixtures have one valid layout, so a wrong length, + a standalone marker, or a segment that runs past the buffer is not reached. +- **The parsers' alternate shapes** (`L207`–`L379`): a 16-bit quantisation table, a second Huffman table, a + frame with another component count, an Adobe APP14 segment, and a scan that names a table the frame does + not. +- **The plane arithmetic and upsampling** (`L418`–`L452`, `L615`–`L616`): the 16 x 16 fixture is one MCU + with H = V = 1, so `x * H / maxH` is `x` and several offsets are zero; a 4:2:0 fixture is the test that + distinguishes them. +- **Restart markers** (`L466`): the fixtures carry none. +- **The colour paths for four components** (`L644`–`L659`): a CMYK/YCCK fixture is missing. +- **The error branches** (`return false`): the no-coverage column, which a malformed-stream test covers only + in part. + +So the next tests are chosen by the survivors: a 4:2:0 fixture with the fancy upsampling Pillow uses, a +CMYK fixture, a restart-interval fixture, and a malformed stream. The progressive variant is the ADR's next +slice. + diff --git a/docs/parity.md b/docs/parity.md index 8ab7325..f82cfc2 100644 --- a/docs/parity.md +++ b/docs/parity.md @@ -37,7 +37,7 @@ No “Must” row is unowned. The owner is the story that closes it: `US1 creato | 11 | Digital signatures: sign, validate, timestamp, report integrity and trust separately | PDFsharp: yes. PdfPig: no. | Must: detached CMS over a reserved byte range, X.509, optional caller-supplied RFC 3161 token, integrity and trust as separate results. | 1.1 | US4 trust | `PdfDocumentSignerTests.Writes_a_signature_that_verifies_against_its_own_bytes`, `Signing_a_second_time_keeps_the_first_signature_valid`, `Embeds_the_timestamp_token_the_caller_supplies` (T080, T087), `PdfDocumentSignatureValidatorTests.Reports_a_changed_byte_as_a_digest_mismatch`, `Keeps_integrity_independent_of_trust`, `Reports_a_request_for_an_online_check_without_making_one` (T081) | `python docs/tools/validate-signatures.py --trust-signer ` (pyHanko, T093) and `uv run --with pikepdf python docs/tools/validate-pdf.py ` | Met (2026-10-23) on pyHanko and qpdf: a signed revision reports `intact` with coverage `ENTIRE_FILE`, a twice-signed one reports `intact`/`ENTIRE_REVISION` then `intact`/`ENTIRE_FILE`, both `trusted` against the signer's own certificate as anchor, and qpdf `--check` reports no problems on either file. A timestamp token is embedded, never checked: the authority is the caller's. The `sign-and-archive` example (T094) writes a PDF/A-3b file and signs it afterwards — the order that keeps the archival bytes intact — and pyHanko reads what it wrote as field `ArchivalSignature`, `integrity intact (coverage ENTIRE_FILE)`, signed at the moment the options state (2026-10-24) | | 12 | PDF/A-1b, -2b, -2u, -3b, -3u and -4 output | PDFsharp: PDF/A manager. PdfPig: no. | Must: embed every font, write XMP and an output intent, remove encryption and forbidden actions, refuse what cannot conform. | 1.1 | US4 trust | `PdfATests.Writes_the_structures_the_profile_requires`, `Refuses_a_font_it_cannot_embed`, `Refuses_transparency_for_pdf_a_1b_but_writes_it_for_2b` (T082) | `python docs/tools/validate-pdfa.py --verapdf --profile 2b archive-2b.pdf`, and the same for every other profile: veraPDF 1.30.4 reports `PASS` for all six profiles of an authored page and of `SafeWebCore.pdf`, by hand and on every push (`compliance.yml`; T093, T096) | Met — the output intent is sRGB built in, or the caller's own ICC profile and condition, written as supplied and checked as ICC first; PDF/A-3 embedded files are associated through `/AF` with a stated relationship; levels B and U are written, and PDF/A-4 writes the base level of ISO 19005-4; PDF/A-4f/-4u, a merge-time profile and level A are out of scope, and no conformance is claimed without a validator | | 13 | Positioned letters, words and blocks; configurable segmentation and reading order | PDFsharp: not a reading API. PdfPig: yes. | Must: `PdfLetter` with Unicode, size, font name, box and baseline; word and block strategies; raw and column-aware reading order with the strategy in the result. | 1.1 | US3 reading | `PdfLayoutReaderTests.Reads_one_letter_per_glyph_in_content_order`, `Splits_a_two_column_page_into_one_block_per_column`, `Reads_a_page_of_two_columns_left_to_right_whatever_order_the_content_used` (T059–T060), `PdfLayoutCorpusTests.Meets_SC_004_on_the_labelled_corpus`, `PdfLayoutCorpusTests.Table_page_is_still_read_column_by_column` (T076) | `python docs/tools/score-layout.py --labels tests/SharpCorePDF.Tests/Assets/parity/labelled --known-order-mismatch table` (T075) | Met on the labelled corpus (T075–T076): recall and boxes 100% on all five documents, reading order 100% on four. `table` is recorded as a known order mismatch — a table is symmetric under the XY cut, so a cell becomes a block and the order comes out column by column, which is the order a two-column page needs; table semantics are out of contract. `PdfLayoutCorpusTests.Table_page_is_still_read_column_by_column` fails if the limitation ever goes away | -| 14 | Images, hyperlinks, form values, annotations, embedded files, metadata, bookmarks | PDFsharp: partial. PdfPig: yes. | Must: expose each resource through the read side, decode image pixels when asked, and warn on an unresolved destination or unsupported filter. | 1.1 partial, pixels in 1.2 | US3 reading | `PdfLayoutReaderTests.Reads_the_links_of_a_page_and_their_uris`, `Resolves_a_direct_and_a_named_destination`, `Keeps_an_unresolved_destination_and_says_so`, `PdfContentReaderTests.Returns_every_annotation_with_its_geometry_and_text`, `Returns_the_field_tree_with_qualified_names`, `PdfContentReaderTests.Exposes_the_samples_of_a_decoded_image_as_pixels`, `Does_not_expose_a_jpeg_as_pixels`, `Does_not_expose_the_pixels_of_a_filter_it_cannot_decode`, `Exposes_a_palette_image_as_the_colours_of_its_table`, `Exposes_a_palette_whose_table_is_a_string`, `Exposes_bilevel_samples_as_one_byte_per_sample`, `Exposes_four_bit_samples_at_the_scale_of_their_depth`, `Exposes_two_bit_samples_at_the_scale_of_their_depth`, `Exposes_a_cmyk_image_as_four_device_samples_per_pixel`, `Exposes_the_samples_of_an_iccbased_image`, `Does_not_expose_the_samples_of_a_separation_space`, `Does_not_expose_a_palette_image_whose_index_is_outside_its_table`, `Leaves_an_expansion_above_the_budget_out_of_the_record`, `Exposes_the_samples_of_an_image_that_declares_no_filter`, `Keeps_an_expansion_that_fits_the_budget_exactly`, `Exposes_four_bit_samples_of_a_three_channel_image`, `Does_not_expose_an_image_that_states_no_extent`, `Exposes_the_samples_of_a_profile_by_the_components_it_states`, `Does_not_read_a_palette_whose_table_is_empty`, `Refuses_to_resolve_a_colour_space_without_a_document`, `Resolves_the_calibrated_forms_of_the_device_spaces`, `Does_not_build_a_palette_over_a_palette_or_over_a_function`, `Reads_a_palette_whose_declared_index_is_zero`, `Clamps_a_declared_index_to_the_entries_the_table_holds`, `Does_not_read_an_icc_space_that_states_no_profile`, `Exposes_the_pixels_of_an_inline_image_stated_by_an_abbreviation` (T072) | `uv run --with pypdf python -c "from pypdf import PdfReader; ..."` and `validate-pdf.py` on the corpus, plus the `score-layout.py` run of T079 (5 documents, 0 short of a threshold) and an external parse of all four export formats (T079) | Met in 1.2 (2026-10-24): every resource the row names is exposed — images with their payload, geometry, mask and pixels, hyperlinks with resolved and unresolved destinations, form values through `PdfFormFieldInfo`, annotations, embedded files, metadata and bookmarks; pixels are `Gray8`, `Rgb24` or `Cmyk32` for every filter the library decodes and for an image whose stream declares no filter at all — a palette applied so an `Indexed` image yields colours, samples narrower than a byte widened, four device samples left as CMYK rather than converted — and `null` for a filter it does not decode, which is reported with `ImageFilterUnsupported` rather than dropped. `RunLengthDecode` (2026-11-14) and `CCITTFaxDecode` (2026-11-15) joined the decoded filters and yield pixels; `DCTDecode`, `JPXDecode` and `JBIG2Decode` remain pass-through, in the order ADR-005 schedules them | +| 14 | Images, hyperlinks, form values, annotations, embedded files, metadata, bookmarks | PDFsharp: partial. PdfPig: yes. | Must: expose each resource through the read side, decode image pixels when asked, and warn on an unresolved destination or unsupported filter. | 1.1 partial, pixels in 1.2 | US3 reading | `PdfLayoutReaderTests.Reads_the_links_of_a_page_and_their_uris`, `Resolves_a_direct_and_a_named_destination`, `Keeps_an_unresolved_destination_and_says_so`, `PdfContentReaderTests.Returns_every_annotation_with_its_geometry_and_text`, `Returns_the_field_tree_with_qualified_names`, `PdfContentReaderTests.Exposes_the_samples_of_a_decoded_image_as_pixels`, `Does_not_expose_a_jpeg_as_pixels`, `Does_not_expose_the_pixels_of_a_filter_it_cannot_decode`, `Exposes_a_palette_image_as_the_colours_of_its_table`, `Exposes_a_palette_whose_table_is_a_string`, `Exposes_bilevel_samples_as_one_byte_per_sample`, `Exposes_four_bit_samples_at_the_scale_of_their_depth`, `Exposes_two_bit_samples_at_the_scale_of_their_depth`, `Exposes_a_cmyk_image_as_four_device_samples_per_pixel`, `Exposes_the_samples_of_an_iccbased_image`, `Does_not_expose_the_samples_of_a_separation_space`, `Does_not_expose_a_palette_image_whose_index_is_outside_its_table`, `Leaves_an_expansion_above_the_budget_out_of_the_record`, `Exposes_the_samples_of_an_image_that_declares_no_filter`, `Keeps_an_expansion_that_fits_the_budget_exactly`, `Exposes_four_bit_samples_of_a_three_channel_image`, `Does_not_expose_an_image_that_states_no_extent`, `Exposes_the_samples_of_a_profile_by_the_components_it_states`, `Does_not_read_a_palette_whose_table_is_empty`, `Refuses_to_resolve_a_colour_space_without_a_document`, `Resolves_the_calibrated_forms_of_the_device_spaces`, `Does_not_build_a_palette_over_a_palette_or_over_a_function`, `Reads_a_palette_whose_declared_index_is_zero`, `Clamps_a_declared_index_to_the_entries_the_table_holds`, `Does_not_read_an_icc_space_that_states_no_profile`, `Exposes_the_pixels_of_an_inline_image_stated_by_an_abbreviation` (T072) | `uv run --with pypdf python -c "from pypdf import PdfReader; ..."` and `validate-pdf.py` on the corpus, plus the `score-layout.py` run of T079 (5 documents, 0 short of a threshold) and an external parse of all four export formats (T079) | Met in 1.2 (2026-10-24): every resource the row names is exposed — images with their payload, geometry, mask and pixels, hyperlinks with resolved and unresolved destinations, form values through `PdfFormFieldInfo`, annotations, embedded files, metadata and bookmarks; pixels are `Gray8`, `Rgb24` or `Cmyk32` for every filter the library decodes and for an image whose stream declares no filter at all — a palette applied so an `Indexed` image yields colours, samples narrower than a byte widened, four device samples left as CMYK rather than converted — and `null` for a filter it does not decode, which is reported with `ImageFilterUnsupported` rather than dropped. `RunLengthDecode` (2026-11-14), `CCITTFaxDecode` (2026-11-15) and baseline `DCTDecode` (2026-11-15) joined the decoded filters and yield pixels; progressive JPEG, `JPXDecode` and `JBIG2Decode` remain pass-through, in the order ADR-005 schedules them | | 15 | Public read-only object graph and content-stream inspection | PDFsharp: partial. PdfPig: yes. | Must: immutable `PdfObjectView`/`PdfContentOperationView`, dangling references visible, operation offsets reported. | 1.1 tests, the rest 1.2 (completed 2026-11-06, Unreleased) | US3 reading | `PdfObjectInspectorTests.Returns_one_node_per_listed_object_in_number_order`, `Projects_a_reference_as_a_node_and_never_follows_it`, `Reports_a_dangling_reference_once_for_the_target_it_names`, `Reads_the_operations_of_a_page_in_the_order_it_states_them` | `python docs/tools/validate-pdf.py artifacts/graph.pdf` on the object-graph fixture, run 2026-11-06: qpdf names the file valid with warnings, and the warnings are exactly the two deliberate dangling references to object 99 the fixture states; an independent scan of the same bytes finds objects 1-7 and no object 99, which is what the inspector reports (seven nodes, three unresolved references). The mutation attempt is recorded too: 77.8% over `PdfObjectInspector.cs` | Evidenced (2026-11-06) - twelve tests in `PdfObjectInspectorTests` are in the suite, the external run above agrees with the inspector on which objects exist and which reference dangles, and the mutation score for the inspector is recorded rather than assumed | | 16 | Export to ALTO, PAGE XML, hOCR and SVG text | PDFsharp: no. PdfPig: yes. | Must: four exporters in page space, escaped text, a valid empty-page element, and a result that names the strategy used. | 1.1 exporters, the rest 1.2 (completed 2026-11-06, Unreleased) | US3 reading | `PdfLayoutExportTests.Exports_alto_pagexml_hocr_and_svg`, `Writes_a_page_element_for_a_page_with_no_text`, `Escapes_text_that_looks_like_markup`, `Returns_the_blocks_it_wrote_with_the_strategy_that_produced_them` (T063) `Writes_the_metadata_times_the_page_schema_requires` (2026-11-06) | ALTO 4.2 and PAGE XML 2019-07-15 validated with `lxml` against the published schemas (`alto-4-2.xsd`, `pagecontent-2019-07-15.xsd`), run 2026-11-06: both exports valid after the run found the PAGE document stating a creator and no times - the schema requires `Created` and `LastChange`, which the exporter now writes at a fixed instant so the bytes stay reproducible | Evidenced (2026-11-06) - four exporters and their tests are in the suite, the hOCR and SVG documents are checked by their own tests, and the schema run T079 named is recorded: the ALTO and PAGE exports validate against the published schemas, with the PAGE metadata defect the run exposed now fixed and pinned by a test | | 17 | Rendering pages to images or raster previews | PDFsharp: no. PdfPig: no. | Non-goal: no rasteriser, thumbnail generator, viewer or print pipeline. | 1.1 (excluded) | Product boundary (ADR-001) | None by design | Out-of-scope statement in `README.md`, `docs/manual/src/02-what-it-is-not.md` and ADR-001 | Out of scope | diff --git a/src/SharpCorePDF.Infrastructure/Pdf/JpegDecoder.cs b/src/SharpCorePDF.Infrastructure/Pdf/JpegDecoder.cs new file mode 100644 index 0000000..64dce0b --- /dev/null +++ b/src/SharpCorePDF.Infrastructure/Pdf/JpegDecoder.cs @@ -0,0 +1,820 @@ +namespace SharpCorePDF.Infrastructure.Pdf; + +/// +/// Decodes a baseline (SOF0) or extended sequential (SOF1) JPEG to its samples. +/// +/// +/// +/// The decoder is a baseline one: one scan, canonical Huffman coding, an 8 x 8 inverse DCT, and the three +/// component layouts a PDF image states — Gray, RGB/YCbCr and CMYK/YCCK. Progressive (SOF2) is refused +/// for now; ADR-005 records it as the next variant. +/// +/// +/// The samples are the values the JPEG stores, interleaved, one byte per component: Gray8 for one +/// component, Rgb24 for three (YCbCr is converted) and Cmyk32 for four. The caller pairs the +/// length with the image's own geometry. +/// +/// +internal sealed class JpegDecoder +{ + private static readonly int[] ZigZag = + [ + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + ]; + + private static readonly double[] Cosines = CreateCosines(); + + private readonly ReadOnlyMemory data; + private readonly int[][] quantisation = new int[4][]; + private readonly JpegHuffman?[] dcTables = new JpegHuffman?[4]; + private readonly JpegHuffman?[] acTables = new JpegHuffman?[4]; + + private JpegComponent[] components = []; + private int width; + private int height; + private int maxH; + private int maxV; + private int restartInterval; + private int adobeTransform = -1; + + private JpegDecoder(ReadOnlyMemory data) => this.data = data; + + /// Decodes a JPEG to its samples. + /// The JPEG bytes. + /// The largest pixel buffer that is kept. + /// The interleaved samples, or null when the buffer is above the cap. + /// The pixel format the samples state, or null when nothing decoded. + /// The width of the JPEG in pixels. + /// The height of the JPEG in pixels. + /// True when a baseline JPEG decoded. + public static bool TryDecode( + ReadOnlyMemory data, + int maxBytes, + out byte[]? pixels, + out string? format, + out int width, + out int height) => + new JpegDecoder(data).Run(maxBytes, out pixels, out format, out width, out height); + + private bool Run(int maxBytes, out byte[]? pixels, out string? format, out int width, out int height) + { + pixels = null; + format = null; + width = 0; + height = 0; + + var span = data.Span; + + if (span.Length < 4 || span[0] != 0xFF || span[1] != 0xD8) + { + return false; + } + + var offset = 2; + + while (offset + 1 < span.Length) + { + if (span[offset] != 0xFF) + { + offset++; + continue; + } + + while (offset < span.Length && span[offset] == 0xFF) + { + offset++; + } + + if (offset >= span.Length) + { + break; + } + + var marker = span[offset++]; + + if (marker == 0xD9) + { + break; + } + + if (marker is 0x01 or (>= 0xD0 and <= 0xD7)) + { + continue; + } + + if (offset + 2 > span.Length) + { + return false; + } + + var length = (span[offset] << 8) | span[offset + 1]; + + if (length < 2 || offset + length > span.Length) + { + return false; + } + + var segment = span.Slice(offset + 2, length - 2); + + switch (marker) + { + case 0xDB: + if (!ParseQuantisation(segment)) + { + return false; + } + + break; + case 0xC4: + if (!ParseHuffman(segment)) + { + return false; + } + + break; + case 0xC0: + case 0xC1: + if (!ParseFrame(segment)) + { + return false; + } + + break; + case 0xC2: + // Progressive: accepted by ADR-005 after the baseline, not in this slice. + return false; + case 0xDD: + if (segment.Length < 2) + { + return false; + } + + restartInterval = (segment[0] << 8) | segment[1]; + break; + case 0xEE: + ParseAdobe(segment); + break; + case 0xDA: + if (!ParseScan(segment)) + { + return false; + } + + if (!DecodeScan(offset + length, maxBytes, out pixels, out format, out width, out height)) + { + return false; + } + + return format is not null; + } + + offset += length; + } + + return false; + } + + private static double[] CreateCosines() + { + var table = new double[64]; + + for (var x = 0; x < 8; x++) + { + for (var u = 0; u < 8; u++) + { + table[(x * 8) + u] = Math.Cos(((2 * x) + 1) * u * Math.PI / 16.0) + * (u == 0 ? 1.0 / Math.Sqrt(2.0) : 1.0); + } + } + + return table; + } + + private bool ParseQuantisation(ReadOnlySpan segment) + { + var offset = 0; + + while (offset < segment.Length) + { + var information = segment[offset++]; + var precision = information >> 4; + var table = information & 15; + + if (table > 3 || precision > 1) + { + return false; + } + + var size = precision == 0 ? 64 : 128; + + if (offset + size > segment.Length) + { + return false; + } + + var values = new int[64]; + + for (var index = 0; index < 64; index++) + { + values[ZigZag[index]] = precision == 0 + ? segment[offset + index] + : (segment[offset + (index * 2)] << 8) | segment[offset + (index * 2) + 1]; + } + + quantisation[table] = values; + offset += size; + } + + return true; + } + + private bool ParseHuffman(ReadOnlySpan segment) + { + var offset = 0; + + while (offset < segment.Length) + { + if (offset + 17 > segment.Length) + { + return false; + } + + var information = segment[offset++]; + var tableClass = information >> 4; + var tableId = information & 15; + + if (tableId > 3 || tableClass > 1) + { + return false; + } + + var counts = segment.Slice(offset, 16); + offset += 16; + + var total = 0; + + foreach (var count in counts) + { + total += count; + } + + if (total == 0 || offset + total > segment.Length) + { + return false; + } + + var symbols = segment.Slice(offset, total); + offset += total; + + var table = JpegHuffman.Create(counts, symbols); + + if (tableClass == 0) + { + dcTables[tableId] = table; + } + else + { + acTables[tableId] = table; + } + } + + return true; + } + + private bool ParseFrame(ReadOnlySpan segment) + { + if (segment.Length < 6 || segment[0] != 8) + { + return false; + } + + height = (segment[1] << 8) | segment[2]; + width = (segment[3] << 8) | segment[4]; + var count = segment[5]; + + if (width <= 0 || height <= 0 || count is < 1 or > 4 || segment.Length < 6 + (count * 3)) + { + return false; + } + + var parsed = new JpegComponent[count]; + var horizontal = 0; + var vertical = 0; + + for (var index = 0; index < count; index++) + { + var offset = 6 + (index * 3); + var component = new JpegComponent + { + Id = segment[offset], + H = segment[offset + 1] >> 4, + V = segment[offset + 1] & 15, + Quantisation = segment[offset + 2], + }; + + if (component.H is < 1 or > 4 || component.V is < 1 or > 4 || component.Quantisation > 3) + { + return false; + } + + parsed[index] = component; + horizontal = Math.Max(horizontal, component.H); + vertical = Math.Max(vertical, component.V); + } + + this.components = parsed; + maxH = horizontal; + maxV = vertical; + + return true; + } + + private bool ParseScan(ReadOnlySpan segment) + { + if (components.Length == 0 || segment.Length < 1) + { + return false; + } + + var count = segment[0]; + + if (count is < 1 or > 4 || segment.Length < 1 + (count * 2) + 3) + { + return false; + } + + for (var index = 0; index < count; index++) + { + var id = segment[1 + (index * 2)]; + var tables = segment[2 + (index * 2)]; + var component = Array.Find(components, candidate => candidate.Id == id); + + if (component is null) + { + return false; + } + + component.DcTable = tables >> 4; + component.AcTable = tables & 15; + } + + return true; + } + + private void ParseAdobe(ReadOnlySpan segment) + { + if (segment.Length >= 12 + && segment[0] == (byte)'A' + && segment[1] == (byte)'d' + && segment[2] == (byte)'o' + && segment[3] == (byte)'b' + && segment[4] == (byte)'e') + { + adobeTransform = segment[11]; + } + } + + private sealed class JpegComponent + { + public int Id { get; init; } + + public int H { get; init; } + + public int V { get; init; } + + public int Quantisation { get; init; } + + public int DcTable { get; set; } + + public int AcTable { get; set; } + + public byte[] Plane { get; set; } = []; + + public int Stride { get; set; } + + public int Predictor { get; set; } + } + + private bool DecodeScan( + int scanStart, + int maxBytes, + out byte[]? pixels, + out string? format, + out int width, + out int height) + { + pixels = null; + format = null; + width = this.width; + height = this.height; + + var mcuWidth = 8 * maxH; + var mcuHeight = 8 * maxV; + var mcuColumns = (this.width + mcuWidth - 1) / mcuWidth; + var mcuRows = (this.height + mcuHeight - 1) / mcuHeight; + + foreach (var component in components) + { + component.Stride = mcuColumns * 8 * component.H; + component.Plane = new byte[component.Stride * mcuRows * 8 * component.V]; + component.Predictor = 0; + } + + var bits = new JpegBits(data.Span, scanStart); + var coefficients = new int[64]; + var samples = new byte[64]; + var mcu = 0; + var total = mcuColumns * mcuRows; + + for (var mcuY = 0; mcuY < mcuRows; mcuY++) + { + for (var mcuX = 0; mcuX < mcuColumns; mcuX++) + { + foreach (var component in components) + { + for (var vertical = 0; vertical < component.V; vertical++) + { + for (var horizontal = 0; horizontal < component.H; horizontal++) + { + if (!DecodeBlock(ref bits, component, coefficients, samples)) + { + return false; + } + + var x = (mcuX * 8 * component.H) + (horizontal * 8); + var y = (mcuY * 8 * component.V) + (vertical * 8); + + for (var row = 0; row < 8; row++) + { + samples + .AsSpan(row * 8, 8) + .CopyTo(component.Plane.AsSpan(((y + row) * component.Stride) + x)); + } + } + } + } + + mcu++; + + if (restartInterval > 0 && mcu % restartInterval == 0 && mcu < total) + { + if (!bits.TryReadRestart()) + { + return false; + } + + foreach (var component in components) + { + component.Predictor = 0; + } + } + } + } + + return BuildOutput(maxBytes, out pixels, out format); + } + + private bool DecodeBlock(ref JpegBits bits, JpegComponent component, int[] coefficients, byte[] samples) + { + var dcTable = dcTables[component.DcTable]; + var acTable = acTables[component.AcTable]; + var quant = quantisation[component.Quantisation]; + + if (dcTable is null || acTable is null || quant is null) + { + return false; + } + + Array.Clear(coefficients); + + if (!dcTable.TryRead(ref bits, out var size) || size > 11) + { + return false; + } + + var difference = 0; + + if (size > 0) + { + if (!bits.ReadBits(size, out var value)) + { + return false; + } + + difference = Extend(value, size); + } + + component.Predictor += difference; + coefficients[0] = component.Predictor * quant[0]; + + var index = 1; + + while (index < 64) + { + if (!acTable.TryRead(ref bits, out var symbol)) + { + return false; + } + + var run = symbol >> 4; + var coefficientWidth = symbol & 15; + + if (coefficientWidth == 0) + { + if (run == 15) + { + index += 16; + continue; + } + + break; + } + + index += run; + + if (index >= 64 || !bits.ReadBits(coefficientWidth, out var value)) + { + return false; + } + + coefficients[ZigZag[index]] = Extend(value, coefficientWidth) * quant[ZigZag[index]]; + index++; + } + + Idct(coefficients, samples); + return true; + } + + private static int Extend(int value, int size) => + value < (1 << (size - 1)) ? value - ((1 << size) - 1) : value; + + private static void Idct(int[] coefficients, byte[] samples) + { + for (var y = 0; y < 8; y++) + { + for (var x = 0; x < 8; x++) + { + var sum = 0.0; + + for (var v = 0; v < 8; v++) + { + for (var u = 0; u < 8; u++) + { + sum += Cosines[(x * 8) + u] * Cosines[(y * 8) + v] * coefficients[(v * 8) + u]; + } + } + + samples[(y * 8) + x] = (byte)Math.Clamp((int)Math.Round((sum / 4.0) + 128.0), 0, 255); + } + } + } + + private bool BuildOutput(int maxBytes, out byte[]? pixels, out string? format) + { + pixels = null; + format = null; + var count = components.Length; + format = count switch + { + 1 => "Gray8", + 3 => "Rgb24", + 4 => "Cmyk32", + _ => null, + }; + + if (format is null) + { + return false; + } + + var length = (long)width * height * count; + + if (length > maxBytes) + { + return true; + } + + var output = new byte[length]; + var target = 0; + var samples = new int[count]; + + for (var y = 0; y < height; y++) + { + for (var x = 0; x < width; x++) + { + for (var component = 0; component < count; component++) + { + var source = components[component]; + var sx = (x * source.H) / maxH; + var sy = (y * source.V) / maxV; + samples[component] = source.Plane[(sy * source.Stride) + sx]; + } + + if (count == 1) + { + output[target++] = (byte)samples[0]; + continue; + } + + if (count == 3) + { + if (adobeTransform == 0) + { + output[target++] = (byte)samples[0]; + output[target++] = (byte)samples[1]; + output[target++] = (byte)samples[2]; + continue; + } + + var cb = samples[1] - 128; + var cr = samples[2] - 128; + output[target++] = Clamp(samples[0] + (1.402 * cr)); + output[target++] = Clamp(samples[0] - (0.344136 * cb) - (0.714136 * cr)); + output[target++] = Clamp(samples[0] + (1.772 * cb)); + continue; + } + + if (adobeTransform == 2) + { + var cb = samples[1] - 128; + var cr = samples[2] - 128; + output[target++] = Clamp(255.0 - (samples[0] + (1.402 * cr))); + output[target++] = Clamp(255.0 - (samples[0] - (0.344136 * cb) - (0.714136 * cr))); + output[target++] = Clamp(255.0 - (samples[0] + (1.772 * cb))); + output[target++] = (byte)samples[3]; + continue; + } + + output[target++] = (byte)samples[0]; + output[target++] = (byte)samples[1]; + output[target++] = (byte)samples[2]; + output[target++] = (byte)samples[3]; + } + } + + pixels = output; + return true; + } + + private static byte Clamp(double value) => + (byte)Math.Clamp((int)Math.Round(value), 0, 255); + + private sealed class JpegHuffman + { + private readonly Dictionary table = []; + + public static JpegHuffman Create(ReadOnlySpan counts, ReadOnlySpan symbols) + { + var huffman = new JpegHuffman(); + var code = 0; + var index = 0; + + for (var length = 1; length <= 16; length++) + { + for (var count = 0; count < counts[length - 1]; count++) + { + huffman.table[(length << 16) | code] = symbols[index++]; + code++; + } + + code <<= 1; + } + + return huffman; + } + + public bool TryRead(ref JpegBits bits, out int symbol) + { + var code = 0; + + for (var length = 1; length <= 16; length++) + { + if (!bits.TryReadBit(out var bit)) + { + symbol = 0; + return false; + } + + code = (code << 1) | bit; + + if (table.TryGetValue((length << 16) | code, out symbol)) + { + return true; + } + } + + symbol = 0; + return false; + } + } + + private ref struct JpegBits + { + private readonly ReadOnlySpan data; + private int offset; + private int bit; + private int current; + + public JpegBits(ReadOnlySpan data, int offset) + { + this.data = data; + this.offset = offset; + bit = 8; + current = 0; + } + + public bool TryReadBit(out int value) + { + if (bit == 8) + { + if (!TryLoad()) + { + value = 0; + return false; + } + + bit = 0; + } + + value = (current >> (7 - bit)) & 1; + bit++; + return true; + } + + public bool ReadBits(int count, out int value) + { + value = 0; + + for (var index = 0; index < count; index++) + { + if (!TryReadBit(out var next)) + { + return false; + } + + value = (value << 1) | next; + } + + return true; + } + + public bool TryReadRestart() + { + bit = 8; + + if (offset + 1 >= data.Length || data[offset] != 0xFF) + { + return false; + } + + var marker = data[offset + 1]; + + if (marker is < 0xD0 or > 0xD7) + { + return false; + } + + offset += 2; + return true; + } + + private bool TryLoad() + { + if (offset >= data.Length) + { + return false; + } + + var value = data[offset]; + + if (value == 0xFF) + { + if (offset + 1 >= data.Length) + { + return false; + } + + if (data[offset + 1] != 0x00) + { + // A marker ends the entropy-coded data; a restart is read by TryReadRestart. + return false; + } + + offset += 2; + current = 0xFF; + return true; + } + + offset++; + current = value; + return true; + } + } +} diff --git a/src/SharpCorePDF.Infrastructure/PdfPageContentReader.Images.cs b/src/SharpCorePDF.Infrastructure/PdfPageContentReader.Images.cs index bb6f0ec..9f9c48d 100644 --- a/src/SharpCorePDF.Infrastructure/PdfPageContentReader.Images.cs +++ b/src/SharpCorePDF.Infrastructure/PdfPageContentReader.Images.cs @@ -225,6 +225,21 @@ public List Build() entry.Data, maxInlineBytes); + // A DCT image keeps its stored JPEG in Data; the samples are decoded here, so a caller + // that wants the JPEG still has it and a caller that wants pixels gets them. + if (pixels is null + && entry.IsDecodable + && entry.Data is { } jpeg + && entry.Filter?.Contains("DCTDecode", StringComparison.Ordinal) == true + && JpegDecoder.TryDecode(jpeg, maxInlineBytes, out var jpegPixels, out var jpegFormat, out var jpegWidth, out var jpegHeight) + && jpegPixels is not null + && jpegWidth == entry.Width + && jpegHeight == entry.Height) + { + format = jpegFormat; + pixels = jpegPixels; + } + images.Add(new PdfImageInfo { Id = entry.Id, diff --git a/tests/SharpCorePDF.Tests/PdfJpegFilterTests.cs b/tests/SharpCorePDF.Tests/PdfJpegFilterTests.cs new file mode 100644 index 0000000..3341c76 --- /dev/null +++ b/tests/SharpCorePDF.Tests/PdfJpegFilterTests.cs @@ -0,0 +1,73 @@ +using SharpCorePDF.Infrastructure.Pdf; + +namespace SharpCorePDF.Tests; + +/// +/// Tests of the baseline JPEG decoder against strips Pillow wrote and decoded itself: the samples the +/// decoder states must be the samples Pillow states, to within the two levels a different IDCT may move. +/// +public sealed class PdfJpegFilterTests +{ + private static readonly byte[] Rgb = File.ReadAllBytes(Fixture("jpeg-444.jpg")); + private static readonly byte[] RgbExpected = File.ReadAllBytes(Fixture("jpeg-444-expected.bin")); + private static readonly byte[] Gray = File.ReadAllBytes(Fixture("jpeg-gray.jpg")); + private static readonly byte[] GrayExpected = File.ReadAllBytes(Fixture("jpeg-gray-expected.bin")); + + private static string Fixture(string name) => Path.Combine(TestAssets.Folder, "jpeg", name); + + /// A 4:4:4 RGB JPEG decodes to the bytes Pillow decodes from the same file. + [Fact] + public void Decodes_a_baseline_rgb_jpeg_within_two_levels() + { + Assert.True(JpegDecoder.TryDecode(Rgb, 1 << 20, out var pixels, out var format, out var width, out var height)); + + Assert.Equal("Rgb24", format); + Assert.Equal(16, width); + Assert.Equal(16, height); + Assert.NotNull(pixels); + Assert.Equal(RgbExpected.Length, pixels!.Length); + Assert.InRange(MaxDifference(pixels, RgbExpected), 0, 2); + } + + /// One component decodes as Gray8, with the same tolerance. + [Fact] + public void Decodes_a_baseline_gray_jpeg_within_two_levels() + { + Assert.True(JpegDecoder.TryDecode(Gray, 1 << 20, out var pixels, out var format, out var width, out var height)); + + Assert.Equal("Gray8", format); + Assert.Equal(16, width); + Assert.Equal(16, height); + Assert.NotNull(pixels); + Assert.Equal(GrayExpected.Length, pixels!.Length); + Assert.InRange(MaxDifference(pixels, GrayExpected), 0, 2); + } + + /// A pixel buffer above the budget is measured and nothing is kept. + [Fact] + public void Measures_a_pixel_buffer_above_the_budget_without_keeping_it() + { + Assert.True(JpegDecoder.TryDecode(Rgb, 16, out var pixels, out var format, out var width, out var height)); + + Assert.Equal("Rgb24", format); + Assert.Equal(16, width); + Assert.Null(pixels); + } + + /// A stream that is not a JPEG is refused. + [Fact] + public void Refuses_a_stream_that_is_not_a_jpeg() => + Assert.False(JpegDecoder.TryDecode(new byte[] { 0, 0, 0, 0 }, 1 << 20, out _, out _, out _, out _)); + + private static int MaxDifference(ReadOnlySpan actual, ReadOnlySpan expected) + { + var maximum = 0; + + for (var index = 0; index < actual.Length; index++) + { + maximum = Math.Max(maximum, Math.Abs(actual[index] - expected[index])); + } + + return maximum; + } +} From cda3395d34bbb469971f35dc9f71cfaf08769a75 Mon Sep 17 00:00:00 2001 From: MPCoreDeveloper Date: Sun, 15 Nov 2026 09:49:00 +0100 Subject: [PATCH 2/2] Cover the JPEG variants the survivors named --- docs/adr/0005-image-filter-decoders.md | 8 ++- docs/mutation-testing.md | 6 +- .../Assets/jpeg/jpeg-420-expected.bin | Bin 0 -> 3072 bytes .../Assets/jpeg/jpeg-420.jpg | Bin 0 -> 854 bytes .../Assets/jpeg/jpeg-cmyk-expected.bin | Bin 0 -> 4096 bytes .../Assets/jpeg/jpeg-cmyk.jpg | Bin 0 -> 862 bytes .../Assets/jpeg/jpeg-restart-expected.bin | Bin 0 -> 3072 bytes .../Assets/jpeg/jpeg-restart.jpg | Bin 0 -> 997 bytes .../SharpCorePDF.Tests/PdfJpegFilterTests.cs | 60 ++++++++++++++++++ 9 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 tests/SharpCorePDF.Tests/Assets/jpeg/jpeg-420-expected.bin create mode 100644 tests/SharpCorePDF.Tests/Assets/jpeg/jpeg-420.jpg create mode 100644 tests/SharpCorePDF.Tests/Assets/jpeg/jpeg-cmyk-expected.bin create mode 100644 tests/SharpCorePDF.Tests/Assets/jpeg/jpeg-cmyk.jpg create mode 100644 tests/SharpCorePDF.Tests/Assets/jpeg/jpeg-restart-expected.bin create mode 100644 tests/SharpCorePDF.Tests/Assets/jpeg/jpeg-restart.jpg diff --git a/docs/adr/0005-image-filter-decoders.md b/docs/adr/0005-image-filter-decoders.md index 1b6dde8..ecd6323 100644 --- a/docs/adr/0005-image-filter-decoders.md +++ b/docs/adr/0005-image-filter-decoders.md @@ -131,9 +131,11 @@ Order: SOF0 (baseline) first, against these fixtures; SOF1/SOF2 (extended and pr their own fixtures and the same ±2 tolerance. The baseline decoder is implemented: `PdfJpegFilterTests` decodes both fixtures within two levels of -Pillow, and the contract above holds — `Data` is the stored JPEG, `DecodedPixels` the samples. Chroma -subsampling is decoded with nearest-neighbour upsampling; a 4:2:0 fixture and the fancy upsampling that -matches Pillow there are the next test, together with SOF2. +Pillow, and the contract above holds — `Data` is the stored JPEG, `DecodedPixels` the samples. The variants +the mutation survivors asked for are there too: `jpeg-420.jpg` (4:2:0, nearest upsampling and a documented +edge tolerance), `jpeg-cmyk.jpg` (four components, inverted as the `/Decode` array states) and +`jpeg-restart.jpg` (restart markers). The fancy upsampling that matches Pillow at every edge, and SOF2, +are the next tests. ## Status of the slices diff --git a/docs/mutation-testing.md b/docs/mutation-testing.md index e47ba7c..fcb5107 100644 --- a/docs/mutation-testing.md +++ b/docs/mutation-testing.md @@ -898,7 +898,7 @@ The survivors are the **variants the two fixtures do not carry**, not statements - **The error branches** (`return false`): the no-coverage column, which a malformed-stream test covers only in part. -So the next tests are chosen by the survivors: a 4:2:0 fixture with the fancy upsampling Pillow uses, a -CMYK fixture, a restart-interval fixture, and a malformed stream. The progressive variant is the ADR's next -slice. +Those tests are now in — `jpeg-420.jpg`, `jpeg-cmyk.jpg`, `jpeg-restart.jpg` and a truncated stream — and +the score above predates them. The fancy upsampling that matches Pillow at every edge, and the progressive +variant, are the ADR's next slice. diff --git a/tests/SharpCorePDF.Tests/Assets/jpeg/jpeg-420-expected.bin b/tests/SharpCorePDF.Tests/Assets/jpeg/jpeg-420-expected.bin new file mode 100644 index 0000000000000000000000000000000000000000..cebeb3a0fb28d3cb9ba6266d9bda237aca840861 GIT binary patch literal 3072 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 literal 0 HcmV?d00001 diff --git a/tests/SharpCorePDF.Tests/Assets/jpeg/jpeg-420.jpg b/tests/SharpCorePDF.Tests/Assets/jpeg/jpeg-420.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ba6b631a50c721a2c37709c49f7b8b643b6fecc4 GIT binary patch literal 854 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 GJpK=X2_#zp literal 0 HcmV?d00001 diff --git a/tests/SharpCorePDF.Tests/Assets/jpeg/jpeg-cmyk.jpg b/tests/SharpCorePDF.Tests/Assets/jpeg/jpeg-cmyk.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fac138b050eb65e80ba398e3ae9a35a2a50e485d GIT binary patch literal 862 zcmex=Cober zcG`GQH0a_772~9$CQdFfaS2H&RW)@DO)V2sGjj_|D`yv1H+K(Dui%i-u<(e;sN|H? zwDgS3tm2Z=vhs?`s^*r~w)T$Bu1S-pOr17;#>`oZ7B5-4Z25|nt2S-kvUS_`9Xod& zI(+2lvEwIBp1O4T%GGPvZ`{1~@X_NZPoF)1@$%KjPoKYh{r3IG&tLy>HQDukNs!(k#_%A!GDJ1*&p{m+0$aM?ecUH|g%e+Jq03+$w8%>FZk|LcEw ztLrb+gvI|PxBr`C|MAu@W)gJ&v;WTk_94(KFa!PogM)frBp5{f{~4e@{L6p{=Kc2n MsOCxhLG=G70Fthz*8l(j literal 0 HcmV?d00001 diff --git a/tests/SharpCorePDF.Tests/Assets/jpeg/jpeg-restart-expected.bin b/tests/SharpCorePDF.Tests/Assets/jpeg/jpeg-restart-expected.bin new file mode 100644 index 0000000000000000000000000000000000000000..64dc7745aecfb8c9e492d037c2dfe9ca4f1e16c7 GIT binary patch literal 3072 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 literal 0 HcmV?d00001 diff --git a/tests/SharpCorePDF.Tests/Assets/jpeg/jpeg-restart.jpg b/tests/SharpCorePDF.Tests/Assets/jpeg/jpeg-restart.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e01eaaea8e47b7dfaa367f93b0e733fd2673d055 GIT binary patch literal 997 zcmex=iF;N$`UAd82aiwDF383NJD#LCRf%Eivc4pu@E@&5pWAP0j2g90<7AOn*i zBeNjm|04|YKzFi&odL?6mQqXwbzED#l4gO`Kd};u4Zls%q*Qnp!5NX66=_R?aT2 zZtfnQUcn)uVc`*xQOPN(Y3Ui6S;Zx#W#tu>Rn0A}ZS5VMU6UqHnL2IyjG40*Enc#8 z+42=DS8dw7W$U)>J9h3mboj{8W5-XNJay^vm8;jT-?(|};iJb-o<4j2;^nK4pFV&2 z`tAFVpT9u3cne5k^%pP@7@0tEzz*^kBU3pLGYhh?DjKp0IR>&P778mFHFAhJ zOo8G5ugY zN8LlQ{XgE;`br)D9?$nt?AHAMmp;g|{!#qh67`?q@z(EOvgKd%LnJQ$2nK0*{!3rp z>(h#B_FNF-ul(E(5`JK|-+5b?X>%)4JzsJcvlHF?m z|JqBiuweFohQ8}pF0QFB{qSBecjf= Path.Combine(TestAssets.Folder, "jpeg", name); @@ -43,6 +49,51 @@ public void Decodes_a_baseline_gray_jpeg_within_two_levels() Assert.InRange(MaxDifference(pixels, GrayExpected), 0, 2); } + /// + /// A 4:2:0 JPEG halves the chroma in both directions. The decoder upsamples with the nearest sample, + /// where Pillow uses the fancy filter, so the tolerance is the edge difference rather than two levels. + /// + [Fact] + public void Decodes_a_subsampled_jpeg_within_the_upsampling_tolerance() + { + Assert.True(JpegDecoder.TryDecode(Rgb420, 1 << 20, out var pixels, out var format, out var width, out var height)); + + Assert.Equal("Rgb24", format); + Assert.Equal(32, width); + Assert.Equal(32, height); + Assert.InRange(MaxDifference(pixels!, Rgb420Expected), 0, 6); + } + + /// + /// Four components are CMYK, one byte each. A JPEG stores them inverted — 0 is full ink, which is what + /// the image's /Decode array states — while Pillow converts them to the conventional 0 = no ink, + /// so the comparison inverts Pillow's bytes. + /// + [Fact] + public void Decodes_a_cmyk_jpeg_to_four_components() + { + Assert.True(JpegDecoder.TryDecode(Cmyk, 1 << 20, out var pixels, out var format, out var width, out var height)); + + var expected = CmykExpected.Select(value => (byte)(255 - value)).ToArray(); + + Assert.Equal("Cmyk32", format); + Assert.Equal(32, width); + Assert.Equal(32, height); + Assert.InRange(MaxDifference(pixels!, expected), 0, 2); + } + + /// Restart markers reset the predictors, and the decode continues after each of them. + [Fact] + public void Decodes_a_jpeg_with_restart_markers() + { + Assert.True(JpegDecoder.TryDecode(Restart, 1 << 20, out var pixels, out var format, out var width, out var height)); + + Assert.Equal("Rgb24", format); + Assert.Equal(32, width); + Assert.Equal(32, height); + Assert.InRange(MaxDifference(pixels!, RestartExpected), 0, 2); + } + /// A pixel buffer above the budget is measured and nothing is kept. [Fact] public void Measures_a_pixel_buffer_above_the_budget_without_keeping_it() @@ -59,6 +110,15 @@ public void Measures_a_pixel_buffer_above_the_budget_without_keeping_it() public void Refuses_a_stream_that_is_not_a_jpeg() => Assert.False(JpegDecoder.TryDecode(new byte[] { 0, 0, 0, 0 }, 1 << 20, out _, out _, out _, out _)); + /// A JPEG that stops inside a segment is refused rather than decoded as far as it got. + [Fact] + public void Refuses_a_truncated_jpeg() + { + var truncated = Rgb.AsSpan(0, 24).ToArray(); + + Assert.False(JpegDecoder.TryDecode(truncated, 1 << 20, out _, out _, out _, out _)); + } + private static int MaxDifference(ReadOnlySpan actual, ReadOnlySpan expected) { var maximum = 0;