Repository navigation
Reduce oversized images while decoding them - #563
Merged
Merged
Conversation
A 19522x27655 Indexed image was expanded to full-resolution RGB and then RGBA, about 6.5 GB at peak, before Skia refused the 2.16 GB pixel buffer because it exceeds its 2 GiB raster limit, so the page failed to render. An image beyond 2^25 pixels or 16384 pixels on a side is now reduced by the smallest whole factor that fits, averaging each block of source pixels. Filtered samples are decoded a band of rows at a time through the existing conversion, and gray and RGB samples are averaged before their RGBA conversion, so no full-resolution intermediate is built. JPEG 2000 images, and samples shorter than their declared rows, are decoded whole and then reduced. The soft-mask combination reuses the same budget search. The page now renders from an 86 MB 3905x5531 image. Decoding takes about as long as before: 1.5 s optimized, 35 s in debug builds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conformance readsDocuments that Safe-PDF reads differently from the base commit, compared with PDFium. A read pdf.js corpus1008 documents compared with Regressions
840 documents of the PDFium corpus read as on Details are in the job summaries of the workflow run. Rerun a case locally with |
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
A page whose image XObject is 19522×27655 px (
/Indexed /DeviceRGB, Flate + RunLength) failed withfailed to create skia raster image from data (19522x27655). Before that, it built every buffer at full resolution:The 2,159,620,440-byte RGBA buffer exceeds Skia's 2 GiB raster limit. A 19522 px side is also wider than GPU texture and browser canvas limits.
Images beyond 2^25 pixels, or 16384 px on a side, are now reduced while they are decoded, by the smallest whole factor that fits. Each output pixel averages its block of source pixels.
factorrows at a time through the existingDecodedSamplesconversion. No full-resolution component or RGBA buffer is built.combined_size) reuses the samePixelBudgetsearch.Results
The page renders from an 86 MB 3905×5531 image. Image decode time:
Follow-ups (not in this PR)
ObjectCollection::insert: 540 MB resident for this file, and 3.8 s of RunLength decoding in debug builds.pdf-jpeg2000.Test plan
cargo testcargo clippy --workspace -- -D warningscargo fmt --checkcargo conformance renderon the file: the page renders and was checked by eye. There was no PDFium reference available locally, so it is not compared against PDFium.🤖 Generated with Claude Code