mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-10-08 00:57:14 +00:00
Chore: Tighten thumbnail supersampling edge cases
Pages so large that the computed DPI hit the floor of 1 were still supersampled to 2 DPI, quadrupling the pixel count pdftoppm had to render for an already oversized page. Supersampling is now skipped at that floor. The downsample test also did not prove the factor was applied, because the final 500x5000 clamp hid it in most cases. A 900x1200 render now has to come out at 450x600, which only happens when the downsample runs. The comments on the DPI cap and the clamp are reworded to describe the supersampled pipeline accurately.
This commit is contained in:
1 parent
26efad77ac
commit
f549201b7c
2 files changed
+16
-7
No files matched your search
@@ -79,7 +79,8 @@ _THUMBNAIL_MAX_WIDTH = 500
|
||||
_THUMBNAIL_MAX_HEIGHT = 5000
|
||||
# Used only when the page geometry cannot be read
|
||||
_THUMBNAIL_FALLBACK_DPI = 150
|
||||
# Matches the density the thumbnail was previously rendered at before scaling
|
||||
# Cap on the target density, applied before supersampling: a capped tiny page
|
||||
# is rasterized at twice this and halved to the size a 300 DPI render gave
|
||||
_THUMBNAIL_MAX_DPI = 300
|
||||
# Pages with known geometry are rendered at this multiple of the computed DPI
|
||||
# and downsampled with Lanczos, which keeps text noticeably crisper than
|
||||
@@ -196,14 +197,16 @@ def _compute_thumbnail_dpi(in_path: Path, logging_group=None) -> tuple[int, int]
|
||||
dpi_for_height = _THUMBNAIL_MAX_HEIGHT * 72 / height_pts
|
||||
# The old pipeline rendered at 300 DPI and then shrank to fit, so only
|
||||
# pages too small to reach the thumbnail size even at 300 DPI end up
|
||||
# smaller than it. Rounding up keeps the render at or above the target,
|
||||
# so the shrink-only clamp in encode_thumbnail_webp trims it to exactly
|
||||
# the thumbnail size instead of leaving it a few pixels short.
|
||||
# smaller than it. Rounding up keeps the downsampled render at or above
|
||||
# the target, so the shrink-only clamp in encode_thumbnail_webp trims it
|
||||
# to exactly the thumbnail size instead of leaving it a few pixels short.
|
||||
dpi = max(
|
||||
1,
|
||||
math.ceil(min(_THUMBNAIL_MAX_DPI, dpi_for_width, dpi_for_height)),
|
||||
)
|
||||
return dpi, _THUMBNAIL_SUPERSAMPLE
|
||||
# A page so large it hits the 1 DPI floor is already oversized, so
|
||||
# doubling it would only quadruple the pixel count for no benefit
|
||||
return dpi, 1 if dpi == 1 else _THUMBNAIL_SUPERSAMPLE
|
||||
|
||||
|
||||
def _render_pdf_thumbnail(
|
||||
|
||||
@@ -147,7 +147,11 @@ class TestComputeThumbnailDpi:
|
||||
pytest.param((612.0, 100000.0), (4, 2), id="tall-strip-height-bound"),
|
||||
pytest.param((200.0, 300.0), (180, 2), id="small-page-width-bound"),
|
||||
pytest.param((72.0, 72.0), (300, 2), id="tiny-page-capped-at-300"),
|
||||
pytest.param((1000000.0, 1000000.0), (1, 2), id="huge-page-minimum-one"),
|
||||
pytest.param(
|
||||
(1000000.0, 1000000.0),
|
||||
(1, 1),
|
||||
id="huge-page-minimum-one-unsupersampled",
|
||||
),
|
||||
pytest.param(None, (150, 1), id="unreadable-geometry-fallback"),
|
||||
],
|
||||
)
|
||||
@@ -166,7 +170,8 @@ class TestComputeThumbnailDpi:
|
||||
- The thumbnail DPI is computed
|
||||
THEN:
|
||||
- The DPI is rounded up so the render reaches 500x5000, never
|
||||
exceeds 300, is at least 1, and is supersampled 2x; an unknown
|
||||
exceeds 300, is at least 1, and is supersampled 2x (except at the
|
||||
1 DPI floor); an unknown
|
||||
size gives the plain 150 DPI fallback without supersampling
|
||||
"""
|
||||
mocker.patch(
|
||||
@@ -491,6 +496,7 @@ class TestEncodeThumbnailWebp:
|
||||
pytest.param((1001, 1401), 2, (500, 700), id="2x-odd-rounded"),
|
||||
pytest.param((1000, 1400), 1, (500, 700), id="no-supersample-clamped"),
|
||||
pytest.param((600, 800), 2, (300, 400), id="2x-small-not-enlarged"),
|
||||
pytest.param((900, 1200), 2, (450, 600), id="2x-below-clamp"),
|
||||
],
|
||||
)
|
||||
def test_supersampled_render_downsampled(
|
||||
|
||||
Reference in new issue
Block a user