diff --git a/glymur/jp2dump.py b/glymur/jp2dump.py index 82c710b..c0f0f7f 100644 --- a/glymur/jp2dump.py +++ b/glymur/jp2dump.py @@ -34,4 +34,3 @@ def jp2dump(filename, codestream=False): warning.lineno, warning.category.__name__, warning.message)) - diff --git a/glymur/jp2k.py b/glymur/jp2k.py index 8dba499..ff3b92a 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -966,8 +966,10 @@ class Jp2k(Jp2kBox): dparam.nb_tile_to_decode = 1 with ExitStack() as stack: - if hasattr(_opj2.OPENJP2, 'opj_stream_create_default_file_stream_v3'): - stream = _opj2.stream_create_default_file_stream_v3(self.filename, + if hasattr(_opj2.OPENJP2, + 'opj_stream_create_default_file_stream_v3'): + filename = self.filename + stream = _opj2.stream_create_default_file_stream_v3(filename, True) stack.callback(_opj2.stream_destroy_v3, stream) else: diff --git a/glymur/test/__init__.py b/glymur/test/__init__.py index e69de29..b61a5e1 100644 --- a/glymur/test/__init__.py +++ b/glymur/test/__init__.py @@ -0,0 +1,3 @@ +""" +Test suite for glymur high-level functionality. +""" diff --git a/glymur/test/fixtures.py b/glymur/test/fixtures.py index 6309c3e..b6ba85d 100644 --- a/glymur/test/fixtures.py +++ b/glymur/test/fixtures.py @@ -1,3 +1,6 @@ +""" +Test fixtures common to more than one test point. +""" import re import sys import warnings @@ -21,18 +24,22 @@ if glymur.lib.openjp2.OPENJP2 is not None: OPENJP2_IS_V2_OFFICIAL = True -msg = "Matplotlib with the PIL backend must be available in order to run the " -msg += "tests in this suite." -no_read_backend_msg = msg +NO_READ_BACKEND_MSG = "Matplotlib with the PIL backend must be available in " +NO_READ_BACKEND_MSG += "order to run the tests in this suite." + try: - from PIL import Image from matplotlib.pyplot import imread - no_read_backend = False -except: - no_read_backend = True + NO_READ_BACKEND = False +except ImportError: + NO_READ_BACKEND = True + def read_image(infile): - # PIL issues warnings which we do not care about, so suppress them. + """Read image using matplotlib backend. + + Hopefully PIL(low) is installed as matplotlib's backend. It issues + warnings which we do not care about, so suppress them. + """ with warnings.catch_warnings(): warnings.simplefilter("ignore") data = imread(infile) @@ -55,27 +62,9 @@ def peak_tolerance(amat, bmat): def read_pgx(pgx_file): """Helper function for reading the PGX comparison files. - - Open the file in ascii mode and read the header line. - Will look something like - - PG ML + 8 128 128 - PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d" """ - header = '' - with open(pgx_file, 'rb') as fptr: - while True: - char = fptr.read(1) - if char[0] == 10 or char == '\n': - pos = fptr.tell() - break - else: - if sys.hexversion < 0x03000000: - header += char - else: - header += chr(char[0]) + header, pos = read_pgx_header(pgx_file) - header = header.rstrip() tokens = re.split(r'\s', header) if (tokens[1][0] == 'M') and (sys.byteorder == 'little'): @@ -100,6 +89,28 @@ def read_pgx(pgx_file): nrows = int(tokens[4]) ncols = int(tokens[3]) + dtype = determine_pgx_datatype(signed, bitdepth) + + shape = [nrows, ncols] + + # Reopen the file in binary mode and seek to the start of the binary + # data + with open(pgx_file, 'rb') as fptr: + fptr.seek(pos) + data = np.fromfile(file=fptr, dtype=dtype).reshape(shape) + + return(data.byteswap(swapbytes)) + +def determine_pgx_datatype(signed, bitdepth): + """Determine the datatype of the PGX file. + + Parameters + ---------- + signed : bool + True if the datatype is signed, false otherwise + bitdepth : int + How many bits are used to make up an image plane. Should be 8 or 16. + """ if signed: if bitdepth <= 8: dtype = np.int8 @@ -115,12 +126,28 @@ def read_pgx(pgx_file): else: raise RuntimeError("unhandled bitdepth") - shape = [nrows, ncols] + return dtype - # Reopen the file in binary mode and seek to the start of the binary - # data +def read_pgx_header(pgx_file): + """Open the file in ascii mode (not really) and read the header line. + Will look something like + + PG ML + 8 128 128 + PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d" + """ + header = '' with open(pgx_file, 'rb') as fptr: - fptr.seek(pos) - data = np.fromfile(file=fptr, dtype=dtype).reshape(shape) + while True: + char = fptr.read(1) + if char[0] == 10 or char == '\n': + pos = fptr.tell() + break + else: + if sys.hexversion < 0x03000000: + header += char + else: + header += chr(char[0]) + + header = header.rstrip() + return header, pos - return(data.byteswap(swapbytes)) diff --git a/glymur/test/test_jp2k.py b/glymur/test/test_jp2k.py index 6e1e7a0..1371a05 100644 --- a/glymur/test/test_jp2k.py +++ b/glymur/test/test_jp2k.py @@ -66,7 +66,7 @@ class TestConfig(unittest.TestCase): """Don't have either openjp2 or openjpeg libraries? Must error out. """ with patch('glymur.lib.openjp2.OPENJP2', new=None): - with patch('glymur.lib.openjpeg.OPENJPEG', new=None): + with patch('glymur.lib.openjpeg.OPENJPEG', new=None): with self.assertRaises(glymur.jp2k.LibraryNotFoundError): d = glymur.Jp2k(self.jp2file).read() @@ -74,7 +74,7 @@ class TestConfig(unittest.TestCase): """Don't have openjp2 library? Must error out. """ with patch('glymur.lib.openjp2.OPENJP2', new=None): - with patch('glymur.lib.openjpeg.OPENJPEG', new=None): + with patch('glymur.lib.openjpeg.OPENJPEG', new=None): with self.assertRaises(glymur.jp2k.LibraryNotFoundError): d = glymur.Jp2k(self.jp2file).read_bands() @@ -84,7 +84,7 @@ class TestConfig(unittest.TestCase): """ data = glymur.Jp2k(self.j2kfile).read() with patch('glymur.lib.openjp2.OPENJP2', new=None): - with patch('glymur.lib.openjpeg.OPENJPEG', new=None): + with patch('glymur.lib.openjpeg.OPENJPEG', new=None): with self.assertRaises(glymur.jp2k.LibraryNotFoundError): with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: ofile = Jp2k(tfile.name, 'wb') diff --git a/glymur/test/test_opj_suite_neg.py b/glymur/test/test_opj_suite_neg.py index 41a0b5e..f851926 100644 --- a/glymur/test/test_opj_suite_neg.py +++ b/glymur/test/test_opj_suite_neg.py @@ -17,17 +17,7 @@ import pkg_resources from glymur.lib import openjp2 as opj2 -from .fixtures import read_image - -msg = "Matplotlib with the PIL backend must be available in order to run the " -msg += "tests in this suite." -no_read_backend_msg = msg -try: - from PIL import Image - from matplotlib.pyplot import imread - no_read_backend = False -except: - no_read_backend = True +from .fixtures import read_image, NO_READ_BACKEND, NO_READ_BACKEND_MSG from glymur import Jp2k import glymur @@ -42,7 +32,7 @@ except: @unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None, "Missing openjp2 library.") -@unittest.skipIf(no_read_backend, no_read_backend_msg) +@unittest.skipIf(NO_READ_BACKEND, NO_READ_BACKEND_MSG) @unittest.skipIf(data_root is None, "OPJ_DATA_ROOT environment variable not set") class TestSuiteNegative(unittest.TestCase): diff --git a/glymur/test/test_opj_suite_write.py b/glymur/test/test_opj_suite_write.py index 41737fd..766297b 100644 --- a/glymur/test/test_opj_suite_write.py +++ b/glymur/test/test_opj_suite_write.py @@ -17,7 +17,7 @@ import numpy as np from glymur.lib import openjp2 as opj2 -from .fixtures import read_image, no_read_backend, no_read_backend_msg +from .fixtures import read_image, NO_READ_BACKEND, NO_READ_BACKEND_MSG from glymur import Jp2k import glymur @@ -33,7 +33,7 @@ except: @unittest.skipIf(os.name == "nt", "no write support on windows, period") @unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None, "Missing openjp2 library.") -@unittest.skipIf(no_read_backend, no_read_backend_msg) +@unittest.skipIf(NO_READ_BACKEND, NO_READ_BACKEND_MSG) @unittest.skipIf(data_root is None, "OPJ_DATA_ROOT environment variable not set") class TestSuiteWrite(unittest.TestCase):