Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c90d5cd84b | ||
|
|
9898904be7 |
@@ -391,15 +391,17 @@ package manager:
|
|||||||
|
|
||||||
* ``winget install -e --id Python.Python.3.11``
|
* ``winget install -e --id Python.Python.3.11``
|
||||||
* ``winget install -e --id UB-Mannheim.TesseractOCR``
|
* ``winget install -e --id UB-Mannheim.TesseractOCR``
|
||||||
* ``winget install -e --id ArtifexSoftware.GhostScript``
|
|
||||||
|
|
||||||
|
You will need to install Ghostscript manually, `since it does not support automated
|
||||||
|
installs anymore <https://artifex.com/news/ghostscript-10.01.0-disabling-silent-install-option>`_.
|
||||||
|
|
||||||
|
* `Ghostscript download page <https://ghostscript.com/releases/gsdnld.html>`_.`
|
||||||
|
|
||||||
(Or alternately, using the `Chocolatey <https://chocolatey.org/>`_ package manager, install
|
(Or alternately, using the `Chocolatey <https://chocolatey.org/>`_ package manager, install
|
||||||
the following when running in an Administrator command prompt):
|
the following when running in an Administrator command prompt):
|
||||||
|
|
||||||
* ``choco install python3``
|
* ``choco install python3``
|
||||||
* ``choco install --pre tesseract``
|
* ``choco install --pre tesseract``
|
||||||
* ``choco install ghostscript``
|
|
||||||
* ``choco install pngquant`` (optional)
|
* ``choco install pngquant`` (optional)
|
||||||
|
|
||||||
Either set of commands will install the required software. At the mmoment there is no
|
Either set of commands will install the required software. At the mmoment there is no
|
||||||
|
|||||||
@@ -28,6 +28,18 @@ tagged yet.
|
|||||||
|
|
||||||
.. |OCRmyPDF PyPI| image:: https://img.shields.io/pypi/v/ocrmypdf.svg
|
.. |OCRmyPDF PyPI| image:: https://img.shields.io/pypi/v/ocrmypdf.svg
|
||||||
|
|
||||||
|
v15.4.4
|
||||||
|
=======
|
||||||
|
|
||||||
|
- Fixed documentation for installing Ghostscript on Windows. :issue:`1198`
|
||||||
|
- Added warning message about security issue in older versions of Ghostscript.
|
||||||
|
|
||||||
|
v15.4.3
|
||||||
|
=======
|
||||||
|
|
||||||
|
- Fixed deprecation warning in pikepdf older than 8.7.1; pikepdf >= 8.7.1 is
|
||||||
|
now required.
|
||||||
|
|
||||||
v15.4.2
|
v15.4.2
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ dependencies = [
|
|||||||
"img2pdf>=0.4.4",
|
"img2pdf>=0.4.4",
|
||||||
"packaging>=20",
|
"packaging>=20",
|
||||||
"pdfminer.six>=20220319",
|
"pdfminer.six>=20220319",
|
||||||
"pikepdf>=8",
|
"pikepdf>=8.7.1",
|
||||||
"pluggy>=0.13.0",
|
"pluggy>=0.13.0",
|
||||||
"reportlab>=3.6.8",
|
"reportlab>=3.6.8",
|
||||||
"rich>=13",
|
"rich>=13",
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ from pathlib import Path
|
|||||||
|
|
||||||
from pikepdf import (
|
from pikepdf import (
|
||||||
Dictionary,
|
Dictionary,
|
||||||
|
Matrix,
|
||||||
Name,
|
Name,
|
||||||
Operator,
|
Operator,
|
||||||
Page,
|
Page,
|
||||||
Pdf,
|
Pdf,
|
||||||
PdfError,
|
PdfError,
|
||||||
PdfMatrix,
|
|
||||||
Stream,
|
Stream,
|
||||||
parse_content_stream,
|
parse_content_stream,
|
||||||
unparse_content_stream,
|
unparse_content_stream,
|
||||||
@@ -268,13 +268,13 @@ class OcrGrafter:
|
|||||||
mediabox = base_page.mediabox
|
mediabox = base_page.mediabox
|
||||||
wp, hp = mediabox[2] - mediabox[0], mediabox[3] - mediabox[1]
|
wp, hp = mediabox[2] - mediabox[0], mediabox[3] - mediabox[1]
|
||||||
|
|
||||||
translate = PdfMatrix().translated(-wt / 2, -ht / 2)
|
translate = Matrix().translated(-wt / 2, -ht / 2)
|
||||||
untranslate = PdfMatrix().translated(wp / 2, hp / 2)
|
untranslate = Matrix().translated(wp / 2, hp / 2)
|
||||||
corner = PdfMatrix().translated(mediabox[0], mediabox[1])
|
corner = Matrix().translated(mediabox[0], mediabox[1])
|
||||||
# -rotation because the input is a clockwise angle and this formula
|
# -rotation because the input is a clockwise angle and this formula
|
||||||
# uses CCW
|
# uses CCW
|
||||||
text_rotation = -text_rotation % 360
|
text_rotation = -text_rotation % 360
|
||||||
rotate = PdfMatrix().rotated(text_rotation)
|
rotate = Matrix().rotated(text_rotation)
|
||||||
|
|
||||||
# Because of rounding of DPI, we might get a text layer that is not
|
# Because of rounding of DPI, we might get a text layer that is not
|
||||||
# identically sized to the target page. Scale to adjust. Normally this
|
# identically sized to the target page. Scale to adjust. Normally this
|
||||||
@@ -285,12 +285,13 @@ class OcrGrafter:
|
|||||||
scale_y = hp / ht
|
scale_y = hp / ht
|
||||||
|
|
||||||
# log.debug('%r', scale_x, scale_y)
|
# log.debug('%r', scale_x, scale_y)
|
||||||
scale = PdfMatrix().scaled(scale_x, scale_y)
|
scale = Matrix().scaled(scale_x, scale_y)
|
||||||
|
|
||||||
# Translate the text so it is centered at (0, 0), rotate it there, adjust
|
# Translate the text so it is centered at (0, 0), rotate it there, adjust
|
||||||
# for a size different between initial and text PDF, then untranslate, and
|
# for a size different between initial and text PDF, then untranslate, and
|
||||||
# finally move the lower left corner to match the mediabox
|
# finally move the lower left corner to match the mediabox. All transforms
|
||||||
ctm = translate @ rotate @ scale @ untranslate @ corner
|
# must be premultiplied so they are applied in reverse order here.
|
||||||
|
ctm = corner @ untranslate @ scale @ rotate @ translate
|
||||||
|
|
||||||
base_resources = _ensure_dictionary(base_page.obj, Name.Resources)
|
base_resources = _ensure_dictionary(base_page.obj, Name.Resources)
|
||||||
base_xobjs = _ensure_dictionary(base_resources, Name.XObject)
|
base_xobjs = _ensure_dictionary(base_resources, Name.XObject)
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from packaging.version import Version
|
||||||
|
|
||||||
from ocrmypdf import hookimpl
|
from ocrmypdf import hookimpl
|
||||||
from ocrmypdf._exec import ghostscript
|
from ocrmypdf._exec import ghostscript
|
||||||
from ocrmypdf.exceptions import MissingDependencyError
|
from ocrmypdf.exceptions import MissingDependencyError
|
||||||
@@ -58,8 +60,15 @@ def check_options(options):
|
|||||||
if gs_version in BLACKLISTED_GS_VERSIONS:
|
if gs_version in BLACKLISTED_GS_VERSIONS:
|
||||||
raise MissingDependencyError(
|
raise MissingDependencyError(
|
||||||
f"Ghostscript {gs_version} contains serious regressions and is not "
|
f"Ghostscript {gs_version} contains serious regressions and is not "
|
||||||
"supported. Please upgrade to a newer version, or downgrade to the "
|
"supported. Please upgrade to a newer version."
|
||||||
"previous version."
|
)
|
||||||
|
if gs_version < Version('10.02.0'):
|
||||||
|
log.warning(
|
||||||
|
f"The installed version of Ghostscript {gs_version}, contains a remote "
|
||||||
|
"code execution security vulnerability. Please upgrade to a newer "
|
||||||
|
"version. For details see CVE-2023-43115. The issue is not known to "
|
||||||
|
"affect OCRmyPDF or processing PDFs with Ghostscript, but upgrading "
|
||||||
|
"Ghostscript is recommended."
|
||||||
)
|
)
|
||||||
|
|
||||||
if options.output_type == 'pdfa':
|
if options.output_type == 'pdfa':
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ from warnings import warn
|
|||||||
|
|
||||||
from pdfminer.layout import LTPage, LTTextBox
|
from pdfminer.layout import LTPage, LTTextBox
|
||||||
from pikepdf import (
|
from pikepdf import (
|
||||||
|
Matrix,
|
||||||
Name,
|
Name,
|
||||||
Object,
|
Object,
|
||||||
Page,
|
Page,
|
||||||
Pdf,
|
Pdf,
|
||||||
PdfImage,
|
PdfImage,
|
||||||
PdfInlineImage,
|
PdfInlineImage,
|
||||||
PdfMatrix,
|
|
||||||
Stream,
|
Stream,
|
||||||
UnsupportedImageTypeError,
|
UnsupportedImageTypeError,
|
||||||
parse_content_stream,
|
parse_content_stream,
|
||||||
@@ -209,7 +209,7 @@ def _interpret_contents(contentstream: Object, initial_shorthand=UNIT_SQUARE):
|
|||||||
CTM unchanged.
|
CTM unchanged.
|
||||||
"""
|
"""
|
||||||
stack = []
|
stack = []
|
||||||
ctm = PdfMatrix(initial_shorthand)
|
ctm = Matrix(initial_shorthand)
|
||||||
xobject_settings: list[XobjectSettings] = []
|
xobject_settings: list[XobjectSettings] = []
|
||||||
inline_images: list[InlineSettings] = []
|
inline_images: list[InlineSettings] = []
|
||||||
name_index = defaultdict(lambda: [])
|
name_index = defaultdict(lambda: [])
|
||||||
@@ -240,7 +240,7 @@ def _interpret_contents(contentstream: Object, initial_shorthand=UNIT_SQUARE):
|
|||||||
# to do. Just pretend nothing happened, keep calm and carry on.
|
# to do. Just pretend nothing happened, keep calm and carry on.
|
||||||
warn("PDF graphics stack underflowed - PDF may be malformed")
|
warn("PDF graphics stack underflowed - PDF may be malformed")
|
||||||
elif operator == 'cm':
|
elif operator == 'cm':
|
||||||
ctm = PdfMatrix(operands) @ ctm
|
ctm = Matrix(operands) @ ctm
|
||||||
elif operator == 'Do':
|
elif operator == 'Do':
|
||||||
image_name = operands[0]
|
image_name = operands[0]
|
||||||
settings = XobjectSettings(
|
settings = XobjectSettings(
|
||||||
@@ -614,12 +614,12 @@ def _process_content_streams(
|
|||||||
):
|
):
|
||||||
# Set the CTM to the state it was when the "Do" operator was
|
# Set the CTM to the state it was when the "Do" operator was
|
||||||
# encountered that is drawing this instance of the Form XObject
|
# encountered that is drawing this instance of the Form XObject
|
||||||
ctm = PdfMatrix(shorthand) if shorthand else PdfMatrix.identity()
|
ctm = Matrix(shorthand) if shorthand else Matrix()
|
||||||
|
|
||||||
# A Form XObject may provide its own matrix to map form space into
|
# A Form XObject may provide its own matrix to map form space into
|
||||||
# user space. Get this if one exists
|
# user space. Get this if one exists
|
||||||
form_shorthand = container.get(Name.Matrix, PdfMatrix.identity())
|
form_shorthand = container.get(Name.Matrix, Matrix())
|
||||||
form_matrix = PdfMatrix(form_shorthand)
|
form_matrix = Matrix(form_shorthand)
|
||||||
|
|
||||||
# Concatenate form matrix with CTM to ensure CTM is correct for
|
# Concatenate form matrix with CTM to ensure CTM is correct for
|
||||||
# drawing this instance of the XObject
|
# drawing this instance of the XObject
|
||||||
|
|||||||
Reference in New Issue
Block a user