Compare commits

...
4 Commits
4 changed files with 51 additions and 18 deletions
+9
View File
@@ -30,6 +30,15 @@ OCRmyPDF typically supports the three most recent Python versions.
.. |OCRmyPDF PyPI| image:: https://img.shields.io/pypi/v/ocrmypdf.svg
v16.4.3
=======
- Work around pdfminer.six issue where a token on the buffer boundary is incorrectly
parsed as two tokens. :issue:`1361`
- New rules are applied to stencil masks and explicit masks when calculating the
optimal page DPI for rendering. :issue:`1362`
- Fixed attempts to use an incompatible jbig2.EXE provided by TeX Live. :issue:`1363`
v16.4.2
=======
+8 -2
View File
@@ -5,7 +5,7 @@
from __future__ import annotations
from subprocess import PIPE
from subprocess import PIPE, CalledProcessError
from packaging.version import Version
@@ -14,7 +14,13 @@ from ocrmypdf.subprocess import get_version, run
def version() -> Version:
return Version(get_version('jbig2', regex=r'jbig2enc (\d+(\.\d+)*).*'))
try:
version = get_version('jbig2', regex=r'jbig2enc (\d+(\.\d+)*).*')
except CalledProcessError as e:
# TeX Live for Windows provides an incompatible jbig2.EXE which may
# be on the PATH.
raise MissingDependencyError('jbig2enc') from e
return Version(version)
def available():
+29 -13
View File
@@ -369,18 +369,21 @@ class ImageInfo:
pim = PdfImage(pdfimage)
else:
raise ValueError("Either pdfimage or inline must be set")
if pim.obj.get(Name.SMask, None) is not None:
self._width = pim.width
self._height = pim.height
if (smask := pim.obj.get(Name.SMask, None)) is not None:
# SMask is pretty much an alpha channel, but in PDF it's possible
# for channel to have different dimensions than the image
# itself. Some PDF writers use this to create a grayscale stencil
# mask. For our purposes, the effective size is the size of the
# larger component (image or smask).
smask = pim.obj[Name.SMask]
self._width = max(smask.get(Name.Width, 0), pim.width)
self._height = max(smask.get(Name.Height, 0), pim.height)
else:
self._width = pim.width
self._height = pim.height
self._width = max(smask.get(Name.Width, 0), self._width)
self._height = max(smask.get(Name.Height, 0), self._height)
if (mask := pim.obj.get(Name.Mask, None)) is not None:
# If the image has a /Mask entry, it has an explicit mask.
self._width = max(mask.get(Name.Width, 0), self._width)
self._height = max(mask.get(Name.Height, 0), self._height)
# If /ImageMask is true, then this image is a stencil mask
# (Images that draw with this stencil mask will have a reference to
@@ -484,9 +487,18 @@ class ImageInfo:
def renderable(self) -> bool:
"""Whether the image is renderable.
Some PDFs in the wild have invalid images that are not renderable.
Some PDFs in the wild have invalid images that are not renderable,
due to unusual dimensions.
Stencil masks are not also not renderable, since they are not
drawn, but rather they control how rendering happens.
"""
return self.dpi.is_finite and self.width >= 0 and self.height >= 0
return (
self.dpi.is_finite
and self.width >= 0
and self.height >= 0
and self.type_ != 'stencil'
)
@property
def dpi(self) -> Resolution:
@@ -1065,10 +1077,14 @@ class PageInfo:
Returns None if there is no meaningful DPI for the page.
"""
image_dpis = [
image.dpi.to_scalar() for image in self._images if image.renderable
]
image_areas = [image.printed_area for image in self._images if image.renderable]
image_dpis = []
image_areas = []
for image in self._images:
if not image.renderable:
continue
image_dpis.append(image.dpi.to_scalar())
image_areas.append(image.printed_area)
total_drawn_area = sum(image_areas)
if total_drawn_area == 0:
return None
+5 -3
View File
@@ -17,6 +17,7 @@ import pdfminer
import pdfminer.encodingdb
import pdfminer.pdfdevice
import pdfminer.pdfinterp
import pdfminer.psparser
from pdfminer.converter import PDFLayoutAnalyzer
from pdfminer.layout import LAParams, LTChar, LTPage, LTTextBox
from pdfminer.pdfcolor import PDFColorSpace
@@ -58,9 +59,10 @@ def pdfsimplefont__init__(
setattr(PDFSimpleFont, '__init__', pdfsimplefont__init__)
#
# pdfminer patches when creator is PScript5.dll
#
# Patch pdfminer.six buffer size
# The parser doesn't properly handle keyword tokens are split across the end of the
# buffer, so increase the buffer size something far larger than will ever be seen.
pdfminer.psparser.PSBaseParser.BUFSIZ = 256 * 1024 * 1024
def pdftype3font__pscript5_get_height(self):