mirror of
https://pdfium.googlesource.com/pdfium
synced 2026-07-31 04:29:37 +08:00
This is a reland of commit 009b91d9d95d998fa7e8e09c55f716cb42d99546 Original change's description: > Decode JPEGs at reduced size via libjpeg scale_denom > > JPEGs store image data in 8x8 DCT tiles in the frequency domain. To > restore an 8x8 tile in the image domain, an IDCT is computed, using up > to 64 coefficients. > > If a JPEG with large dimensions is drawn at small scale on screen, > pdfium used to completely decompress the JPEG to large size, doing a > full IDCT for each tile, and then scale it down at decode time. > > Using scale_denom, pdfium can instead decode the image at 1/8th (or > 1/4th, 1/2th) its size (in each dimension) by not doing the full IDCT, > but instead only taking the one DC term (for 1/8th), or 2x2 or 4x4 > coefficents (for 1/4th, 1/2th). > > This not just saves work decoding the image, it also outputs a smaller > image that is faster to downsample when painting it. For most images, > this shouldn't look perceptively different than downsampling from the > large bitmap. > > This kind of matches what Blink does when decoding JPEGs [1], and > morally matches what pdfium already does for JPEG2000s after > https://pdfium-review.googlesource.com/c/pdfium/+/99970. > > (Note that CPDF_ImageRenderer::StartLoadDIBBase() in > cpdf_imagerenderer.cpp passes in the page size as max_size_required, > which cpdf_dib.cpp uses to compute resolution_levels_to_skip. So image > decoding currently isn't limited to the size the image is drawn at, but > by the size of the bitmap the whole page is drawn at. This can be be > improved later.) > > Depending on what data the encoder writes in padding rows / columns for > images that aren't a multiple of the MCU size, the code might produce > artifacts in the last row or column. So only do this for images with > sizes a multiple of the MCU for now, see also https://crbug.com/890745 > and the discussion on > https://github.com/libjpeg-turbo/libjpeg-turbo/issues/297. This is > unfortunate, but currently there's no way to do better without hacks. > (This also matches what Blink does.) > > Timing (hyperfine, --render-repeats): a 3072x2304 4:4:4 image drawn onto > a 64pt page decodes in 40ms at scale_denom 8 vs 84ms at full resolution. > > 1: > https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc;l=430 > ...but evidently this is much harder to hit now then when that code was > initially added, probably because JPEGs in Chrome now go down the > DecodeYUV path, which doesn't set scale_denom (yet?). > > Depends on new baseline in > https://pdfium-review.googlesource.com/c/pdfium_tests/+/151570 > and updates DEPS to pick it up. > > Plumb the existing resolution_levels_to_skip (computed in > CPDF_DIB::StartLoadDIBBase from the render device size) into the DCT > path. CreateDCTDecoder maps it to a libjpeg scale_denom of 1/2/4/8 > (capped at 8, the largest power-of-two DCT scaling libjpeg supports) and > passes it to JpegModule::CreateDecoder. JpegDecoder sets > cinfo.scale_denom before jpeg_start_decompress and reports the > scaled-down output dimensions (ceil(dim/scale_denom), matching > jpeg_core_output_dimensions). The DIB then adopts the decoder's reduced > dimensions, mirroring the JPX path. libjpeg performs the reduction > cheaply inside the IDCT (e.g. 1/8 uses a 1x1 IDCT), so far fewer pixels > are produced for images shown much smaller than native. > > The calls to SetWidth()/SetHeight() are a slight behavior change for all > JPEG data for invalid files: Previously, the code used width/height from > the PDF dict, now it gets the size from the decoder. These sizes are > supposed to match, but if they aren't, pdfium now uses the other one. > This is arguably better, as that size dictates how much data is actually > present. > > Bug: 531782505 > Change-Id: I66409898d028685813b274e063aedf52200be0dd > Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/151550 > Commit-Queue: Nico Weber <thakis@chromium.org> > Reviewed-by: Lei Zhang <thestig@chromium.org> > Reviewed-by: Nico Weber <thakis@google.com> Bug: 531782505 Change-Id: I42c141839a21c77855b06caded3c79db2e53ed50 Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/151930 Commit-Queue: Nico Weber <thakis@chromium.org> Reviewed-by: Nico Weber <thakis@google.com> Reviewed-by: Lei Zhang <thestig@chromium.org>
39 KiB
39 KiB