94 lines
2.8 KiB
Python
94 lines
2.8 KiB
Python
# SPDX-FileCopyrightText: 2024 James R. Barlow
|
|||
|
|
# SPDX-License-Identifier: MPL-2.0
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import logging
|
||
|
|
|
||
|
|
import pikepdf
|
||
|
|
import pytest
|
||
|
|
from pikepdf import Name
|
||
|
|
|
||
|
|
from ocrmypdf._graft import discard_page_thumbnails
|
||
|
|
|
||
|
|
from .conftest import check_ocrmypdf
|
||
|
|
|
||
|
|
# pylint: disable=redefined-outer-name
|
||
|
|
|
||
|
|
|
||
|
|
def _add_thumbnail(pdf: pikepdf.Pdf, pageindex: int = 0) -> None:
|
||
|
|
"""Attach a minimal /Thumb image XObject to a page."""
|
||
|
|
width, height = 4, 4
|
||
|
|
thumb = pikepdf.Stream(pdf, b'\x00' * (width * height))
|
||
|
|
thumb.Type = Name.XObject
|
||
|
|
thumb.Subtype = Name.Image
|
||
|
|
thumb.Width = width
|
||
|
|
thumb.Height = height
|
||
|
|
thumb.ColorSpace = Name.DeviceGray
|
||
|
|
thumb.BitsPerComponent = 8
|
||
|
|
pdf.pages[pageindex].obj.Thumb = pdf.make_indirect(thumb)
|
||
|
|
|
||
|
|
|
||
|
|
def test_discard_page_thumbnails_removes_thumbnails(resources):
|
||
|
|
with pikepdf.open(resources / 'francais.pdf') as pdf:
|
||
|
|
# No thumbnails -> nothing to do
|
||
|
|
assert discard_page_thumbnails(pdf) == 0
|
||
|
|
|
||
|
|
_add_thumbnail(pdf, 0)
|
||
|
|
assert Name.Thumb in pdf.pages[0].obj
|
||
|
|
|
||
|
|
assert discard_page_thumbnails(pdf) == 1
|
||
|
|
assert Name.Thumb not in pdf.pages[0].obj
|
||
|
|
|
||
|
|
# Idempotent: a second call finds nothing to remove
|
||
|
|
assert discard_page_thumbnails(pdf) == 0
|
||
|
|
|
||
|
|
|
||
|
|
def test_discard_page_thumbnails_counts_each_page(resources):
|
||
|
|
with pikepdf.open(resources / 'multipage.pdf') as pdf:
|
||
|
|
assert len(pdf.pages) >= 2
|
||
|
|
_add_thumbnail(pdf, 0)
|
||
|
|
_add_thumbnail(pdf, 1)
|
||
|
|
assert discard_page_thumbnails(pdf) == 2
|
||
|
|
assert all(Name.Thumb not in page.obj for page in pdf.pages)
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.fixture
|
||
|
|
def pdf_with_thumbnail(resources, outdir):
|
||
|
|
out = outdir / 'with_thumbnail.pdf'
|
||
|
|
with pikepdf.open(resources / 'graph.pdf') as pdf:
|
||
|
|
_add_thumbnail(pdf, 0)
|
||
|
|
assert Name.Thumb in pdf.pages[0].obj
|
||
|
|
pdf.save(out)
|
||
|
|
return out
|
||
|
|
|
||
|
|
|
||
|
|
def test_thumbnail_discarded_end_to_end(pdf_with_thumbnail, outpdf, caplog):
|
||
|
|
caplog.set_level(logging.DEBUG)
|
||
|
|
check_ocrmypdf(
|
||
|
|
pdf_with_thumbnail,
|
||
|
|
outpdf,
|
||
|
|
'--output-type',
|
||
|
|
'pdf',
|
||
|
|
'--plugin',
|
||
|
|
'tests/plugins/tesseract_noop.py',
|
||
|
|
)
|
||
|
|
with pikepdf.open(outpdf) as pdf:
|
||
|
|
assert all(Name.Thumb not in page.obj for page in pdf.pages)
|
||
|
|
assert 'thumbnail' in caplog.text.lower()
|
||
|
|
|
||
|
|
|
||
|
|
def test_thumbnail_discarded_with_ocr_engine_none(pdf_with_thumbnail, outpdf):
|
||
|
|
# Even in pure image-processing mode, OCRmyPDF rewrites the PDF, which can
|
||
|
|
# alter page appearance, so the stale thumbnail must still be discarded.
|
||
|
|
check_ocrmypdf(
|
||
|
|
pdf_with_thumbnail,
|
||
|
|
outpdf,
|
||
|
|
'--ocr-engine',
|
||
|
|
'none',
|
||
|
|
'--output-type',
|
||
|
|
'pdf',
|
||
|
|
)
|
||
|
|
with pikepdf.open(outpdf) as pdf:
|
||
|
|
assert all(Name.Thumb not in page.obj for page in pdf.pages)
|