Skip to content

Commit

Permalink
add tests for examples
Browse files Browse the repository at this point in the history
  • Loading branch information
FriedrichFroebel committed Jan 24, 2024
1 parent b6c68a3 commit 0c82071
Show file tree
Hide file tree
Showing 16 changed files with 230 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ jobs:
python -m pip install --upgrade flake8 pep8-naming
- name: run flake8
run:
python -m flake8 tests/ doc/ setup.py
python -m flake8 tests/ doc/ examples/ setup.py
- name: run pycodestyle
run:
python -m pycodestyle djvu/
Expand Down
8 changes: 6 additions & 2 deletions examples/djvu-crop-text
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.

from __future__ import print_function

import argparse
import os
import sys
Expand All @@ -24,8 +22,10 @@ import djvu.const
import djvu.decode
import djvu.sexpr


EMPTY_TEXT_SEXPR = djvu.sexpr.Expression([djvu.const.TEXT_ZONE_PAGE, 0, 0, 0, 0, ''])


class ArgumentParser(argparse.ArgumentParser):

def __init__(self):
Expand All @@ -49,6 +49,7 @@ class ArgumentParser(argparse.ArgumentParser):
self.error('Unable to parse page numbers')
return options


def crop_text(sexpr, width, height):
if isinstance(sexpr, djvu.sexpr.ListExpression) and len(sexpr) >= 5:
tp = sexpr[0]
Expand All @@ -67,6 +68,7 @@ def crop_text(sexpr, width, height):
else:
return sexpr


class Context(djvu.decode.Context):

def handle_message(self, message):
Expand Down Expand Up @@ -100,12 +102,14 @@ class Context(djvu.decode.Context):
self.process_page(page).print_into(sed_file)
sed_file.write('\n.\n\n')


def main():
parser = ArgumentParser()
options = parser.parse_args()
context = Context()
context.process(options.path, options.pages)


if __name__ == '__main__':
main()

Expand Down
6 changes: 4 additions & 2 deletions examples/djvu-dump-text
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,13 @@
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.

from __future__ import print_function

import argparse
import os
import sys

import djvu.decode


def print_text(sexpr, level=0):
if level > 0:
print(' ' * (2 * level - 1), end=' ')
Expand All @@ -34,6 +33,7 @@ def print_text(sexpr, level=0):
else:
print(sexpr)


class Context(djvu.decode.Context):

def handle_message(self, message):
Expand All @@ -50,13 +50,15 @@ class Context(djvu.decode.Context):
page.get_info()
print_text(page.text.sexpr)


def main():
ap = argparse.ArgumentParser()
ap.add_argument('path', metavar='DJVU-FILE')
options = ap.parse_args()
context = Context()
context.process(options.path)


if __name__ == '__main__':
main()

Expand Down
27 changes: 16 additions & 11 deletions examples/djvu2png
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,23 @@
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.

from __future__ import print_function

import argparse
import os
import sys

import cairo
try:
import cairo # pycairo
except ImportError:
import cairocffi as cairo
import djvu.decode
import numpy

cairo_pixel_format = cairo.FORMAT_ARGB32
djvu_pixel_format = djvu.decode.PixelFormatRgbMask(0xFF0000, 0xFF00, 0xFF, bpp=32)
djvu_pixel_format.rows_top_to_bottom = 1
djvu_pixel_format.y_top_to_bottom = 0

CAIRO_PIXEL_FORMAT = cairo.FORMAT_ARGB32
DJVU_PIXEL_FORMAT = djvu.decode.PixelFormatRgbMask(0xFF0000, 0xFF00, 0xFF, bpp=32)
DJVU_PIXEL_FORMAT.rows_top_to_bottom = 1
DJVU_PIXEL_FORMAT.y_top_to_bottom = 0


class Context(djvu.decode.Context):

