Merge branch 'master' into feature/drop-3.7
This commit is contained in:
+7
-11
@@ -2,16 +2,13 @@
|
||||
# SPDX-License-Identifier: CC-BY-SA-4.0
|
||||
|
||||
# dotfiles
|
||||
.*
|
||||
!.coveragerc
|
||||
!.dockerignore
|
||||
!.git_archival.txt
|
||||
!.gitattributes
|
||||
!.gitignore
|
||||
!.pre-commit-config.yaml
|
||||
!.readthedocs.yaml
|
||||
!.github/
|
||||
!.docker/
|
||||
.coverage
|
||||
.venv*/
|
||||
.tox/
|
||||
.vscode/
|
||||
.ipynb_checkpoints/
|
||||
.mypy_cache/
|
||||
.pytest_cache/
|
||||
|
||||
# Dev scratch
|
||||
*.ipynb
|
||||
@@ -45,4 +42,3 @@ docs/_build/
|
||||
docs/_static/
|
||||
docs/_templates/
|
||||
docs/Makefile
|
||||
ocrmypdf/lib/_*.py
|
||||
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: OCRmyPDF
|
||||
Upstream-Contact: James R. Barlow <james@purplerock.ca>
|
||||
Source: https://github.com/ocrmypdf/OCRmyPDF
|
||||
|
||||
|
||||
Files:
|
||||
.git_archival.txt
|
||||
docs/images/logo-social.png
|
||||
docs/images/logo-square-256.svg
|
||||
docs/images/logo-square.png
|
||||
docs/images/logo-square.svg
|
||||
docs/images/logo.svg
|
||||
setup.cfg
|
||||
Copyright: (C) 2022 James R. Barlow
|
||||
License: MPL-2.0
|
||||
|
||||
Files:
|
||||
docs/images/macos-workflow.png
|
||||
Copyright: (C) 2022 James R. Barlow
|
||||
License: CC-BY-SA-4.0
|
||||
|
||||
Files:
|
||||
tests/resources/acroform.pdf
|
||||
tests/resources/aspect.pdf
|
||||
tests/resources/blank.pdf
|
||||
tests/resources/cmyk.pdf
|
||||
tests/resources/crom.png
|
||||
tests/resources/enormous.pdf
|
||||
tests/resources/formxobject.pdf
|
||||
tests/resources/francais.pdf
|
||||
tests/resources/hugemono.pdf
|
||||
tests/resources/invalid.pdf
|
||||
tests/resources/kcs.pdf
|
||||
tests/resources/livecycle.pdf
|
||||
tests/resources/missing_docinfo.pdf
|
||||
tests/resources/negzero.pdf
|
||||
tests/resources/no_contents.pdf
|
||||
tests/resources/toc.pdf
|
||||
tests/resources/trivial.pdf
|
||||
tests/resources/truetype_font_nomapping.pdf
|
||||
tests/resources/type3_font_nomapping.pdf
|
||||
Copyright: (C) 2022 James R. Barlow
|
||||
License: CC-BY-SA-4.0
|
||||
|
||||
Files:
|
||||
tests/resources/graph.pdf
|
||||
tests/resources/graph_ocred.pdf
|
||||
Copyright: (C) 2012 SmokeyJoe
|
||||
License: GFDL-1.2-or-later or CC-BY-SA-3.0
|
||||
|
||||
Files: tests/resources/c02-22.pdf
|
||||
tests/resources/congress.jpg
|
||||
tests/resources/multipage.pdf
|
||||
Copyright: Public domain
|
||||
License: public-domain
|
||||
Copyright on these files has expired.
|
||||
|
||||
Files: docs/images/bitmap_vs_svg.svg
|
||||
Copyright: (C) 2006 Yug
|
||||
License: CC-BY-SA-2.5
|
||||
|
||||
Files: tests/cache/*
|
||||
Copyright: (C) 2022 James R. Barlow
|
||||
License: CC-BY-SA-4.0
|
||||
|
||||
Files: tests/resources/linn.png
|
||||
tests/resources/linn.pdf
|
||||
tests/resources/linn.txt
|
||||
tests/resources/ccitt.pdf
|
||||
tests/resources/cardinal.pdf
|
||||
tests/resources/jbig2.pdf
|
||||
tests/resources/skew.pdf
|
||||
tests/resources/rotated_skew.pdf
|
||||
tests/resources/poster.pdf
|
||||
Copyright: (C) 1985 Forat Electronics
|
||||
License: GFDL-1.2-or-later or CC-BY-SA-3.0
|
||||
|
||||
Files: tests/resources/lichtenstein.pdf
|
||||
Copyright: (C) 2001 Andreas Tille
|
||||
(C) 2007 Alessio Damato
|
||||
License: GFDL-1.2-or-later or CC-BY-SA-3.0
|
||||
|
||||
Files: tests/resources/masks.pdf
|
||||
Copyright: held by the contributors to the German Wikipedia article "Linux"
|
||||
see: https://de.wikipedia.org/w/index.php?title=Linux&action=history
|
||||
(masks.pdf generated from Wikipedia article as of 2016-08-24)
|
||||
License: CC-BY-SA-3.0
|
||||
|
||||
Files: tests/resources/epson.pdf
|
||||
Copyright: held by the contributors to the Wikipedia article "Optical character recognition"
|
||||
see: https://en.wikipedia.org/w/index.php?title=Optical_character_recognition&action=history
|
||||
(epson.pdf generated from Wikipedia article as of 2016-09-14)
|
||||
License: CC-BY-SA-3.0
|
||||
|
||||
Files: tests/resources/typewriter.png tests/resources/2400dpi.pdf
|
||||
Copyright: (C) 2005 Ellywa
|
||||
License: GFDL-1.2-or-later or CC-BY-SA-1.0 or CC-BY-SA-2.0 or CC-BY-SA-2.5 or CC-BY-SA-3.0
|
||||
Comment:
|
||||
Obtained from: https://commons.wikimedia.org/wiki/File:Triumph.typewriter_text_Linzensoep.gif
|
||||
|
||||
Files: tests/resources/overlay.pdf
|
||||
Copyright: (C) 2017 Max Anderson
|
||||
License: MIT
|
||||
|
||||
Files:
|
||||
tests/resources/baiona*.png
|
||||
tests/resources/baiona*.jpg
|
||||
tests/resources/link.pdf
|
||||
tests/resources/palette.pdf
|
||||
Copyright: (C) 2014 Euskaldunaa
|
||||
License: CC-BY-SA-4.0
|
||||
|
||||
Files: tests/resources/vector.pdf
|
||||
Copyright: (C) 2018 Catscratch
|
||||
License: MIT
|
||||
|
||||
Files: src/ocrmypdf/data/sRGB.icc
|
||||
Copyright: Kai-Uwe Behrmann <www.behrmann.name>
|
||||
Marti Maria <www.littlecms.com>
|
||||
Photogamut <www.photogamut.org>
|
||||
Graeme Gill <www.argyllcms.com>
|
||||
ColorSolutions <www.basICColor.com>
|
||||
License: Zlib
|
||||
|
||||
Files: tests/resources/3small.pdf
|
||||
Copyright: (C) 2014 Euskaldunaa
|
||||
(C) 2017 James R. Barlow
|
||||
(C) 2005 Ellywa
|
||||
License: CC-BY-SA-4.0 and (GFDL-1.2-or-later or CC-BY-SA-1.0 or CC-BY-SA-2.0 or CC-BY-SA-2.5 or CC-BY-SA-3.0)
|
||||
Comment: concatenation of baiona_gray.png, crom.png and typewriter.png/2400dpi.pdf
|
||||
+2
-1
@@ -37,7 +37,8 @@ For all other Linux, you must build a JBIG2 encoder from source:
|
||||
.. _jbig2-lossy:
|
||||
|
||||
Dependencies include libtoolize and libleptonica, which on Ubuntu systems
|
||||
are packaged as libtool and libleptonica-dev.
|
||||
are packaged as libtool and libleptonica-dev. On Fedora (35) they are packaged
|
||||
as libtool and leptonica-devel.
|
||||
|
||||
Lossy mode JBIG2
|
||||
================
|
||||
|
||||
@@ -188,7 +188,8 @@ def generate_pdfa(
|
||||
strategy = 'LeaveColorUnchanged'
|
||||
gs_version = version()
|
||||
if gs_version == '9.56.0':
|
||||
# 9.56.0 introduced a new rendering mode that breaks our OCR
|
||||
# 9.56.0 breaks our OCR, should be fixed in 9.56.1
|
||||
# https://bugs.ghostscript.com/show_bug.cgi?id=705187
|
||||
compression_args.append('-dNEWPDF=false')
|
||||
|
||||
# nb no need to specify ProcessColorModel when ColorConversionStrategy
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# SPDX-FileCopyrightText: 2022 James R. Barlow
|
||||
# SPDX-FileCopyrightText: 2018-2022 James R. Barlow
|
||||
# SPDX-FileCopyrightText: 2019 Martin Wind
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
"""OCRmyPDF page processing pipeline functions."""
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# SPDX-FileCopyrightText: 2022 James R. Barlow
|
||||
# SPDX-FileCopyrightText: 2019-2022 James R. Barlow
|
||||
# SPDX-FileCopyrightText: 2019 Martin Wind
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
"""Implements the concurrent and page synchronous parts of the pipeline."""
|
||||
|
||||
+6
-1
@@ -44,7 +44,7 @@ TESTS_ROOT = Path(__file__).parent.resolve()
|
||||
PROJECT_ROOT = TESTS_ROOT
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@pytest.fixture(scope="session")
|
||||
def resources() -> Path:
|
||||
return Path(TESTS_ROOT) / 'resources'
|
||||
|
||||
@@ -78,6 +78,11 @@ def no_outpdf(tmp_path) -> Path:
|
||||
return tmp_path / 'no_output.pdf'
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def multipage(resources):
|
||||
return resources / 'multipage.pdf'
|
||||
|
||||
|
||||
def check_ocrmypdf(input_file: Path, output_file: Path, *args) -> Path:
|
||||
"""Run ocrmypdf and confirm that a valid plausible PDF was created."""
|
||||
api_args = [str(input_file), str(output_file)] + [
|
||||
|
||||
@@ -140,18 +140,19 @@ def cached_run(options, run_args, **run_kwargs):
|
||||
tessfile = args.outputbase + '.' + configfile
|
||||
shutil.copy(tessfile, str(cache_folder / configfile) + '.bin')
|
||||
|
||||
manifest = {}
|
||||
manifest['tesseract_version'] = TesseractOcrEngine.version().replace('\n', ' ')
|
||||
manifest['system'] = platform.system()
|
||||
manifest['python'] = platform.python_version()
|
||||
manifest['argv_slug'] = cache_folder.name
|
||||
manifest['sourcefile'] = str(Path(source_file).relative_to(TESTS_ROOT))
|
||||
|
||||
def clean_sys_argv():
|
||||
for arg in run_args[1:]:
|
||||
yield re.sub(r'.*/ocrmypdf[.]io[.][^/]+[/](.*)', r'$TMPDIR/\1', arg)
|
||||
|
||||
manifest['args'] = list(clean_sys_argv())
|
||||
manifest = {
|
||||
'tesseract_version': TesseractOcrEngine.version().replace('\n', ' '),
|
||||
'system': platform.system(),
|
||||
'python': platform.python_version(),
|
||||
'argv_slug': cache_folder.name,
|
||||
'sourcefile': str(Path(source_file).relative_to(TESTS_ROOT)),
|
||||
'args': list(clean_sys_argv()),
|
||||
}
|
||||
|
||||
with (Path(CACHE_ROOT) / 'manifest.jsonl').open('a') as f:
|
||||
json.dump(manifest, f)
|
||||
f.write('\n')
|
||||
|
||||
@@ -23,7 +23,7 @@ the copyright holder(s) and license(s) applicable to these resources.
|
||||
- `US Congressional Records`_
|
||||
- difficult OCR image (color background)
|
||||
* - graph.pdf
|
||||
- `Wikimedia: Pandas text analysis.png`_
|
||||
- `Wikimedia:Simple_line_graph_of_ACE_2012_results_by_candidate_sj01.png`_
|
||||
- image with slanted text
|
||||
* - lichtenstein.pdf
|
||||
- `Wikimedia: JPEG2000 Lichtenstein`_
|
||||
@@ -111,14 +111,12 @@ These test resources are assemblies or derivatives from other previously mention
|
||||
- baiona_alpha.png (from baiona.png, RGB+A version)
|
||||
- cardinal.pdf (four cardinal directions, baked-in rotated copies of linn.png)
|
||||
- ccitt.pdf (linn.png, converted to CCITT encoding)
|
||||
- encrypted_algo4.pdf (congress.jpg, encrypted with algorithm 4 - not supported by PyPDF2)
|
||||
- graph_ocred.pdf (from graph.pdf)
|
||||
- jbig2.pdf (congress.jpg, converted to JBIG2 encoding)
|
||||
- jbig2.pdf (from linn.png)
|
||||
- multipage.pdf (from several other files)
|
||||
- palette.pdf (congress.jpg, converted to a 256-color palette)
|
||||
- palette.pdf (from baiona_colormapped.png)
|
||||
- poster.pdf (from linn.png)
|
||||
- rotated_skew.pdf (a /Rotate'd and skewed document from linn.png)
|
||||
- skew-encrypted.pdf (skew.pdf with encryption - access supported by PyPDF2, password is "password")
|
||||
- skew.pdf (from linn.png, skew simulated by adjusting the transformation matrix)
|
||||
- toc.pdf (from formxobject.pdf, trivial.pdf)
|
||||
|
||||
@@ -129,7 +127,7 @@ These test resources are assemblies or derivatives from other previously mention
|
||||
|
||||
.. _`US Congressional Records`: http://www.baxleystamps.com/litho/meiji/courts_1871.jpg
|
||||
|
||||
.. _`Wikimedia: Pandas text analysis.png`: https://en.wikipedia.org/wiki/File:Pandas_text_analysis.png
|
||||
.. _`Wikimedia: Simple_line_graph_of_ACE_2012_results_by_candidate_sj01.png`: https://en.wikipedia.org/wiki/File:Simple_line_graph_of_ACE_2012_results_by_candidate_sj01.png
|
||||
|
||||
.. _`Wikimedia: JPEG2000 Lichtenstein`: https://en.wikipedia.org/wiki/JPEG_2000#/media/File:Jpeg2000_2-level_wavelet_transform-lichtenstein.png
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Regular → Executable
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -14,9 +14,9 @@ from .conftest import run_ocrmypdf_api
|
||||
|
||||
@pytest.mark.skipif(True, reason="--use-threads is currently default")
|
||||
@pytest.mark.skipif(os.name == 'nt', reason="Windows doesn't have SIGKILL")
|
||||
def test_simulate_oom_killer(resources, no_outpdf):
|
||||
def test_simulate_oom_killer(multipage, no_outpdf):
|
||||
exitcode = run_ocrmypdf_api(
|
||||
resources / 'multipage.pdf',
|
||||
multipage,
|
||||
no_outpdf,
|
||||
'--force-ocr',
|
||||
'--plugin',
|
||||
|
||||
+20
-14
@@ -7,11 +7,10 @@ import os
|
||||
import shutil
|
||||
from math import isclose
|
||||
from pathlib import Path
|
||||
from subprocess import PIPE, run
|
||||
from subprocess import run
|
||||
from unittest.mock import patch
|
||||
|
||||
import pikepdf
|
||||
import PIL
|
||||
import pytest
|
||||
from PIL import Image
|
||||
|
||||
@@ -153,9 +152,9 @@ def test_skip_big(resources, outpdf):
|
||||
|
||||
@pytest.mark.parametrize('renderer', RENDERERS)
|
||||
@pytest.mark.parametrize('output_type', ['pdf', 'pdfa'])
|
||||
def test_maximum_options(renderer, output_type, resources, outpdf):
|
||||
def test_maximum_options(renderer, output_type, multipage, outpdf):
|
||||
check_ocrmypdf(
|
||||
resources / 'multipage.pdf',
|
||||
multipage,
|
||||
outpdf,
|
||||
'-d',
|
||||
'-ci' if have_unpaper() else None,
|
||||
@@ -292,12 +291,6 @@ def test_input_file_not_a_pdf(caplog, no_outpdf):
|
||||
assert input_file in caplog.text
|
||||
|
||||
|
||||
def test_encrypted(resources, caplog, no_outpdf):
|
||||
result = run_ocrmypdf_api(resources / 'skew-encrypted.pdf', no_outpdf)
|
||||
assert result == ExitCode.encrypted_pdf
|
||||
assert 'encryption must be removed' in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize('renderer', RENDERERS)
|
||||
def test_pagesegmode(renderer, resources, outpdf):
|
||||
check_ocrmypdf(
|
||||
@@ -398,14 +391,27 @@ def test_tesseract_image_too_big(renderer, resources, outpdf):
|
||||
)
|
||||
|
||||
|
||||
def test_algo4(resources, outpdf):
|
||||
p = run_ocrmypdf(
|
||||
resources / 'encrypted_algo4.pdf',
|
||||
@pytest.mark.parametrize('encryption_level', [2, 3, 4, 6])
|
||||
def test_encrypted(resources, outpdf, encryption_level, caplog):
|
||||
encryption = pikepdf.models.encryption.Encryption(
|
||||
owner='ocrmypdf',
|
||||
user='ocrmypdf',
|
||||
R=encryption_level,
|
||||
aes=(encryption_level >= 4),
|
||||
metadata=(encryption_level == 6),
|
||||
)
|
||||
|
||||
with pikepdf.open(resources / 'jbig2.pdf') as pdf:
|
||||
pdf.save(outpdf, encryption=encryption)
|
||||
|
||||
exitcode = run_ocrmypdf_api(
|
||||
outpdf,
|
||||
outpdf,
|
||||
'--plugin',
|
||||
'tests/plugins/tesseract_noop.py',
|
||||
)
|
||||
assert p.returncode == ExitCode.encrypted_pdf
|
||||
assert exitcode == ExitCode.encrypted_pdf
|
||||
assert 'encryption must be removed' in caplog.text
|
||||
|
||||
|
||||
def test_jbig2_passthrough(resources, outpdf):
|
||||
|
||||
@@ -27,10 +27,15 @@ needs_jbig2enc = pytest.mark.skipif(
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def palette(resources):
|
||||
return resources / 'palette.pdf'
|
||||
|
||||
|
||||
@needs_pngquant
|
||||
@pytest.mark.parametrize('pdf', ['multipage.pdf', 'palette.pdf'])
|
||||
def test_basic(resources, pdf, outpdf):
|
||||
infile = resources / pdf
|
||||
@pytest.mark.parametrize('pdf', ['multipage', 'palette'])
|
||||
def test_basic(multipage, palette, pdf, outpdf):
|
||||
infile = multipage if pdf == 'multipage' else palette
|
||||
opt.main(infile, outpdf, level=3)
|
||||
|
||||
assert 0.98 * Path(outpdf).stat().st_size <= Path(infile).stat().st_size
|
||||
|
||||
@@ -48,10 +48,9 @@ def test_nonmonotonic_warning(caplog):
|
||||
assert 'out of order' in caplog.text
|
||||
|
||||
|
||||
def test_limited_pages(resources, outpdf):
|
||||
multi = resources / 'multipage.pdf'
|
||||
def test_limited_pages(multipage, outpdf):
|
||||
ocrmypdf.ocr(
|
||||
multi,
|
||||
multipage,
|
||||
outpdf,
|
||||
pages='5-6',
|
||||
optimize=0,
|
||||
|
||||
@@ -276,7 +276,8 @@ def test_rasterize_rotates(resources, tmp_path):
|
||||
rotation=90,
|
||||
filter_vector=False,
|
||||
)
|
||||
assert Image.open(img).size == (123, 151), "Image not rotated"
|
||||
with Image.open(img) as im:
|
||||
assert im.size == (83, 200), "Image not rotated"
|
||||
|
||||
img = tmp_path / 'img180.png'
|
||||
pm.hook.rasterize_pdf_page(
|
||||
@@ -289,7 +290,7 @@ def test_rasterize_rotates(resources, tmp_path):
|
||||
rotation=180,
|
||||
filter_vector=False,
|
||||
)
|
||||
assert Image.open(img).size == (151, 123), "Image not rotated"
|
||||
assert Image.open(img).size == (200, 83), "Image not rotated"
|
||||
|
||||
|
||||
def test_simulated_scan(outdir):
|
||||
|
||||
Reference in New Issue
Block a user