From 3d17a60a54651d2ad0695734b646367f6f12e862 Mon Sep 17 00:00:00 2001 From: "James R. Barlow" Date: Fri, 5 Jun 2026 00:30:35 -0700 Subject: [PATCH] feat: add Ink classification type for image mask fill colors (#1688) --- src/ocrmypdf/pdfinfo/__init__.py | 4 ++-- src/ocrmypdf/pdfinfo/_types.py | 14 ++++++++++++++ tests/test_pdfinfo.py | 8 +++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/ocrmypdf/pdfinfo/__init__.py b/src/ocrmypdf/pdfinfo/__init__.py index 3257ea4e..8ee7a581 100644 --- a/src/ocrmypdf/pdfinfo/__init__.py +++ b/src/ocrmypdf/pdfinfo/__init__.py @@ -6,7 +6,7 @@ from __future__ import annotations -from ocrmypdf.pdfinfo._types import Colorspace, Encoding, FloatRect +from ocrmypdf.pdfinfo._types import Colorspace, Encoding, FloatRect, Ink from ocrmypdf.pdfinfo.info import PageInfo, PdfInfo -__all__ = ["Colorspace", "Encoding", "FloatRect", "PageInfo", "PdfInfo"] +__all__ = ["Colorspace", "Encoding", "FloatRect", "Ink", "PageInfo", "PdfInfo"] diff --git a/src/ocrmypdf/pdfinfo/_types.py b/src/ocrmypdf/pdfinfo/_types.py index fa5252cd..cc98c827 100644 --- a/src/ocrmypdf/pdfinfo/_types.py +++ b/src/ocrmypdf/pdfinfo/_types.py @@ -39,6 +39,20 @@ class Encoding(Enum): flate_jpeg = auto() +class Ink(Enum): + """Classification of the fill color used to paint a stencil image mask. + + A stencil (image mask) is painted with the current fill color, so the + color depth needed to rasterize it for OCR depends on that fill color, + not on the mask's 1-bit data. + """ + + # pylint: disable=invalid-name + mono = auto() # black (or no color information to preserve) + gray = auto() # achromatic but not pure black + color = auto() # chromatic, or a fill we cannot prove is achromatic + + FloatRect = tuple[float, float, float, float] FRIENDLY_COLORSPACE: dict[str, Colorspace] = { diff --git a/tests/test_pdfinfo.py b/tests/test_pdfinfo.py index db705877..5d6fd8bb 100644 --- a/tests/test_pdfinfo.py +++ b/tests/test_pdfinfo.py @@ -18,7 +18,7 @@ from reportlab.pdfgen.canvas import Canvas from ocrmypdf import pdfinfo from ocrmypdf.exceptions import InputFileError from ocrmypdf.helpers import IMG2PDF_KWARGS, Resolution -from ocrmypdf.pdfinfo import Colorspace, Encoding +from ocrmypdf.pdfinfo import Colorspace, Encoding, Ink from ocrmypdf.pdfinfo._contentstream import _interpret_contents from ocrmypdf.pdfinfo.layout import PDFPage @@ -290,3 +290,9 @@ def test_image_scale0(image_scale0): ) assert not pi.pages[0]._images[0].dpi.is_finite assert pi.pages[0].dpi == Resolution(0, 0) + + +def test_ink_enum_is_picklable(): + # ImageInfo crosses the worker-process boundary, so Ink must pickle. + for member in (Ink.mono, Ink.gray, Ink.color): + assert pickle.loads(pickle.dumps(member)) is member