Merge branch 'issue246' into devel

This commit is contained in:
jevans 2014-09-15 20:09:03 -04:00
commit 14b19dd1e2
15 changed files with 800 additions and 357 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
*.pyc
*.swp

View file

@ -12,9 +12,9 @@ before_install:
# command to install dependencies
install:
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then pip install lxml contextlib2 mock; fi
- if [[ $TRAVIS_PYTHON_VERSION == '3.3' ]]; then pip install lxml numpy; fi
- if [[ $TRAVIS_PYTHON_VERSION == '3.4' ]]; then pip install lxml numpy; fi
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then pip install lxml contextlib2 mock six; fi
- if [[ $TRAVIS_PYTHON_VERSION == '3.3' ]]; then pip install lxml numpy six; fi
- if [[ $TRAVIS_PYTHON_VERSION == '3.4' ]]; then pip install lxml numpy six; fi
# command to run tests
script:

View file

@ -1,34 +0,0 @@
#!/usr/bin/env python
import argparse
import sys
import glymur
description='Print JPEG2000 metadata.'
parser = argparse.ArgumentParser(description=description)
parser.add_argument('-x', '--noxml', help='Suppress XML.',
action='store_true')
parser.add_argument('-s', '--short', help='Only print box id, offset, and length.',
action='store_true')
chelp='Level of codestream information. 0 suppressed all details, 1 prints headers, 2 prints the full codestream'
parser.add_argument('-c', '--codestream',
help=chelp,
nargs=1,
type=int,
default=[0])
parser.add_argument('filename')
args = parser.parse_args()
if args.noxml:
glymur.set_printoptions(xml=False)
if args.short:
glymur.set_printoptions(short=True)
if args.codestream[0] == 0:
glymur.set_printoptions(codestream=False)
print_full_codestream = False
elif args.codestream[0] == 1:
print_full_codestream = False
else:
print_full_codestream = True
filename = args.filename
glymur.jp2dump(args.filename, codestream=print_full_codestream)

View file

@ -3,21 +3,28 @@ How do I...?
------------
... read the lowest resolution thumbnail?
=========================================
Printing the Jp2k object should reveal the number of resolutions
(look in the COD segment section of the codestream), but you can
take a shortcut by supplying -1 as the
resolution level. ::
... read the lower resolution images?
=====================================
Jp2k implements slicing via the :py:meth:`__getitem__` method so
any lower resolution images in a JPEG 2000 file can easily be
accessed, for example here's how to retrieve the first sub-image ::
>>> import glymur
>>> jp2file = glymur.data.nemo()
>>> jp2 = glymur.Jp2k(jp2file)
>>> thumbnail = jp2.read(rlevel=-1)
>>> fullres = jp2[:]
>>> print(fullres.shape)
(1456, 2592, 3)
>>> thumbnail = jp2[::2, ::2]
>>> print(thumbnail.shape)
(728, 1296, 3)
The :py:meth:`read` method gives many more options for other JPEG 2000 features
such as quality layers.
... display metadata?
=====================
There are two ways. From the unix command line, the script **jp2dump** is
There are two ways. From the command line, the script **jp2dump** is
available. ::
$ jp2dump /path/to/glymur/installation/data/nemo.jp2

View file

@ -27,10 +27,5 @@ but you should also be able to install Glymur via pip ::
$ pip install glymur
This will install a script **jp2dump** that can be used from the unix command
line for dumping JP2 metadata, so you should adjust your **$PATH**
environment variable to take advantage of it. For example, if you install
with pip's `--user` option on linux ::
$ export PATH=$HOME/.local/bin:$PATH
In addition to the package, this also gives you a script **jp2dump** that can
be used from the command line line to print JPEG 2000 metadata.

49
glymur/command_line.py Normal file
View file

@ -0,0 +1,49 @@
#!/usr/bin/env python
import argparse
import sys
from . import jp2dump, set_printoptions
def main():
description='Print JPEG2000 metadata.'
parser = argparse.ArgumentParser(description=description)
parser.add_argument('-x', '--noxml',
help='Suppress XML.',
action='store_true')
parser.add_argument('-s', '--short',
help='Only print box id, offset, and length.',
action='store_true')
chelp = 'Level of codestream information. 0 suppressed all details, '
chelp += '1 prints headers, 2 prints the full codestream'
parser.add_argument('-c', '--codestream',
help=chelp,
nargs=1,
type=int,
default=[0])
parser.add_argument('filename')
args = parser.parse_args()
if args.noxml:
set_printoptions(xml=False)
if args.short:
set_printoptions(short=True)
codestream_level = args.codestream[0]
if codestream_level not in [0, 1, 2]:
raise ValueError("Invalid level of codestream information specified.")
if codestream_level == 0:
set_printoptions(codestream=False)
print_full_codestream = False
elif codestream_level == 1:
print_full_codestream = False
else:
print_full_codestream = True
filename = args.filename
jp2dump(args.filename, codestream=print_full_codestream)

View file