Expand All @@ -45,21 +48,22 @@ class Context(djvu.decode.Context):
page_job = page.decode(wait=True)
width, height = page_job.size
rect = (0, 0, width, height)
bytes_per_line = cairo.ImageSurface.format_stride_for_width(cairo_pixel_format, width)
bytes_per_line = cairo.ImageSurface.format_stride_for_width(CAIRO_PIXEL_FORMAT, width)
assert bytes_per_line % 4 == 0
color_buffer = numpy.zeros((height, bytes_per_line // 4), dtype=numpy.uint32)
page_job.render(mode, rect, rect, djvu_pixel_format, row_alignment=bytes_per_line, buffer=color_buffer)
page_job.render(mode, rect, rect, DJVU_PIXEL_FORMAT, row_alignment=bytes_per_line, buffer=color_buffer)
mask_buffer = numpy.zeros((height, bytes_per_line // 4), dtype=numpy.uint32)
if mode == djvu.decode.RENDER_FOREGROUND:
page_job.render(djvu.decode.RENDER_MASK_ONLY, rect, rect, djvu_pixel_format, row_alignment=bytes_per_line, buffer=mask_buffer)
page_job.render(djvu.decode.RENDER_MASK_ONLY, rect, rect, DJVU_PIXEL_FORMAT, row_alignment=bytes_per_line, buffer=mask_buffer)
mask_buffer <<= 24
color_buffer |= mask_buffer
color_buffer ^= 0xFF000000
surface = cairo.ImageSurface.create_for_data(color_buffer, cairo_pixel_format, width, height)
surface = cairo.ImageSurface.create_for_data(color_buffer, CAIRO_PIXEL_FORMAT, width, height)
surface.write_to_png(png_path)
# Multi-page documents are not yet supported:
break


def main():
parser = argparse.ArgumentParser()
parser.set_defaults(mode=djvu.decode.RENDER_COLOR)
Expand All @@ -73,6 +77,7 @@ def main():
context = Context()
context.process(options.djvu_path, options.png_path, options.mode)


if __name__ == '__main__':
main()

Expand Down
6 changes: 6 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,12 @@ def make_release_tree(self, base_dir, files):
'flake8',
'pep8-naming',
],
'examples': [
# djvu2png
# 'cairocffi', # Broken: https://github.com/Kozea/cairocffi/issues/223
'pycairo',
'numpy',
]
},
**meta
)
Expand Down
Empty file added tests/__init__.py
Empty file.
Empty file added tests/examples/__init__.py
Empty file.
32 changes: 32 additions & 0 deletions tests/examples/test_djvu2png.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import os
import subprocess
from tempfile import NamedTemporaryFile

from tests.tools import EXAMPLES, IMAGES, TestCase


class Djvu2PngTestCase(TestCase):
def check(self, mode: str):
with NamedTemporaryFile(suffix='.png') as outfile:
subprocess.run(
[
os.path.join(EXAMPLES, 'djvu2png'),
f'--{mode}',
os.path.join(IMAGES, 'test1.djvu'),
outfile.name
]
)
with open(os.path.join(IMAGES, f'test1_{mode}.png'), mode='rb') as fd:
expected = fd.read()
outfile.seek(0)
self.assertEqual(expected, outfile.read())

def test_foreground(self):
self.check('foreground')

def test_background(self):
# Sample files have no background.
pass

def test_mask(self):
self.check('mask')
18 changes: 18 additions & 0 deletions tests/examples/test_djvu_crop_text.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import os
import subprocess

from tests.tools import EXAMPLES, IMAGES, TestCase


class DjvuCropTextTestCase(TestCase):
def test_djvu_dump_text(self):
stdout = subprocess.check_output(
[
os.path.join(EXAMPLES, 'djvu-crop-text'),
os.path.join(IMAGES, 'test0.djvu'),
],
stderr=subprocess.PIPE,
)
with open(os.path.join(IMAGES, 'test0_crop-text.txt'), mode='rb') as fd:
expected = fd.read()
self.assertEqual(expected, stdout)
17 changes: 17 additions & 0 deletions tests/examples/test_djvu_dump_text.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import os
import subprocess

from tests.tools import EXAMPLES, IMAGES, TestCase


class DjvuDumpTextTestCase(TestCase):
def test_djvu_dump_text(self):
stdout = subprocess.check_output(
[
os.path.join(EXAMPLES, 'djvu-dump-text'),
os.path.join(IMAGES, 'test0.djvu'),
]
)
with open(os.path.join(IMAGES, 'test0_dump-text.txt'), mode='rb') as fd:
expected = fd.read()
self.assertEqual(expected, stdout)
11 changes: 11 additions & 0 deletions tests/images/test0_crop-text.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
remove-txt
select 1
set-txt
(page 0 0 2550 3300 (line 466 2712 978 2777 (word 466 2727 493 2776 "1") (word 570 2726 773 2775 "Lorem") (word 794 2712 978 2777 "ipsum")) (line 463 2604 2079 2649 (word 463 2604 573 2649 "Optio") (word 593 2604 859 2649 "reprehenderit") (word 878 2615 1062 2649 "molestias") (word 1085 2615 1180 2644 "amet") (word 1200 2604 1368 2649 "aliquam,") (word 1393 2604 1574 2649 "similique") (word 1594 2604 1830 2649 "doloremque") (word 1851 2604 1938 2649 "fuga") (word 1957 2615 2079 2649 "labore")) (line 462 2544 2081 2589 (word 462 2544 688 2589 "voluptatum") (word 701 2544 933 2589 "voluptatem,") (word 949 2555 1135 2589 "commodi") (word 1149 2544 1256 2589 "culpa") (word 1270 2544 1446 2589 "voluptas,") (word 1462 2555 1587 2589 "officia") (word 1601 2555 1738 2584 "tenetur") (word 1751 2544 1918 2589 "expedita") (word 1932 2544 2081 2589 "quidem")) (line 461 2483 2078 2528 (word 461 2494 521 2528 "hic") (word 534 2483 683 2528 "repellat") (word 695 2494 884 2528 "molestiae") (word 898 2483 977 2528 "quis") (word 993 2494 1204 2517 "accusamus") (word 1219 2494 1362 2528 "dolores") (word 1376 2483 1629 2528 "repudiandae,") (word 1644 2483 1793 2528 "quidem") (word 1805 2494 1842 2528 "in") (word 1856 2494 1900 2528 "ad") (word 1914 2483 2078 2528 "voluptas")) (line 462 2423 1561 2468 (word 462 2423 621 2468 "eligendi") (word 635 2434 790 2468 "maiores") (word 805 2423 946 2468 "placeat") (word 959 2434 1003 2457 "ex") (word 1018 2434 1244 2463 "consectetur") (word 1258 2434 1292 2463 "at") (word 1305 2434 1443 2463 "tenetur") (word 1457 2433 1561 2463 "amet.")) (line 1264 375 1278 409 (word 1264 375 1278 409 "1")))
.

select 2
set-txt
(page 0 0 2550 3300 (line 462 2712 910 2777 (word 462 2727 495 2776 "2") (word 571 2712 910 2777 "Hyperlinks")) (line 462 2599 714 2641 (word 462 2599 532 2641 "2.1") (word 597 2599 714 2640 "local")) (line 464 2505 544 2540 (word 464 2505 544 2540 "\342\206\2221")) (line 462 2358 772 2400 (word 462 2358 535 2400 "2.2") (word 598 2358 772 2397 "remote")) (line 463 2256 964 2298 (word 463 2256 964 2298 "http://jwilk.net/")) (line 1260 375 1282 409 (word 1260 375 1282 409 "2")))
.

114 changes: 114 additions & 0 deletions tests/images/test0_dump-text.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
page [0, 0, 2550, 3300]
line [466, 2712, 978, 2777]
word [466, 2727, 493, 2776]
"1"
word [570, 2726, 773, 2775]
"Lorem"
word [794, 2712, 978, 2777]
"ipsum"
line [463, 2604, 2079, 2649]
word [463, 2604, 573, 2649]
"Optio"
word [593, 2604, 859, 2649]
"reprehenderit"
word [878, 2615, 1062, 2649]
"molestias"
word [1085, 2615, 1180, 2644]
"amet"
word [1200, 2604, 1368, 2649]
"aliquam,"
word [1393, 2604, 1574, 2649]
"similique"
word [1594, 2604, 1830, 2649]
"doloremque"
word [1851, 2604, 1938, 2649]
"fuga"
word [1957, 2615, 2079, 2649]
"labore"
line [462, 2544, 2081, 2589]
word [462, 2544, 688, 2589]
"voluptatum"
word [701, 2544, 933, 2589]
"voluptatem,"
word [949, 2555, 1135, 2589]
"commodi"
word [1149, 2544, 1256, 2589]
"culpa"
word [1270, 2544, 1446, 2589]
"voluptas,"
word [1462, 2555, 1587, 2589]
"officia"
word [1601, 2555, 1738, 2584]
"tenetur"
word [1751, 2544, 1918, 2589]
"expedita"
word [1932, 2544, 2081, 2589]
"quidem"
line [461, 2483, 2078, 2528]
word [461, 2494, 521, 2528]
"hic"
word [534, 2483, 683, 2528]
"repellat"
word [695, 2494, 884, 2528]
"molestiae"
word [898, 2483, 977, 2528]
"quis"
word [993, 2494, 1204, 2517]
"accusamus"
word [1219, 2494, 1362, 2528]
"dolores"
word [1376, 2483, 1629, 2528]
"repudiandae,"
word [1644, 2483, 1793, 2528]
"quidem"
word [1805, 2494, 1842, 2528]
"in"
word [1856, 2494, 1900, 2528]
"ad"
word [1914, 2483, 2078, 2528]
"voluptas"
line [462, 2423, 1561, 2468]
word [462, 2423, 621, 2468]
"eligendi"
word [635, 2434, 790, 2468]
"maiores"
word [805, 2423, 946, 2468]
"placeat"
word [959, 2434, 1003, 2457]
"ex"
word [1018, 2434, 1244, 2463]
"consectetur"
word [1258, 2434, 1292, 2463]
"at"
word [1305, 2434, 1443, 2463]
"tenetur"
word [1457, 2433, 1561, 2463]
"amet."
line [1264, 375, 1278, 409]
word [1264, 375, 1278, 409]
"1"
page [0, 0, 2550, 3300]
line [462, 2712, 910, 2777]
word [462, 2727, 495, 2776]
"2"
word [571, 2712, 910, 2777]
"Hyperlinks"
line [462, 2599, 714, 2641]
word [462, 2599, 532, 2641]
"2.1"
word [597, 2599, 714, 2640]
"local"
line [464, 2505, 544, 2540]
word [464, 2505, 544, 2540]
"\342\206\2221"
line [462, 2358, 772, 2400]
word [462, 2358, 535, 2400]
"2.2"
word [598, 2358, 772, 2397]
"remote"
line [463, 2256, 964, 2298]
word [463, 2256, 964, 2298]
"http://jwilk.net/"
line [1260, 375, 1282, 409]
word [1260, 375, 1282, 409]
"2"
Binary file added tests/images/test1_foreground.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/images/test1_mask.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 1 addition & 3 deletions tests/test_decode.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
)

from tools import (
IMAGES,
interim_locale,
get_changelog_version,
locale_encoding,
Expand All @@ -85,9 +86,6 @@
)


IMAGES = os.path.join(os.path.dirname(__file__), 'images', '')


class DecodeTestCase(TestCase):
def run_command(self, *cmd, **kwargs):
stdin = kwargs.pop('stdin', None)
Expand Down
Loading

0 comments on commit 0c82071

Please sign in to comment.