Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42713b77d7 | ||
|
|
690f88119d | ||
|
|
78f391536b | ||
|
|
7bdd1828a9 | ||
|
|
a8f513eeeb | ||
|
|
af18bc0684 |
+8
-8
@@ -12,7 +12,7 @@ subprocess call anyway, as this provides isolation of its activities.
|
|||||||
Example
|
Example
|
||||||
=======
|
=======
|
||||||
|
|
||||||
OCRmyPDF one high-level function to run its main engine from an
|
OCRmyPDF provides one high-level function to run its main engine from an
|
||||||
application. The parameters are symmetric to the command line arguments
|
application. The parameters are symmetric to the command line arguments
|
||||||
and largely have the same functions.
|
and largely have the same functions.
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ and largely have the same functions.
|
|||||||
if __name__ == '__main__': # To ensure correct behavior on Windows and macOS
|
if __name__ == '__main__': # To ensure correct behavior on Windows and macOS
|
||||||
ocrmypdf.ocr('input.pdf', 'output.pdf', deskew=True)
|
ocrmypdf.ocr('input.pdf', 'output.pdf', deskew=True)
|
||||||
|
|
||||||
With a few exceptions, all of the command line arguments are available
|
With some exceptions, all of the command line arguments are available
|
||||||
and may be passed as equivalent keywords.
|
and may be passed as equivalent keywords.
|
||||||
|
|
||||||
A few differences are that ``verbose`` and ``quiet`` are not available.
|
A few differences are that ``verbose`` and ``quiet`` are not available.
|
||||||
@@ -41,29 +41,29 @@ execution. To do this, it will:
|
|||||||
- manage the signal flags of its worker processes
|
- manage the signal flags of its worker processes
|
||||||
- execute other subprocesses (forking and executing other programs)
|
- execute other subprocesses (forking and executing other programs)
|
||||||
|
|
||||||
The Python process that calls ``ocrmypdf.ocr()`` must be sufficiently
|
The Python process that calls :func:`ocrmypdf.ocr()` must be sufficiently
|
||||||
privileged to perform these actions.
|
privileged to perform these actions.
|
||||||
|
|
||||||
There currently is no option to manage how jobs are scheduled other
|
There currently is no option to manage how jobs are scheduled other
|
||||||
than the argument ``jobs=`` which will limit the number of worker
|
than the argument ``jobs=`` which will limit the number of worker
|
||||||
processes.
|
processes.
|
||||||
|
|
||||||
Creating a child process to call ``ocrmypdf.ocr()`` is suggested. That
|
Creating a child process to call :func:`ocrmypdf.ocr()` is suggested. That
|
||||||
way your application will survive and remain interactive even if
|
way your application will survive and remain interactive even if
|
||||||
OCRmyPDF fails for any reason.
|
OCRmyPDF fails for any reason.
|
||||||
|
|
||||||
Programs that call ``ocrmypdf.ocr()`` should also install a SIGBUS signal
|
Programs that call :func:`ocrmypdf.ocr()` should also install a SIGBUS signal
|
||||||
handler (except on Windows), to raise an exception if access to a memory
|
handler (except on Windows), to raise an exception if access to a memory
|
||||||
mapped file fails. OCRmyPDF may use memory mapping.
|
mapped file fails. OCRmyPDF may use memory mapping.
|
||||||
|
|
||||||
``ocrmypdf.ocr()`` will take a threading lock to prevent multiple runs of itself
|
:func:`ocrmypdf.ocr()` will take a threading lock to prevent multiple runs of itself
|
||||||
in the same Python interpreter process. This is not thread-safe, because of how
|
in the same Python interpreter process. This is not thread-safe, because of how
|
||||||
OCRmyPDF's plugins and Python's library import system work. If you need to parallelize
|
OCRmyPDF's plugins and Python's library import system work. If you need to parallelize
|
||||||
OCRmyPDF, use processes.
|
OCRmyPDF, use processes.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
On Windows and macOS, the script that calls ``ocrmypdf.ocr()`` must be
|
On Windows and macOS, the script that calls :func:`ocrmypdf.ocr()` must be
|
||||||
protected by an "ifmain" guard (``if __name__ == '__main__'``). If you do
|
protected by an "ifmain" guard (``if __name__ == '__main__'``). If you do
|
||||||
not take at least one of these steps, process semantics will prevent
|
not take at least one of these steps, process semantics will prevent
|
||||||
OCRmyPDF from working correctly.
|
OCRmyPDF from working correctly.
|
||||||
@@ -96,7 +96,7 @@ Exceptions
|
|||||||
|
|
||||||
OCRmyPDF may throw standard Python exceptions, ``ocrmypdf.exceptions.*``
|
OCRmyPDF may throw standard Python exceptions, ``ocrmypdf.exceptions.*``
|
||||||
exceptions, some exceptions related to multiprocessing, and
|
exceptions, some exceptions related to multiprocessing, and
|
||||||
``KeyboardInterrupt``. The parent process should provide an exception
|
:exc:`KeyboardInterrupt`. The parent process should provide an exception
|
||||||
handler. OCRmyPDF will clean up its temporary files and worker processes
|
handler. OCRmyPDF will clean up its temporary files and worker processes
|
||||||
automatically when an exception occurs.
|
automatically when an exception occurs.
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ extensions = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
# Extension settings
|
# Extension settings
|
||||||
|
intersphinx_mapping = {'https://docs.python.org/': None}
|
||||||
napoleon_use_rtype = False
|
napoleon_use_rtype = False
|
||||||
issues_github_path = "jbarlow83/OCRmyPDF"
|
issues_github_path = "jbarlow83/OCRmyPDF"
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,18 @@ wish to use some of its features for working with PDFs.
|
|||||||
for Python 3.6 around that time. The change will be marked with a major
|
for Python 3.6 around that time. The change will be marked with a major
|
||||||
release.
|
release.
|
||||||
|
|
||||||
|
v12.7.0
|
||||||
|
=======
|
||||||
|
|
||||||
|
- Fixed test suite failure when using pikepdf 3.2.0 that was compiled with pybind11
|
||||||
|
2.8.0. :issue:`843`
|
||||||
|
- Improve advice to user about using ``--max-image-mpixels`` if OCR fails for this
|
||||||
|
reason.
|
||||||
|
- Minor documentation fixes. (Thanks to @mara004.)
|
||||||
|
- Don't require importlib-metadata and importlib-resources backports on versions of
|
||||||
|
Python where the standard library implementation is sufficient.
|
||||||
|
(Thanks to Marco Genasci.)
|
||||||
|
|
||||||
v12.6.0
|
v12.6.0
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ install_requires =
|
|||||||
cffi>=1.9.1 # must be a setup and install requirement
|
cffi>=1.9.1 # must be a setup and install requirement
|
||||||
coloredlogs>=14.0 # strictly optional
|
coloredlogs>=14.0 # strictly optional
|
||||||
img2pdf>=0.3.0,<0.5 # pure Python
|
img2pdf>=0.3.0,<0.5 # pure Python
|
||||||
importlib-metadata>=4 # until Python 3.8
|
importlib-metadata>=4;python_version<'3.8' # until Python 3.8
|
||||||
importlib-resources>=5 # until Python 3.9
|
importlib-resources>=5;python_version<'3.9' # until Python 3.9
|
||||||
pdfminer.six!=20200720,>=20191110,<=20201018
|
pdfminer.six!=20200720,>=20191110,<=20201018
|
||||||
pikepdf>=2.10.0
|
pikepdf>=2.10.0
|
||||||
pikepdf<3;implementation_name=="pypy" and python_version=='3.6'
|
pikepdf<3;implementation_name=="pypy" and python_version=='3.6'
|
||||||
@@ -112,4 +112,4 @@ ignore =
|
|||||||
ignore = D203,F401,W503,E501,E203,F841
|
ignore = D203,F401,W503,E501,E203,F841
|
||||||
exclude = .git,__pycache__,docs/conf.py,build,dist,.venv,.venvpp,.eggs,tmp,src/ocrmypdf/lib/
|
exclude = .git,__pycache__,docs/conf.py,build,dist,.venv,.venvpp,.eggs,tmp,src/ocrmypdf/lib/
|
||||||
max-complexity = 10
|
max-complexity = 10
|
||||||
max-line-length = 100
|
max-line-length = 100
|
||||||
|
|||||||
@@ -414,6 +414,13 @@ def run_pipeline(options, *, plugin_manager, api=False):
|
|||||||
else:
|
else:
|
||||||
log.error(type(e).__name__)
|
log.error(type(e).__name__)
|
||||||
return e.exit_code
|
return e.exit_code
|
||||||
|
except (PIL.Image.DecompressionBombError if not api else NeverRaise) as e:
|
||||||
|
log.exception(
|
||||||
|
"A decompression bomb error was encountered while executing the "
|
||||||
|
"pipeline. Use the argument --max-image-mpixels to raise the maximum "
|
||||||
|
"image pixel limit."
|
||||||
|
)
|
||||||
|
return ExitCode.other_error
|
||||||
except (Exception if not api else NeverRaise): # pylint: disable=broad-except
|
except (Exception if not api else NeverRaise): # pylint: disable=broad-except
|
||||||
log.exception("An exception occurred while executing the pipeline")
|
log.exception("An exception occurred while executing the pipeline")
|
||||||
return ExitCode.other_error
|
return ExitCode.other_error
|
||||||
|
|||||||
@@ -5,7 +5,10 @@
|
|||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
|
||||||
from importlib_metadata import version as _package_version
|
try:
|
||||||
|
from importlib_metadata import version as _package_version
|
||||||
|
except ImportError:
|
||||||
|
from importlib.metadata import version as _package_version
|
||||||
|
|
||||||
PROGRAM_NAME = 'ocrmypdf'
|
PROGRAM_NAME = 'ocrmypdf'
|
||||||
|
|
||||||
|
|||||||
@@ -454,7 +454,7 @@ def _transcode_png(pike: Pdf, filename: Path, xref: Xref) -> bool:
|
|||||||
img2pdf.convert(fspath(filename), outputstream=f)
|
img2pdf.convert(fspath(filename), outputstream=f)
|
||||||
|
|
||||||
with Pdf.open(output) as pdf_image:
|
with Pdf.open(output) as pdf_image:
|
||||||
foreign_image = next(pdf_image.pages[0].images.values())
|
foreign_image = next(iter(pdf_image.pages[0].images.values()))
|
||||||
local_image = pike.copy_foreign(foreign_image)
|
local_image = pike.copy_foreign(foreign_image)
|
||||||
|
|
||||||
im_obj = pike.get_object(xref, 0)
|
im_obj = pike.get_object(xref, 0)
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ import base64
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Iterator, Union
|
from typing import Dict, Iterator, Union
|
||||||
|
|
||||||
import importlib_resources
|
try:
|
||||||
|
from importlib_resources import read_binary
|
||||||
|
except ImportError:
|
||||||
|
from importlib.resources import read_binary
|
||||||
import pikepdf
|
import pikepdf
|
||||||
import pkg_resources # deprecated
|
import pkg_resources # deprecated
|
||||||
|
|
||||||
@@ -104,7 +107,7 @@ def generate_pdfa_ps(target_filename: Path, icc: str = 'sRGB'):
|
|||||||
if icc != 'sRGB':
|
if icc != 'sRGB':
|
||||||
raise NotImplementedError("Only supporting sRGB")
|
raise NotImplementedError("Only supporting sRGB")
|
||||||
|
|
||||||
bytes_icc_profile = importlib_resources.read_binary(
|
bytes_icc_profile = read_binary(
|
||||||
'ocrmypdf.data', SRGB_ICC_PROFILE_NAME
|
'ocrmypdf.data', SRGB_ICC_PROFILE_NAME
|
||||||
)
|
)
|
||||||
ps = '\n'.join(_make_postscript(icc, bytes_icc_profile, 3))
|
ps = '\n'.join(_make_postscript(icc, bytes_icc_profile, 3))
|
||||||
|
|||||||
@@ -87,4 +87,4 @@ def test_jpeg_in_jpeg_out(resources, outpdf):
|
|||||||
'tests/plugins/tesseract_noop.py',
|
'tests/plugins/tesseract_noop.py',
|
||||||
)
|
)
|
||||||
with pikepdf.open(outpdf) as pdf:
|
with pikepdf.open(outpdf) as pdf:
|
||||||
assert next(pdf.pages[0].images.values()).Filter == pikepdf.Name.DCTDecode
|
assert next(iter(pdf.pages[0].images.values())).Filter == pikepdf.Name.DCTDecode
|
||||||
|
|||||||
+5
-6
@@ -745,14 +745,13 @@ def test_pdfa_n(pdfa_level, resources, outpdf):
|
|||||||
assert pdfa_info['conformance'] == f'PDF/A-{pdfa_level}B'
|
assert pdfa_info['conformance'] == f'PDF/A-{pdfa_level}B'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(
|
def test_decompression_bomb_error(resources, outpdf):
|
||||||
PIL.__version__ < '5.0.0', reason="Pillow < 5.0.0 doesn't raise the exception"
|
|
||||||
)
|
|
||||||
@pytest.mark.slow
|
|
||||||
def test_decompression_bomb(resources, outpdf):
|
|
||||||
p, _out, err = run_ocrmypdf(resources / 'hugemono.pdf', outpdf)
|
p, _out, err = run_ocrmypdf(resources / 'hugemono.pdf', outpdf)
|
||||||
assert 'decompression bomb' in err
|
assert 'decompression bomb' in err and '--max-image-mpixels' in err
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.slow
|
||||||
|
def test_decompression_bomb_succeeds(resources, outpdf):
|
||||||
p, _out, err = run_ocrmypdf(
|
p, _out, err = run_ocrmypdf(
|
||||||
resources / 'hugemono.pdf', outpdf, '--max-image-mpixels', '2000'
|
resources / 'hugemono.pdf', outpdf, '--max-image-mpixels', '2000'
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user