@ -759,6 +759,96 @@ class Jp2k(Jp2kBox):
return boxes
def __getitem__(self, pargs):
"""
Slicing protocol.
"""
codestream = self.get_codestream(header_only=True)
if isinstance(pargs, int):
# Not a very good use of this protocol, but technically legal.
# This retrieves a single row.
row = pargs
area = (row, 0, row + 1, codestream.segment[1].xsiz)
return self.read(area=area).squeeze()
if isinstance(pargs, slice):
# Case of jp2[:], i.e. retrieve the entire image.
#
# Should have a slice object where start = stop = step = None
return self.read()
if isinstance(pargs, tuple) and all(isinstance(x, int) for x in pargs):
# Retrieve a single pixel.
# Something like jp2[r, c]
row = pargs[0]
col = pargs[1]
area = (row, col, row + 1, col + 1)
pixel = self.read(area=area).squeeze()
if len(pargs) == 2:
return pixel
elif len(pargs) == 3:
return pixel[pargs[2]]
# Assuming pargs is a tuple of slices from now on.
rows = pargs[0]
cols = pargs[1]
if len(pargs) == 2:
bands = slice(None, None, None)
else:
bands = pargs[2]
if rows.step is None:
rows_step = 1
else:
rows_step = rows.step
if cols.step is None:
cols_step = 1
else:
cols_step = cols.step
if rows_step != cols_step:
msg = "Row and column strides must be the same."
raise IndexError(msg)
# Ok, reduce layer step is the same in both xy directions, so just take
# one of them.
step = rows_step
if np.log2(step) != np.floor(np.log2(step)):
msg = "Row and column strides must be powers of 2."
raise IndexError(msg)
if rows.start is None:
rows_start = 0
else:
rows_start = rows.start
if rows.stop is None:
rows_stop = codestream.segment[1].ysiz
else:
rows_stop = rows.stop
if cols.start is None:
cols_start = 0
else:
cols_start = cols.start
if cols.stop is None:
cols_stop = codestream.segment[1].xsiz
else:
cols_stop = cols.stop
area = (rows_start, cols_start, rows_stop, cols_stop)
data = self.read(area=area, rlevel=np.int(np.log2(step)))
if len(pargs) == 2:
return data
# Ok, 3 arguments in pargs.
return data[:, :, bands]
def read(self, **kwargs):
"""Read a JPEG 2000 image.
@ -833,7 +923,7 @@ class Jp2k(Jp2kBox):
raise RuntimeError(msg)
def _read_openjpeg(self, rlevel=0, ignore_pclr_cmap_cdef=False,
verbose=False):
verbose=False, area=None):
"""Read a JPEG 2000 image using libopenjpeg.
Parameters
@ -846,6 +936,9 @@ class Jp2k(Jp2kBox):
color transformation. Defaults to False.
verbose : bool, optional
Print informational messages produced by the OpenJPEG library.
area : tuple, optional
Specifies decoding image area,
(first_row, first_col, last_row, last_col)
Returns
-------
@ -898,6 +991,18 @@ class Jp2k(Jp2kBox):
# data 2D instead of 3D.
data.shape = data.shape[0:2]
if area is not None:
x0, y0, x1, y1 = area
extent = 2 ** rlevel
if x1 - x0 < extent or y1 - y0 < extent:
msg = "Decoded area is too small."
raise IOError(msg)
area = [int(round(float(x)/extent + 2 ** -20)) for x in area]
rows = slice(area[0], area[2], None)
cols = slice(area[1], area[3], None)
data = data[rows, cols]
return data
def _read_openjp2(self, rlevel=0, layer=0, area=None, tile=None,

View file

@ -37,6 +37,24 @@ except:
raise
# The Cinema2K/4K tests seem to need the freeimage backend to skimage.io
# in order to work. Unfortunately, scikit-image/freeimage is about as wonky as
# it gets. Anaconda can get totally weirded out on versions up through 3.6.4
# on Python3 with scikit-image up through version 0.10.0.
NO_SKIMAGE_FREEIMAGE_SUPPORT = False
try:
import skimage
import skimage.io
if (((sys.hexversion >= 0x03000000) and
('Anaconda' in sys.version) and
(re.match('0.10', skimage.__version__)))):
NO_SKIMAGE_FREEIMAGE_SUPPORT = True
else:
skimage.io.use_plugin('freeimage', 'imread')
except ((ImportError, RuntimeError)):
NO_SKIMAGE_FREEIMAGE_SUPPORT = True
def _indent(textstr):
"""
Indent a string.
@ -437,7 +455,9 @@ Contiguous Codestream Box (jp2c) @ (3223, 1132296)
Step size: [(0, 8), (0, 9), (0, 9), (0, 10)]
CME marker segment @ (3305, 37)
"Created by OpenJPEG version 2.0.0"'''
nemo_dump_full = dump.format(_indent(nemo_xmp))
nemo_with_codestream_header = dump.format(_indent(nemo_xmp))
#nemo_dump_full = dump.format(_indent(nemo_xmp))
nemo_dump_short = r"""JPEG 2000 Signature Box (jP ) @ (0, 12)
File Type Box (ftyp) @ (12, 20)
@ -633,7 +653,7 @@ number_list_box = r"""Number List Box (nlst) @ (-1, 0)
Association[2]: compositing layer 0"""
goodstuff = r"""Codestream:
goodstuff_codestream_header = r"""Codestream:
SOC marker segment @ (0, 0)
SIZ marker segment @ (2, 47)
Profile: no profile
@ -668,3 +688,80 @@ goodstuff = r"""Codestream:
Quantization style: no quantization, 2 guard bits
Step size: [(0, 8), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10)]"""
goodstuff_with_full_header = r"""Codestream:
SOC marker segment @ (0, 0)
SIZ marker segment @ (2, 47)
Profile: no profile
Reference Grid Height, Width: (800 x 480)
Vertical, Horizontal Reference Grid Offset: (0 x 0)
Reference Tile Height, Width: (800 x 480)
Vertical, Horizontal Reference Tile Offset: (0 x 0)
Bitdepth: (8, 8, 8)
Signed: (False, False, False)
Vertical, Horizontal Subsampling: ((1, 1), (1, 1), (1, 1))
COD marker segment @ (51, 12)
Coding style:
Entropy coder, without partitions
SOP marker segments: False
EPH marker segments: False
Coding style parameters:
Progression order: LRCP
Number of layers: 1
Multiple component transformation usage: reversible
Number of resolutions: 6
Code block height, width: (64 x 64)
Wavelet transform: 5-3 reversible
Precinct size: default, 2^15 x 2^15
Code block context:
Selective arithmetic coding bypass: False
Reset context probabilities on coding pass boundaries: False
Termination on each coding pass: False
Vertically stripe causal context: False
Predictable termination: False
Segmentation symbols: False
QCD marker segment @ (65, 19)
Quantization style: no quantization, 2 guard bits
Step size: [(0, 8), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10)]
SOT marker segment @ (86, 10)
Tile part index: 0
Tile part length: 115132
Tile part instance: 0
Number of tile parts: 1
COC marker segment @ (98, 9)
Associated component: 1
Coding style for this component: Entropy coder, PARTITION = 0
Coding style parameters:
Number of resolutions: 6
Code block height, width: (64 x 64)
Wavelet transform: 5-3 reversible
Code block context:
Selective arithmetic coding bypass: False
Reset context probabilities on coding pass boundaries: False
Termination on each coding pass: False
Vertically stripe causal context: False
Predictable termination: False
Segmentation symbols: False
QCC marker segment @ (109, 20)
Associated Component: 1
Quantization style: no quantization, 2 guard bits
Step size: [(0, 8), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10)]
COC marker segment @ (131, 9)
Associated component: 2
Coding style for this component: Entropy coder, PARTITION = 0
Coding style parameters:
Number of resolutions: 6
Code block height, width: (64 x 64)
Wavelet transform: 5-3 reversible
Code block context:
Selective arithmetic coding bypass: False
Reset context probabilities on coding pass boundaries: False
Termination on each coding pass: False
Vertically stripe causal context: False
Predictable termination: False
Segmentation symbols: False
QCC marker segment @ (142, 20)
Associated Component: 2
Quantization style: no quantization, 2 guard bits
Step size: [(0, 8), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10)]
SOD marker segment @ (164, 0)
EOC marker segment @ (115218, 0)"""

View file

@ -13,6 +13,8 @@ import tempfile
import unittest
import warnings
import six
from glymur import Jp2k
import glymur
@ -20,6 +22,8 @@ from .fixtures import opj_data_file, OPJ_DATA_ROOT
@unittest.skipIf(sys.hexversion < 0x03030000,
"assertWarn methods introduced in 3.x")
@unittest.skipIf(re.match('1.[0-6]', six.__version__) is not None,
"Problem with earlier versions of six on python3")
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
class TestWarnings(unittest.TestCase):

View file

@ -52,6 +52,307 @@ def load_tests(loader, tests, ignore):
return tests
class TestSliceProtocol(unittest.TestCase):
"""
Test slice protocol, i.e. when using [ ] to read image data.
"""
@classmethod
def setUpClass(self):
self.jp2 = Jp2k(glymur.data.nemo())
self.jp2_data = self.jp2.read()
self.j2k = Jp2k(glymur.data.goodstuff())
self.j2k_data = self.j2k.read()
def test_resolution_strides_cannot_differ(self):
with self.assertRaises(IndexError):
# Strides in x/y directions cannot differ.
self.j2k[::2, ::3]
def test_resolution_strides_cannot_differ(self):
with self.assertRaises(IndexError):
# Strides in x/y directions cannot differ.
self.j2k[::2, ::3]
def test_resolution_strides_must_be_powers_of_two(self):
with self.assertRaises(IndexError):
self.j2k[::3, ::3]
def test_integer_index_in_3d(self):
for j in [0, 1, 2]:
band = self.j2k[:, :, j]
np.testing.assert_array_equal(self.j2k_data[:, :, j], band)
def test_slice_in_third_dimension(self):
actual = self.j2k[:,:,1:3]
expected = self.j2k_data[:,:,1:3]
np.testing.assert_array_equal(actual, expected)
def test_reduce_resolution_and_slice_in_third_dimension(self):
d = self.j2k[::2, ::2, 1:3]
all = self.j2k.read(rlevel=1)
np.testing.assert_array_equal(all[:,:,1:3], d)
def test_retrieve_single_row(self):
actual = self.jp2[0]
expected = self.jp2_data[0]
np.testing.assert_array_equal(actual, expected)
def test_retrieve_single_pixel(self):
actual = self.jp2[0,0]
expected = self.jp2_data[0, 0]
np.testing.assert_array_equal(actual, expected)
def test_retrieve_single_component(self):
actual = self.jp2[20,20,2]
expected = self.jp2_data[20, 20, 2]
np.testing.assert_array_equal(actual, expected)
def test_full_resolution_slicing_by_quarters_upper_left(self):
actual = self.jp2[:728, :1296]
expected = self.jp2_data[:728, :1296]
np.testing.assert_array_equal(actual, expected)
def test_full_resolution_slicing_by_quarters_lower_left(self):
actual = self.jp2[728:, :1296]
expected = self.jp2_data[728:, :1296]
np.testing.assert_array_equal(actual, expected)
def test_full_resolution_slicing_by_quarters_upper_right(self):
actual = self.jp2[:728, 1296:]
expected = self.jp2_data[:728, 1296:]
np.testing.assert_array_equal(actual, expected)
def test_full_resolution_slicing_by_quarters_lower_right(self):
actual = self.jp2[728:, 1296:]
expected = self.jp2_data[728:, 1296:]
np.testing.assert_array_equal(actual, expected)
def test_full_resolution_slicing_by_quarters_center(self):
actual = self.jp2[364:1092, 648:1942]
expected = self.jp2_data[364:1092, 648:1942]
np.testing.assert_array_equal(actual, expected)
def test_full_resolution_slicing_by_halves_left(self):
actual = self.jp2[:, :1296]
expected = self.jp2_data[:, :1296]
np.testing.assert_array_equal(actual, expected)
def test_full_resolution_slicing_by_right_half(self):
actual = self.jp2[:, 1296:]
expected = self.jp2_data[:, 1296:]
np.testing.assert_array_equal(actual, expected)
def test_full_resolution_slicing_by_top_half(self):
actual = self.jp2[:728, :]
expected = self.jp2_data[:728, :]
np.testing.assert_array_equal(actual, expected)
def test_full_resolution_slicing_by_bottom_half(self):
actual = self.jp2[728:, :]
expected = self.jp2_data[728:, :]
np.testing.assert_array_equal(actual, expected)
def test_region_rlevel1(self):
actual = self.jp2[0:201:2, 0:201:2]
expected = self.jp2.read(area=(0, 0, 201, 201), rlevel=1)
np.testing.assert_array_equal(actual, expected)
def test_region_rlevel1_slice_start_is_none(self):
actual = self.jp2[:201:2, :201:2]
expected = self.jp2.read(area=(0, 0, 201, 201), rlevel=1)
np.testing.assert_array_equal(actual, expected)
def test_region_rlevel1_slice_stop_is_none(self):
actual = self.jp2[201::2, 201::2]
expected = self.jp2.read(area=(201, 201, 1456, 2592), rlevel=1)
np.testing.assert_array_equal(actual, expected)
def test_region_rlevel1(self):
actual = self.jp2[0:202:2, 0:202:2]
expected = self.jp2.read(area=(0, 0, 202, 202), rlevel=1)
np.testing.assert_array_equal(actual, expected)
def test_slice_protocol_2d_reduce_resolution(self):
d = self.j2k[:]
self.assertEqual(d.shape, (800, 480, 3))
d = self.j2k[::1, ::1]
self.assertEqual(d.shape, (800, 480, 3))
d = self.j2k[::2, ::2]
self.assertEqual(d.shape, (400, 240, 3))
d = self.j2k[::4, ::4]
self.assertEqual(d.shape, (200, 120, 3))
d = self.j2k[::8, ::8]
self.assertEqual(d.shape, (100, 60, 3))
d = self.j2k[::16, ::16]
self.assertEqual(d.shape, (50, 30, 3))
d = self.j2k[::32, ::32]
self.assertEqual(d.shape, (25, 15, 3))
def test_region_rlevel5(self):
actual = self.j2k[5:533:32, 27:423:32]
expected = self.j2k.read(area=(5, 27, 533, 423), rlevel=5)
np.testing.assert_array_equal(actual, expected)
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
class TestSliceProtocolOpjData(unittest.TestCase):
"""
Test slice protocol, i.e. when using [ ] to read image data.
These correspond to tests for the read method with the area parameter.
"""
@classmethod
def setUpClass(self):
jfile = opj_data_file('input/conformance/p1_04.j2k')
self.j2k = Jp2k(jfile)
self.j2k_data = self.j2k.read()
self.j2k_half_data = self.j2k.read(rlevel=1)
self.j2k_quarter_data = self.j2k.read(rlevel=2)
def test_NR_DEC_p1_04_j2k_43_decode(self):
actual = self.j2k[:1024, :1024]
expected = self.j2k_data
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_44_decode(self):
actual = self.j2k[640:768, 512:640]
expected = self.j2k_data[640:768, 512:640]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_45_decode(self):
actual = self.j2k[896:1024, 896:1024]
expected = self.j2k_data[896:1024, 896:1024]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_46_decode(self):
actual = self.j2k[500:800, 100:300]
expected = self.j2k_data[500:800, 100:300]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_47_decode(self):
actual = self.j2k[520:600, 260:360]
expected = self.j2k_data[520:600, 260:360]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_48_decode(self):
actual = self.j2k[520:660, 260:360]
expected = self.j2k_data[520:660, 260:360]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_49_decode(self):
actual = self.j2k[520:600, 360:400]
expected = self.j2k_data[520:600, 360:400]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_50_decode(self):
actual = self.j2k[:1024:4, :1024:4]
expected = self.j2k_quarter_data[:256, :256]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_51_decode(self):
actual = self.j2k[640:768:4, 512:640:4]
expected = self.j2k_quarter_data[160:192, 128:160]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_52_decode(self):
actual = self.j2k[896:1024:4, 896:1024:4]
expected = self.j2k_quarter_data[224:352, 224:352]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_53_decode(self):
actual = self.j2k[500:800:4, 100:300:4]
expected = self.j2k_quarter_data[125:200, 25:75]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_54_decode(self):
actual = self.j2k[520:600:4, 260:360:4]
expected = self.j2k_quarter_data[130:150, 65:90]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_55_decode(self):
actual = self.j2k[520:660:4, 260:360:4]
expected = self.j2k_quarter_data[130:165, 65:90]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_56_decode(self):
actual = self.j2k[520:600:4, 360:400:4]
expected = self.j2k_quarter_data[130:150, 90:100]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_06_j2k_75_decode(self):
# Image size would be 0 x 0.
with self.assertRaises((IOError, OSError)):
self.j2k[9:12:4, 9:12:4]
def test_NR_DEC_p0_04_j2k_85_decode(self):
actual = self.j2k[:256, :256]
expected = self.j2k_data[:256, :256]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_86_decode(self):
actual = self.j2k[:128, 128:256]
expected = self.j2k_data[:128, 128:256]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_87_decode(self):
actual = self.j2k[10:200, 50:120]
expected = self.j2k_data[10:200, 50:120]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_88_decode(self):
actual = self.j2k[150:210, 10:190]
expected = self.j2k_data[150:210, 10:190]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_89_decode(self):
actual = self.j2k[80:150, 100:200]
expected = self.j2k_data[80:150, 100:200]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_90_decode(self):
actual = self.j2k[20:50, 150:200]
expected = self.j2k_data[20:50, 150:200]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_91_decode(self):
actual = self.j2k[:256:4, :256:4]
expected = self.j2k_quarter_data[0:64, 0:64]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_92_decode(self):
actual = self.j2k[:128:4, 128:256:4]
expected = self.j2k_quarter_data[:32, 32:64]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_93_decode(self):
actual = self.j2k[10:200:4, 50:120:4]
expected = self.j2k_quarter_data[3:50, 13:30]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_94_decode(self):
actual = self.j2k[150:210:4, 10:190:4]
expected = self.j2k_quarter_data[38:53, 3:48]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_95_decode(self):
actual = self.j2k[80:150:4, 100:200:4]
expected = self.j2k_quarter_data[20:38, 25:50]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_96_decode(self):
actual = self.j2k[20:50:4, 150:200:4]
expected = self.j2k_quarter_data[5:13, 38:50]
np.testing.assert_array_equal(actual, expected)
class TestJp2k(unittest.TestCase):
"""These tests should be run by just about all configuration."""
@ -63,6 +364,7 @@ class TestJp2k(unittest.TestCase):
def tearDown(self):
pass
@unittest.skipIf(os.name == "nt", "Unexplained failure on windows")
def test_irreversible(self):
"""Irreversible"""
@ -566,13 +868,6 @@ class TestJp2k_1_x(unittest.TestCase):
def tearDown(self):
pass
def test_area(self):
"""Area option not allowed for 1.x.
"""
j2k = Jp2k(self.j2kfile)
with self.assertRaises(TypeError):
j2k.read(area=(0, 0, 100, 100))
def test_tile(self):
"""tile option not allowed for 1.x.
"""

View file

@ -124,105 +124,6 @@ class TestSuite2point1(unittest.TestCase):
Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_p1_04_j2k_43_decode(self):
jfile = opj_data_file('input/conformance/p1_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(0, 0, 1024, 1024))
odata = jp2k.read()
np.testing.assert_array_equal(ssdata, odata)
def test_NR_DEC_p1_04_j2k_44_decode(self):
jfile = opj_data_file('input/conformance/p1_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(640, 512, 768, 640))
odata = jp2k.read()
np.testing.assert_array_equal(ssdata, odata[640:768, 512:640])
def test_NR_DEC_p1_04_j2k_45_decode(self):
jfile = opj_data_file('input/conformance/p1_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(896, 896, 1024, 1024))
odata = jp2k.read()
np.testing.assert_array_equal(ssdata, odata[896:1024, 896:1024])
def test_NR_DEC_p1_04_j2k_46_decode(self):
jfile = opj_data_file('input/conformance/p1_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(500, 100, 800, 300))
odata = jp2k.read()
np.testing.assert_array_equal(ssdata, odata[500:800, 100:300])
def test_NR_DEC_p1_04_j2k_47_decode(self):
jfile = opj_data_file('input/conformance/p1_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(520, 260, 600, 360))
odata = jp2k.read()
np.testing.assert_array_equal(ssdata, odata[520:600, 260:360])
def test_NR_DEC_p1_04_j2k_48_decode(self):
jfile = opj_data_file('input/conformance/p1_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(520, 260, 660, 360))
odata = jp2k.read()
np.testing.assert_array_equal(ssdata, odata[520:660, 260:360])
def test_NR_DEC_p1_04_j2k_49_decode(self):
jfile = opj_data_file('input/conformance/p1_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(520, 360, 600, 400))
odata = jp2k.read()
np.testing.assert_array_equal(ssdata, odata[520:600, 360:400])
def test_NR_DEC_p1_04_j2k_50_decode(self):
jfile = opj_data_file('input/conformance/p1_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(0, 0, 1024, 1024), rlevel=2)
odata = jp2k.read(rlevel=2)
np.testing.assert_array_equal(ssdata, odata[0:256, 0:256])
def test_NR_DEC_p1_04_j2k_51_decode(self):
jfile = opj_data_file('input/conformance/p1_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(640, 512, 768, 640), rlevel=2)
odata = jp2k.read(rlevel=2)
np.testing.assert_array_equal(ssdata, odata[160:192, 128:160])
def test_NR_DEC_p1_04_j2k_52_decode(self):
jfile = opj_data_file('input/conformance/p1_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(896, 896, 1024, 1024), rlevel=2)
odata = jp2k.read(rlevel=2)
np.testing.assert_array_equal(ssdata, odata[224:352, 224:352])
def test_NR_DEC_p1_04_j2k_53_decode(self):
jfile = opj_data_file('input/conformance/p1_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(500, 100, 800, 300), rlevel=2)
odata = jp2k.read(rlevel=2)
np.testing.assert_array_equal(ssdata, odata[125:200, 25:75])
def test_NR_DEC_p1_04_j2k_54_decode(self):
jfile = opj_data_file('input/conformance/p1_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(520, 260, 600, 360), rlevel=2)
odata = jp2k.read(rlevel=2)
np.testing.assert_array_equal(ssdata, odata[130:150, 65:90])
def test_NR_DEC_p1_04_j2k_55_decode(self):
jfile = opj_data_file('input/conformance/p1_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(520, 260, 660, 360), rlevel=2)
odata = jp2k.read(rlevel=2)
np.testing.assert_array_equal(ssdata, odata[130:165, 65:90])
def test_NR_DEC_p1_04_j2k_56_decode(self):
jfile = opj_data_file('input/conformance/p1_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(520, 360, 600, 400), rlevel=2)
odata = jp2k.read(rlevel=2)
np.testing.assert_array_equal(ssdata, odata[130:150, 90:100])
def test_NR_DEC_p1_04_j2k_57_decode(self):
jfile = opj_data_file('input/conformance/p1_04.j2k')
jp2k = Jp2k(jfile)
@ -263,127 +164,180 @@ class TestSuite2point1(unittest.TestCase):
with self.assertRaises(IOError):
j.read()
def test_NR_DEC_p1_06_j2k_70_decode(self):
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
@unittest.skipIf(re.match(r'''(1|2.0.0)''',
glymur.version.openjpeg_version) is not None,
"Only supported in 2.0.1 or higher")
class TestReadArea(unittest.TestCase):
"""
Runs tests introduced in version 2.0+ or that pass only in 2.0+
Specifically for read method with area parameter.
"""
@classmethod
def setUpClass(self):
jfile = opj_data_file('input/conformance/p1_04.j2k')
self.j2k = Jp2k(jfile)
self.j2k_data = self.j2k.read()
self.j2k_half_data = self.j2k.read(rlevel=1)
self.j2k_quarter_data = self.j2k.read(rlevel=2)
jfile = opj_data_file('input/conformance/p1_06.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(9, 9, 12, 12), rlevel=1)
self.assertEqual(ssdata.shape, (1, 1, 3))
self.j2k_p1_06 = Jp2k(jfile)
def test_NR_DEC_p1_04_j2k_43_decode(self):
actual = self.j2k.read(area=(0, 0, 1024, 1024))
expected = self.j2k_data
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_44_decode(self):
actual = self.j2k.read(area=(640, 512, 768, 640))
expected = self.j2k_data[640:768, 512:640]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_45_decode(self):
actual = self.j2k.read(area=(896, 896, 1024, 1024))
expected = self.j2k_data[896:1024, 896:1024]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_46_decode(self):
actual = self.j2k.read(area=(500, 100, 800, 300))
expected = self.j2k_data[500:800, 100:300]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_47_decode(self):
actual = self.j2k.read(area=(520, 260, 600, 360))
expected = self.j2k_data[520:600, 260:360]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_48_decode(self):
actual = self.j2k.read(area=(520, 260, 660, 360))
expected = self.j2k_data[520:660, 260:360]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_49_decode(self):
actual = self.j2k.read(area=(520, 360, 600, 400))
expected = self.j2k_data[520:600, 360:400]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_50_decode(self):
actual = self.j2k.read(area=(0, 0, 1024, 1024), rlevel=2)
expected = self.j2k_quarter_data
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_51_decode(self):
actual = self.j2k.read(area=(640, 512, 768, 640), rlevel=2)
expected = self.j2k_quarter_data[160:192, 128:160]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_52_decode(self):
actual = self.j2k.read(area=(896, 896, 1024, 1024), rlevel=2)
expected = self.j2k_quarter_data[224:352, 224:352]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_53_decode(self):
actual = self.j2k.read(area=(500, 100, 800, 300), rlevel=2)
expected = self.j2k_quarter_data[125:200, 25:75]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_54_decode(self):
actual = self.j2k.read(area=(520, 260, 600, 360), rlevel=2)
expected = self.j2k_quarter_data[130:150, 65:90]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_55_decode(self):
actual = self.j2k.read(area=(520, 260, 660, 360), rlevel=2)
expected = self.j2k_quarter_data[130:165, 65:90]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_04_j2k_56_decode(self):
actual = self.j2k.read(area=(520, 360, 600, 400), rlevel=2)
expected = self.j2k_quarter_data[130:150, 90:100]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p1_06_j2k_70_decode(self):
actual = self.j2k_p1_06.read(area=(9, 9, 12, 12), rlevel=1)
self.assertEqual(actual.shape, (1, 1, 3))
def test_NR_DEC_p1_06_j2k_71_decode(self):
jfile = opj_data_file('input/conformance/p1_06.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(10, 4, 12, 10), rlevel=1)
self.assertEqual(ssdata.shape, (1, 3, 3))
actual = self.j2k_p1_06.read(area=(10, 4, 12, 10), rlevel=1)
self.assertEqual(actual.shape, (1, 3, 3))
def test_NR_DEC_p1_06_j2k_72_decode(self):
jfile = opj_data_file('input/conformance/p1_06.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(3, 3, 9, 9), rlevel=1)
ssdata = self.j2k_p1_06.read(area=(3, 3, 9, 9), rlevel=1)
self.assertEqual(ssdata.shape, (3, 3, 3))
def test_NR_DEC_p1_06_j2k_73_decode(self):
jfile = opj_data_file('input/conformance/p1_06.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(4, 4, 7, 7), rlevel=1)
ssdata = self.j2k_p1_06.read(area=(4, 4, 7, 7), rlevel=1)
self.assertEqual(ssdata.shape, (2, 2, 3))
def test_NR_DEC_p1_06_j2k_74_decode(self):
jfile = opj_data_file('input/conformance/p1_06.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(4, 4, 5, 5), rlevel=1)
ssdata = self.j2k_p1_06.read(area=(4, 4, 5, 5), rlevel=1)
self.assertEqual(ssdata.shape, (1, 1, 3))
def test_NR_DEC_p1_06_j2k_75_decode(self):
# Image size would be 0 x 0.
jfile = opj_data_file('input/conformance/p1_06.j2k')
jp2k = Jp2k(jfile)
with self.assertRaises((IOError, OSError)):
jp2k.read(area=(9, 9, 12, 12), rlevel=2)
self.j2k_p1_06.read(area=(9, 9, 12, 12), rlevel=2)
def test_NR_DEC_p0_04_j2k_85_decode(self):
jfile = opj_data_file('input/conformance/p0_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(0, 0, 256, 256))
fulldata = jp2k.read()
np.testing.assert_array_equal(fulldata[0:256, 0:256], ssdata)
actual = self.j2k.read(area=(0, 0, 256, 256))
expected = self.j2k_data[:256, :256]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_86_decode(self):
jfile = opj_data_file('input/conformance/p0_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(0, 128, 128, 256))
fulldata = jp2k.read()
np.testing.assert_array_equal(fulldata[0:128, 128:256], ssdata)
actual = self.j2k.read(area=(0, 128, 128, 256))
expected = self.j2k_data[:128, 128:256]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_87_decode(self):
jfile = opj_data_file('input/conformance/p0_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(10, 50, 200, 120))
fulldata = jp2k.read()
np.testing.assert_array_equal(fulldata[10:200, 50:120], ssdata)
actual = self.j2k.read(area=(10, 50, 200, 120))
expected = self.j2k_data[10:200, 50:120]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_88_decode(self):
jfile = opj_data_file('input/conformance/p0_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(150, 10, 210, 190))
fulldata = jp2k.read()
np.testing.assert_array_equal(fulldata[150:210, 10:190], ssdata)
actual = self.j2k.read(area=(150, 10, 210, 190))
expected = self.j2k_data[150:210, 10:190]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_89_decode(self):
jfile = opj_data_file('input/conformance/p0_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(80, 100, 150, 200))
fulldata = jp2k.read()
np.testing.assert_array_equal(fulldata[80:150, 100:200], ssdata)
actual = self.j2k.read(area=(80, 100, 150, 200))
expected = self.j2k_data[80:150, 100:200]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_90_decode(self):
jfile = opj_data_file('input/conformance/p0_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(20, 150, 50, 200))
fulldata = jp2k.read()
np.testing.assert_array_equal(fulldata[20:50, 150:200], ssdata)
actual = self.j2k.read(area=(20, 150, 50, 200))
expected = self.j2k_data[20:50, 150:200]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_91_decode(self):
jfile = opj_data_file('input/conformance/p0_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(0, 0, 256, 256), rlevel=2)
fulldata = jp2k.read(rlevel=2)
np.testing.assert_array_equal(fulldata[0:64, 0:64], ssdata)
actual = self.j2k.read(area=(0, 0, 256, 256), rlevel=2)
expected = self.j2k_quarter_data[0:64, 0:64]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_92_decode(self):
jfile = opj_data_file('input/conformance/p0_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(0, 128, 128, 256), rlevel=2)
fulldata = jp2k.read(rlevel=2)
np.testing.assert_array_equal(fulldata[0:32, 32:64], ssdata)
actual = self.j2k.read(area=(0, 128, 128, 256), rlevel=2)
expected = self.j2k_quarter_data[:32, 32:64]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_93_decode(self):
jfile = opj_data_file('input/conformance/p0_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(10, 50, 200, 120), rlevel=2)
fulldata = jp2k.read(rlevel=2)
np.testing.assert_array_equal(fulldata[3:50, 13:30], ssdata)
actual = self.j2k.read(area=(10, 50, 200, 120), rlevel=2)
expected = self.j2k_quarter_data[3:50, 13:30]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_94_decode(self):
jfile = opj_data_file('input/conformance/p0_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(150, 10, 210, 190), rlevel=2)
fulldata = jp2k.read(rlevel=2)
np.testing.assert_array_equal(fulldata[38:53, 3:48], ssdata)
actual = self.j2k.read(area=(150, 10, 210, 190), rlevel=2)
expected = self.j2k_quarter_data[38:53, 3:48]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_95_decode(self):
jfile = opj_data_file('input/conformance/p0_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(80, 100, 150, 200), rlevel=2)
fulldata = jp2k.read(rlevel=2)
np.testing.assert_array_equal(fulldata[20:38, 25:50], ssdata)
actual = self.j2k.read(area=(80, 100, 150, 200), rlevel=2)
expected = self.j2k_quarter_data[20:38, 25:50]
np.testing.assert_array_equal(actual, expected)
def test_NR_DEC_p0_04_j2k_96_decode(self):
jfile = opj_data_file('input/conformance/p0_04.j2k')
jp2k = Jp2k(jfile)
ssdata = jp2k.read(area=(20, 150, 50, 200), rlevel=2)
fulldata = jp2k.read(rlevel=2)
np.testing.assert_array_equal(fulldata[5:13, 38:50], ssdata)
if __name__ == "__main__":
unittest.main()
actual = self.j2k.read(area=(20, 150, 50, 200), rlevel=2)
expected = self.j2k_quarter_data[5:13, 38:50]
np.testing.assert_array_equal(actual, expected)

View file

@ -16,16 +16,14 @@ import unittest
import warnings
import numpy as np
try:
import skimage.io
skimage.io.use_plugin('freeimage', 'imread')
_HAS_SKIMAGE_FREEIMAGE_SUPPORT = True
except ((ImportError, RuntimeError)):
_HAS_SKIMAGE_FREEIMAGE_SUPPORT = False
except ImportError:
pass
from .fixtures import OPJ_DATA_ROOT, opj_data_file, read_image
from .fixtures import NO_READ_BACKEND, NO_READ_BACKEND_MSG
from .fixtures import NO_SKIMAGE_FREEIMAGE_SUPPORT
from glymur import Jp2k
import glymur
@ -44,7 +42,7 @@ class TestSuiteNegative(unittest.TestCase):
pass
@unittest.skipIf(not _HAS_SKIMAGE_FREEIMAGE_SUPPORT,
@unittest.skipIf(NO_SKIMAGE_FREEIMAGE_SUPPORT,
"Cannot read input image without scikit-image/freeimage")
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
def test_cinema2K_bad_frame_rate(self):

View file

@ -14,22 +14,20 @@ import unittest
import warnings
import numpy as np
try:
import skimage.io
skimage.io.use_plugin('freeimage', 'imread')
_HAS_SKIMAGE_FREEIMAGE_SUPPORT = True
except ((ImportError, RuntimeError)):
_HAS_SKIMAGE_FREEIMAGE_SUPPORT = False
except ImportError:
pass
from .fixtures import read_image, NO_READ_BACKEND, NO_READ_BACKEND_MSG
from .fixtures import OPJ_DATA_ROOT, opj_data_file
from .fixtures import OPJ_DATA_ROOT, NO_SKIMAGE_FREEIMAGE_SUPPORT
from .fixtures import opj_data_file
from . import fixtures
from glymur import Jp2k
import glymur
@unittest.skipIf(not _HAS_SKIMAGE_FREEIMAGE_SUPPORT,
@unittest.skipIf(NO_SKIMAGE_FREEIMAGE_SUPPORT,
"Cannot read input image without scikit-image/freeimage")
@unittest.skipIf(os.name == "nt", "no write support on windows, period")
@unittest.skipIf(re.match(r'''(1|2.0.0)''',
@ -230,7 +228,7 @@ class TestSuiteWriteCinema(unittest.TestCase):
codestream = j.get_codestream()
self.check_cinema2k_codestream(codestream, (1998, 1080))
@unittest.skipIf(not _HAS_SKIMAGE_FREEIMAGE_SUPPORT,
@unittest.skipIf(NO_SKIMAGE_FREEIMAGE_SUPPORT,
"Cannot read input image without scikit-image/freeimage")
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
@unittest.skipIf(not re.match("(1.5|2.0.0)", glymur.version.openjpeg_version),

View file

@ -31,7 +31,7 @@ else:
import lxml.etree as ET
import glymur
from glymur import Jp2k
from glymur import Jp2k, command_line
from . import fixtures
from .fixtures import OPJ_DATA_ROOT, opj_data_file
from .fixtures import text_gbr_27, text_gbr_33, text_gbr_34
@ -107,74 +107,6 @@ class TestPrinting(unittest.TestCase):
with self.assertRaises(TypeError):
glymur.set_printoptions(hi='low')
def test_propts_no_codestream_then_no_xml(self):
"""Verify printed output when codestream=False and xml=False, #162"""
# The print options should be persistent across invocations.
glymur.set_printoptions(codestream=False)
glymur.set_printoptions(xml=False)
with patch('sys.stdout', new=StringIO()) as fake_out:
glymur.jp2dump(self.jp2file)
actual = fake_out.getvalue().strip()
# Get rid of the filename line, as it is not set in stone.
lst = actual.split('\n')
lst = lst[1:]
actual = '\n'.join(lst)
self.assertEqual(actual, fixtures.nemo_dump_no_codestream_no_xml)
def test_printopt_no_codestr_or_xml(self):
"""Verify printed output when codestream=False and xml=False"""
glymur.set_printoptions(codestream=False, xml=False)
with patch('sys.stdout', new=StringIO()) as fake_out:
glymur.jp2dump(self.jp2file)
actual = fake_out.getvalue().strip()
# Get rid of the filename line, as it is not set in stone.
lst = actual.split('\n')
lst = lst[1:]
actual = '\n'.join(lst)
self.assertEqual(actual, fixtures.nemo_dump_no_codestream_no_xml)
def test_printoptions_no_codestream(self):
"""Verify printed output when codestream=False"""
glymur.set_printoptions(codestream=False)
with patch('sys.stdout', new=StringIO()) as fake_out:
glymur.jp2dump(self.jp2file)
actual = fake_out.getvalue().strip()
# Get rid of the filename line, as it is not set in stone.
lst = actual.split('\n')
lst = lst[1:]
actual = '\n'.join(lst)
self.assertEqual(actual, fixtures.nemo_dump_no_codestream)
def test_printoptions_no_xml(self):
"""Verify printed output when xml=False"""
glymur.set_printoptions(xml=False)
with patch('sys.stdout', new=StringIO()) as fake_out:
glymur.jp2dump(self.jp2file)
actual = fake_out.getvalue().strip()
# Get rid of the filename line, as it is not set in stone.
lst = actual.split('\n')
lst = lst[1:]
actual = '\n'.join(lst)
expected = fixtures.nemo_dump_no_xml
self.assertEqual(actual, expected)
def test_printoptions_short(self):
"""Verify printed output when short=True"""
glymur.set_printoptions(short=True)
with patch('sys.stdout', new=StringIO()) as fake_out:
glymur.jp2dump(self.jp2file)
actual = fake_out.getvalue().strip()
# Get rid of the filename line, as it is not set in stone.
lst = actual.split('\n')
lst = lst[1:]
actual = '\n'.join(lst)
self.assertEqual(actual, fixtures.nemo_dump_short)
def test_asoc_label_box(self):
"""verify printing of asoc, label boxes"""
# Construct a fake file with an asoc and a label box, as
@ -228,32 +160,6 @@ class TestPrinting(unittest.TestCase):
expected = '\n'.join(lines)
self.assertEqual(actual, expected)
def test_jp2dump(self):
"""basic jp2dump test"""
with patch('sys.stdout', new=StringIO()) as fake_out:
glymur.jp2dump(self.jp2file)
actual = fake_out.getvalue().strip()
# Get rid of the filename line, as it is not set in stone.
lst = actual.split('\n')
lst = lst[1:]
actual = '\n'.join(lst)
self.assertEqual(actual, fixtures.nemo_dump_full)
def test_entire_file(self):
"""verify output from printing entire file"""
j = glymur.Jp2k(self.jp2file)
with patch('sys.stdout', new=StringIO()) as fake_out:
print(j)
actual = fake_out.getvalue().strip()
# Get rid of the filename line, as it is not set in stone.
lst = actual.split('\n')
lst = lst[1:]
actual = '\n'.join(lst)
self.assertEqual(actual, fixtures.nemo_dump_full)
def test_coc_segment(self):
"""verify printing of COC segment"""
j = glymur.Jp2k(self.jp2file)
@ -1113,5 +1019,71 @@ class TestPrintingOpjDataRoot(unittest.TestCase):
self.assertTrue(True)
if __name__ == "__main__":
unittest.main()
class TestJp2dump(unittest.TestCase):
"""Tests for verifying how jp2dump console script works."""
def setUp(self):
self.jpxfile = glymur.data.jpxfile()
self.jp2file = glymur.data.nemo()
self.j2kfile = glymur.data.goodstuff()
# Reset printoptions for every test.
glymur.set_printoptions(short=False, xml=True, codestream=True)
def tearDown(self):
pass
def run_jp2dump(self, args):
sys.argv = args
with patch('sys.stdout', new=StringIO()) as fake_out:
command_line.main()
actual = fake_out.getvalue().strip()
# Remove the file line, as that is filesystem-dependent.
lines = actual.split('\n')
actual = '\n'.join(lines[1:])
return actual
def test_default_nemo(self):
"""Should be able to dump a JP2 file's metadata with no codestream."""
actual = self.run_jp2dump(['', self.jp2file])
self.assertEqual(actual, fixtures.nemo_dump_no_codestream)
def test_codestream_0(self):
"""Verify dumping with -c 0, supressing all codestream details."""
actual = self.run_jp2dump(['', '-c', '0', self.jp2file])
self.assertEqual(actual, fixtures.nemo_dump_no_codestream)
def test_codestream_1(self):
"""Verify dumping with -c 1, print just the header."""
actual = self.run_jp2dump(['', '-c', '1', self.jp2file])
self.assertEqual(actual, fixtures.nemo_with_codestream_header)
def test_codestream_2(self):
"""Verify dumping with -c 2, full details."""
with patch('sys.stdout', new=StringIO()) as fake_out:
sys.argv = ['', '-c', '2', self.j2kfile]
command_line.main()
actual = fake_out.getvalue().strip()
self.assertIn(fixtures.goodstuff_with_full_header, actual)
def test_codestream_invalid(self):
"""Verify dumping with -c 3, not allowd."""
with self.assertRaises(ValueError):
sys.argv = ['', '-c', '3', self.jp2file]
command_line.main()
def test_short(self):
"""Verify dumping with -s, short option."""
actual = self.run_jp2dump(['', '-s', self.jp2file])
self.assertEqual(actual, fixtures.nemo_dump_short)
def test_suppress_xml(self):
"""Verify dumping with -x, suppress XML."""
actual = self.run_jp2dump(['', '-x', self.jp2file])
self.assertEqual(actual, fixtures.nemo_dump_no_codestream_no_xml)

View file

@ -12,7 +12,9 @@ kwargs = {'name': 'glymur',
'packages': ['glymur', 'glymur.data', 'glymur.test', 'glymur.lib',
'glymur.lib.test'],
'package_data': {'glymur': ['data/*.jp2', 'data/*.j2k', 'data/*.jpx']},
'scripts': ['bin/jp2dump'],
'entry_points': {
'console_scripts': ['jp2dump=glymur.command_line:main'],
},
'license': 'MIT',
'test_suite': 'glymur.test'}