)]}'
{
  "commit": "fb09d84c50e95b848f75d61a7c3859cf0c32a749",
  "tree": "6cfb6746a5acaf3de45f58b6d9824860de623816",
  "parents": [
    "afaf7ae5a2a2797b722667995a5ce64b4cad6135"
  ],
  "author": {
    "name": "Lei Zhang",
    "email": "thestig@chromium.org",
    "time": "Fri Jul 10 16:55:25 2026 -0700"
  },
  "committer": {
    "name": "pdfium-scoped@luci-project-accounts.iam.gserviceaccount.com",
    "email": "pdfium-scoped@luci-project-accounts.iam.gserviceaccount.com",
    "time": "Fri Jul 10 16:55:25 2026 -0700"
  },
  "message": "Revert \"Decode JPEGs at reduced size via libjpeg scale_denom\"\n\nThis reverts commit 009b91d9d95d998fa7e8e09c55f716cb42d99546.\n\nReason for revert: Signifincantly slows down rendering in some cases.\n\nFailure Link: https://ci.chromium.org/ui/p/chromium/builders/ci/win11-arm64-dbg-tests/12279/overview\n\nOriginal change\u0027s description:\n\u003e Decode JPEGs at reduced size via libjpeg scale_denom\n\u003e\n\u003e JPEGs store image data in 8x8 DCT tiles in the frequency domain. To\n\u003e restore an 8x8 tile in the image domain, an IDCT is computed, using up\n\u003e to 64 coefficients.\n\u003e\n\u003e If a JPEG with large dimensions is drawn at small scale on screen,\n\u003e pdfium used to completely decompress the JPEG to large size, doing a\n\u003e full IDCT for each tile, and then scale it down at decode time.\n\u003e\n\u003e Using scale_denom, pdfium can instead decode the image at 1/8th (or\n\u003e 1/4th, 1/2th) its size (in each dimension) by not doing the full IDCT,\n\u003e but instead only taking the one DC term (for 1/8th), or 2x2 or 4x4\n\u003e coefficents (for 1/4th, 1/2th).\n\u003e\n\u003e This not just saves work decoding the image, it also outputs a smaller\n\u003e image that is faster to downsample when painting it. For most images,\n\u003e this shouldn\u0027t look perceptively different than downsampling from the\n\u003e large bitmap.\n\u003e\n\u003e This kind of matches what Blink does when decoding JPEGs [1], and\n\u003e morally matches what pdfium already does for JPEG2000s after\n\u003e https://pdfium-review.googlesource.com/c/pdfium/+/99970.\n\u003e\n\u003e (Note that CPDF_ImageRenderer::StartLoadDIBBase() in\n\u003e cpdf_imagerenderer.cpp passes in the page size as max_size_required,\n\u003e which cpdf_dib.cpp uses to compute resolution_levels_to_skip. So image\n\u003e decoding currently isn\u0027t limited to the size the image is drawn at, but\n\u003e by the size of the bitmap the whole page is drawn at. This can be be\n\u003e improved later.)\n\u003e\n\u003e Depending on what data the encoder writes in padding rows / columns for\n\u003e images that aren\u0027t a multiple of the MCU size, the code might produce\n\u003e artifacts in the last row or column. So only do this for images with\n\u003e sizes a multiple of the MCU for now, see also https://crbug.com/890745\n\u003e and the discussion on\n\u003e https://github.com/libjpeg-turbo/libjpeg-turbo/issues/297. This is\n\u003e unfortunate, but currently there\u0027s no way to do better without hacks.\n\u003e (This also matches what Blink does.)\n\u003e\n\u003e Timing (hyperfine, --render-repeats): a 3072x2304 4:4:4 image drawn onto\n\u003e a 64pt page decodes in 40ms at scale_denom 8 vs 84ms at full resolution.\n\u003e\n\u003e 1:\n\u003e https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc;l\u003d430\n\u003e ...but evidently this is much harder to hit now then when that code was\n\u003e initially added, probably because JPEGs in Chrome now go down the\n\u003e DecodeYUV path, which doesn\u0027t set scale_denom (yet?).\n\u003e\n\u003e Depends on new baseline in\n\u003e https://pdfium-review.googlesource.com/c/pdfium_tests/+/151570\n\u003e and updates DEPS to pick it up.\n\u003e\n\u003e Plumb the existing resolution_levels_to_skip (computed in\n\u003e CPDF_DIB::StartLoadDIBBase from the render device size) into the DCT\n\u003e path. CreateDCTDecoder maps it to a libjpeg scale_denom of 1/2/4/8\n\u003e (capped at 8, the largest power-of-two DCT scaling libjpeg supports) and\n\u003e passes it to JpegModule::CreateDecoder. JpegDecoder sets\n\u003e cinfo.scale_denom before jpeg_start_decompress and reports the\n\u003e scaled-down output dimensions (ceil(dim/scale_denom), matching\n\u003e jpeg_core_output_dimensions). The DIB then adopts the decoder\u0027s reduced\n\u003e dimensions, mirroring the JPX path. libjpeg performs the reduction\n\u003e cheaply inside the IDCT (e.g. 1/8 uses a 1x1 IDCT), so far fewer pixels\n\u003e are produced for images shown much smaller than native.\n\u003e\n\u003e The calls to SetWidth()/SetHeight() are a slight behavior change for all\n\u003e JPEG data for invalid files: Previously, the code used width/height from\n\u003e the PDF dict, now it gets the size from the decoder. These sizes are\n\u003e supposed to match, but if they aren\u0027t, pdfium now uses the other one.\n\u003e This is arguably better, as that size dictates how much data is actually\n\u003e present.\n\u003e\n\u003e Bug: 531782505\n\u003e Change-Id: I66409898d028685813b274e063aedf52200be0dd\n\u003e Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/151550\n\u003e Commit-Queue: Nico Weber \u003cthakis@chromium.org\u003e\n\u003e Reviewed-by: Lei Zhang \u003cthestig@chromium.org\u003e\n\u003e Reviewed-by: Nico Weber \u003cthakis@google.com\u003e\n\n# Not skipping CQ checks because original CL landed \u003e 1 day ago.\n\nBug: 531782505\nChange-Id: If8fa628779381543e6243b75b0b07e26ae87ac12\nReviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/151870\nReviewed-by: Lei Zhang \u003cthestig@chromium.org\u003e\nCommit-Queue: Lei Zhang \u003cthestig@chromium.org\u003e\nBot-Commit: rubber-stamper@appspot.gserviceaccount.com \u003crubber-stamper@appspot.gserviceaccount.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "d69a33839b816959aacf89589e98f78ca3279971",
      "old_mode": 33188,
      "old_path": "DEPS",
      "new_id": "99ec26886685625ab8154e6d3035b75f028342c7",
      "new_mode": 33188,
      "new_path": "DEPS"
    },
    {
      "type": "modify",
      "old_id": "925f22d093da939ec2b1b9ca2abd6bf7b94bc563",
      "old_mode": 33188,
      "old_path": "core/fpdfapi/page/cpdf_dib.cpp",
      "new_id": "ae8949cc6cec1e7a374a68f4fec592d41b7be3d3",
      "new_mode": 33188,
      "new_path": "core/fpdfapi/page/cpdf_dib.cpp"
    },
    {
      "type": "modify",
      "old_id": "c2eccec7ccc4bfb1638c8d610887a9091404cae9",
      "old_mode": 33188,
      "old_path": "core/fpdfapi/page/cpdf_dib.h",
      "new_id": "e576f2972c39a0f204c32980ea0a0575eceeb4a8",
      "new_mode": 33188,
      "new_path": "core/fpdfapi/page/cpdf_dib.h"
    },
    {
      "type": "modify",
      "old_id": "c266a220132ccd58b187c769a5dc7aef92fb066a",
      "old_mode": 33188,
      "old_path": "core/fpdfapi/page/cpdf_pageimagecache_unittest.cpp",
      "new_id": "eed9b1ccbe5fc646768ca76b4ed192f366dceb6c",
      "new_mode": 33188,
      "new_path": "core/fpdfapi/page/cpdf_pageimagecache_unittest.cpp"
    },
    {
      "type": "modify",
      "old_id": "97e663c6bfa22beb2596d818ac7d48a2294c221e",
      "old_mode": 33188,
      "old_path": "core/fpdfapi/page/cpdf_streamparser.cpp",
      "new_id": "612fe2325f6800c20eb22885e4a394ed9ce52380",
      "new_mode": 33188,
      "new_path": "core/fpdfapi/page/cpdf_streamparser.cpp"
    },
    {
      "type": "modify",
      "old_id": "031c5bab32a1d94c078e2c1bfa9a645c7a8211ac",
      "old_mode": 33188,
      "old_path": "core/fxcodec/jpeg/jpegmodule.cpp",
      "new_id": "02b60f95d773ec655b916c2d256ebc8cda3720ad",
      "new_mode": 33188,
      "new_path": "core/fxcodec/jpeg/jpegmodule.cpp"
    },
    {
      "type": "modify",
      "old_id": "94874668bafa21772d23dc350208c8338df26a38",
      "old_mode": 33188,
      "old_path": "core/fxcodec/jpeg/jpegmodule.h",
      "new_id": "b24b65ba2254c32aed2e0ab84c6c93c4c553c0d0",
      "new_mode": 33188,
      "new_path": "core/fxcodec/jpeg/jpegmodule.h"
    },
    {
      "type": "delete",
      "old_id": "f50124c2cb3fbcf3185e9130b38fbf6eb8b0b785",
      "old_mode": 33188,
      "old_path": "testing/resources/jpeg_reduced_size.in",
      "new_id": "0000000000000000000000000000000000000000",
      "new_mode": 0,
      "new_path": "/dev/null"
    },
    {
      "type": "delete",
      "old_id": "d24663e6f0a12550c6fc2d96bb6e346511fa9d90",
      "old_mode": 33188,
      "old_path": "testing/resources/jpeg_reduced_size.pdf",
      "new_id": "0000000000000000000000000000000000000000",
      "new_mode": 0,
      "new_path": "/dev/null"
    },
    {
      "type": "delete",
      "old_id": "46455d3da200a5c3407ac08b919f852a802fc452",
      "old_mode": 33188,
      "old_path": "testing/resources/jpeg_reduced_size_with_smask.in",
      "new_id": "0000000000000000000000000000000000000000",
      "new_mode": 0,
      "new_path": "/dev/null"
    },
    {
      "type": "delete",
      "old_id": "4eee3ee5913007a7ddffc3921b05eb4370348389",
      "old_mode": 33188,
      "old_path": "testing/resources/jpeg_reduced_size_with_smask.pdf",
      "new_id": "0000000000000000000000000000000000000000",
      "new_mode": 0,
      "new_path": "/dev/null"
    },
    {
      "type": "delete",
      "old_id": "f5ee4bdff41f692ce963cf335478128c9dec55d6",
      "old_mode": 33188,
      "old_path": "testing/resources/jpeg_unaligned_no_reduce.in",
      "new_id": "0000000000000000000000000000000000000000",
      "new_mode": 0,
      "new_path": "/dev/null"
    },
    {
      "type": "delete",
      "old_id": "147553ec44138cacd0301e73d2c25bc1cf6eaa20",
      "old_mode": 33188,
      "old_path": "testing/resources/jpeg_unaligned_no_reduce.pdf",
      "new_id": "0000000000000000000000000000000000000000",
      "new_mode": 0,
      "new_path": "/dev/null"
    }
  ]
}
