From f37da173e310bf2a387834b4fcf981d39e4e997b Mon Sep 17 00:00:00 2001 From: John Evans Date: Thu, 15 May 2014 06:58:32 -0400 Subject: [PATCH] Releasing 0.5.12. Fix a few documentation warts. Added changelog into RST documentation. Restored glymur.lib.openjp2.*_v3 functions removed in 0.5.11 --- CHANGES.txt | 2 + docs/source/conf.py | 2 +- docs/source/detailed_installation.rst | 9 +- docs/source/how_do_i.rst | 23 +- docs/source/index.rst | 4 +- docs/source/introduction.rst | 4 +- docs/source/whatsnew/0.5.rst | 50 +++ docs/source/whatsnew/index.rst | 11 + glymur/lib/openjp2.py | 54 +++- glymur/lib/test/test_openjp2_svn.py | 443 ++++++++++++++++++++++++++ glymur/version.py | 2 +- 11 files changed, 578 insertions(+), 26 deletions(-) create mode 100644 docs/source/whatsnew/0.5.rst create mode 100644 docs/source/whatsnew/index.rst create mode 100644 glymur/lib/test/test_openjp2_svn.py diff --git a/CHANGES.txt b/CHANGES.txt index 4799831..82438ca 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,5 @@ +May 18, 2014 - v0.5.12 Restored _v3 functions removed in 0.5.11 + May 09, 2014 - v0.5.11 Added support for Python 3.4, OpenJPEG 2.0.1, and OpenJPEG 2.1.0. diff --git a/docs/source/conf.py b/docs/source/conf.py index 35fe2c0..53d1c0b 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -78,7 +78,7 @@ copyright = u'2013, John Evans' # The short X.Y version. version = '0.5' # The full version, including alpha/beta/rc tags. -release = '0.5.11' +release = '0.5.12' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/source/detailed_installation.rst b/docs/source/detailed_installation.rst index 15c5ed4..cf855df 100644 --- a/docs/source/detailed_installation.rst +++ b/docs/source/detailed_installation.rst @@ -1,20 +1,21 @@ ---------------------------------- Advanced Installation Instructions ---------------------------------- -Most users won't need to read this! You've been warned... '''''''''''''''''''''' Glymur Configuration '''''''''''''''''''''' The default glymur installation process relies upon OpenJPEG being -properly installed on your system as a shared library. You need -at least version 1.5 in order to read and write JPEG 2000 files. +properly installed on your system as a shared library. If you have OpenJPEG +installed through your system's package manager on linux or if you use MacPorts +on the mac, you are probably already set to go. But if you have OpenJPEG +installed into a non-standard place or if you use windows, then read on. Glymur uses ctypes to access the openjp2/openjpeg libraries, and because ctypes accesses libraries in a platform-dependent manner, it is recommended that if you compile and install OpenJPEG into a -non-standard location, you should create a configuration file to +non-standard location, you should then create a configuration file to help Glymur properly find the openjpeg or openjp2 libraries (linux users or macports users don't need to bother with this if you are using OpenJPEG as provided by your package manager). The configuration diff --git a/docs/source/how_do_i.rst b/docs/source/how_do_i.rst index 5cf2c8f..db87774 100644 --- a/docs/source/how_do_i.rst +++ b/docs/source/how_do_i.rst @@ -68,10 +68,11 @@ The **append** method can add an XML box as shown below:: ... add metadata in a more general fashion? =========================================== -An existing raw codestream (or JP2 file) can be wrapped (re-wrapped) in a -user-defined set of JP2 boxes. To get just a minimal JP2 jacket on the -codestream provided by `goodstuff.j2k` (a file consisting of a raw codestream), -you can use the **wrap** method with no box argument: :: +An existing raw codestream or JP2 file can be wrapped (re-wrapped in the case +of JP2) in a user-defined set of JP2 boxes. To get just a minimal +JP2 jacket on the codestream provided by `goodstuff.j2k` (a file +consisting of just a raw codestream), you can use the **wrap** method +with no box argument: :: >>> import glymur >>> jfile = glymur.data.goodstuff() @@ -106,10 +107,12 @@ layer (the signature, file type, JP2 header, and contiguous codestream), with two additional boxes (image header and color specification) contained in the JP2 header superbox. -XML boxes are not in the minimal set of box requirements for the JP2 format, so -in order to add an XML box into the mix before the codestream box, we'll need to -re-specify all of the boxes. If you already have a JP2 jacket in place, you can just reuse that, -though. Take the following example content in an XML file `favorites.xml` : :: +XML boxes are not in the minimal set of box requirements for the +JP2 format, so in order to add an XML box into the mix before the +codestream box, we'll need to re-specify all of the boxes. If you +already have a JP2 jacket in place, you can just reuse that, though. +Take the following example content in an XML file `favorites.xml` +: :: @@ -219,8 +222,8 @@ Here's how the Preview application on the mac shows the RGBA image. .. image:: goodstuff_alpha.png -work with XMP UUIDs? -==================== +... work with XMP UUIDs? +======================== The example JP2 file shipped with glymur has an XMP UUID. :: >>> import glymur diff --git a/docs/source/index.rst b/docs/source/index.rst index 8536be8..3c556d7 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -15,8 +15,10 @@ Contents: introduction detailed_installation how_do_i - roadmap api + roadmap + whatsnew/index + ------------------ Indices and tables diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index bce4598..382f3c3 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -3,7 +3,7 @@ Glymur: a Python interface for JPEG 2000 ---------------------------------------- **Glymur** is an interface to the OpenJPEG library -which allows one to read and write JPEG 2000 files from within Python. +which allows one to read and write JPEG 2000 files from Python. Glymur supports both reading and writing of JPEG 2000 images, but writing JPEG 2000 images is currently limited to images that can fit in memory @@ -18,7 +18,7 @@ Glymur works on Python 2.6, 2.7, 3.3, and 3.4. OpenJPEG Installation ===================== Glymur will read JPEG 2000 images with versions 1.3, 1.4, 1.5, 2.0, and 2.1 of -OpenJPEG. Writing images is only supported with the 1.5 or better, however, +OpenJPEG. Writing images is only supported with OpenJPEG 1.5 or better, however, and version 2.1 is strongly recommended. For more information about OpenJPEG, please consult http://www.openjpeg.org. diff --git a/docs/source/whatsnew/0.5.rst b/docs/source/whatsnew/0.5.rst new file mode 100644 index 0000000..86ce1dd --- /dev/null +++ b/docs/source/whatsnew/0.5.rst @@ -0,0 +1,50 @@ +===================== +Changes in glymur 0.5 +===================== + +Changes in 0.5.12 +================= + +* Minor documentation fixes for grammar and style. +* The functions removed in 0.5.11 due to API changes in OpenJPEG 2.1.0 were + restored for backwards compatibility. They are deprecated, though, and will + be removed in 0.6.0. + + * ``glymur.lib.openjp2.stream_create_default_file_stream_v3`` + * ``glymur.lib.openjp2.opj.stream_destroy_v3`` + + +Changes in 0.5.11 +================= + +* Added support for Python 3.4. +* OpenJPEG 1.5.2 and 2.0.1 are officially supported. +* OpenJPEG 2.1.0 is officially supported, but the ABI changes introduced by + OpenJPEG 2.1.0 required corresponding changes to glymur's ctypes interface. + The functions + + * ``glymur.lib.openjp2.stream_create_default_file_stream_v3`` + * ``glymur.lib.openjp2.opj.stream_destroy_v3`` + + functions were renamed to + + * ``glymur.lib.openjp2.stream_create_default_file_stream`` + * ``glymur.lib.openjp2.opj.stream_destroy`` + + in order to follow OpenJPEG's upstream changes. Unless you were using the + svn version of OpenJPEG, you should not be affected by this. + + +Changes in 0.5.10 +================= + +* Fixed bad warning issued when an unsupported reader requirement box mask + length was encountered. + +Changes in 0.5.9 +================ + +* Fixed bad library load on linux as a result of botched 0.5.8 release. + This release was primarily aimed at supporting SunPy. + + diff --git a/docs/source/whatsnew/index.rst b/docs/source/whatsnew/index.rst new file mode 100644 index 0000000..7a22fac --- /dev/null +++ b/docs/source/whatsnew/index.rst @@ -0,0 +1,11 @@ +.. _whatsnew: + +********************** +"What's new" documents +********************** + +These document the changes between minor (or major) versions of glymur. + +.. toctree:: + + 0.5 diff --git a/glymur/lib/openjp2.py b/glymur/lib/openjp2.py index a28ddfd..69589f5 100644 --- a/glymur/lib/openjp2.py +++ b/glymur/lib/openjp2.py @@ -1293,7 +1293,7 @@ def start_compress(codec, image, stream): def _stream_create_default_file_stream_2p0(fptr, isa_read_stream): - """Wraps openjp2 library function opj_stream_create_default_vile_stream. + """Wraps openjp2 library function opj_stream_create_default_file_stream. Sets the stream to be a file stream. @@ -1318,7 +1318,7 @@ def _stream_create_default_file_stream_2p0(fptr, isa_read_stream): def _stream_create_default_file_stream_2p1(fname, isa_read_stream): - """Wraps openjp2 library function opj_stream_create_default_vile_stream. + """Wraps openjp2 library function opj_stream_create_default_file_stream. Sets the stream to be a file stream. @@ -1343,11 +1343,6 @@ def _stream_create_default_file_stream_2p1(fname, isa_read_stream): read_stream) return stream -if re.match(r'''2.0''', version()): - stream_create_default_file_stream = _stream_create_default_file_stream_2p0 -else: - stream_create_default_file_stream = _stream_create_default_file_stream_2p1 - def stream_destroy(stream): """Wraps openjp2 library function opj_stream_destroy. @@ -1362,6 +1357,51 @@ def stream_destroy(stream): OPENJP2.opj_stream_destroy.restype = ctypes.c_void_p OPENJP2.opj_stream_destroy(stream) +if re.match(r'''2.0''', version()): + # We must have the 2.0.x + stream_create_default_file_stream = _stream_create_default_file_stream_2p0 +else: + # We must have version 2.1. + stream_create_default_file_stream = _stream_create_default_file_stream_2p1 + +# The _v3 functions existed only in the SVN version of OpenJPEG, before 2.1.0 +# was released +stream_create_default_file_stream_v3 = _stream_create_default_file_stream_2p1 +stream_create_default_file_stream_v3.__doc__ = r""" +Wraps openjp2 library function opj_stream_create_default_file_stream_v3. + + Sets the stream to be a file stream. + + This function is deprecated and will be removed in the 0.6.0 version of + glymur. Please use stream_create_default_file_stream instead. + + Parameters + ---------- + fname : str + Specifies a file. + isa_read_stream: bool + True (read) or False (write) + + Returns + ------- + stream : stream_t + An OpenJPEG file stream. + """ + +stream_destroy_v3 = stream_destroy +stream_destroy_v3.__doc__ = r""" +Wraps openjp2 library function opj_stream_destroy. + + Destroys the stream created by create_stream. + + This function is deprecated and wil be removed in the 0.6.0 version of + glymur. Please use stream_destroy instead. + + Parameters + ---------- + stream : STREAM_TYPE_P + The file stream. + """ def write_tile(codec, tile_index, data, data_size, stream): """Wraps openjp2 library function opj_write_tile. diff --git a/glymur/lib/test/test_openjp2_svn.py b/glymur/lib/test/test_openjp2_svn.py new file mode 100644 index 0000000..e52fe80 --- /dev/null +++ b/glymur/lib/test/test_openjp2_svn.py @@ -0,0 +1,443 @@ +""" +Tests for functions that wrap SVN version of libopenjp2 (before release of +2.1.0) +""" +# R0904: Seems like pylint is fooled in this situation +# W0142: using kwargs is ok in this context +# pylint: disable=R0904,W0142 + +# unittest2 is python-2.6 only (pylint/python-2.7) +# pylint: disable=F0401 + +import os +import re +import sys +import tempfile + +if sys.hexversion < 0x02070000: + import unittest2 as unittest +else: + import unittest + +import numpy as np + +import glymur +from glymur.lib import openjp2 + +if re.match("2.0", glymur.version.openjpeg_version): + OPENJP2_IS_V2_OFFICIAL = True +else: + OPENJP2_IS_V2_OFFICIAL = False + +@unittest.skipIf(os.name == "nt", "Temporary file issue on window.") +@unittest.skipIf(openjp2.OPENJP2 is None, + "Missing openjp2 library.") +@unittest.skipIf(OPENJP2_IS_V2_OFFICIAL, "API followed here specific to V2.1") +class TestOpenJP2(unittest.TestCase): + """Test openjp2 library functionality. + + Some tests correspond to those in the openjpeg test suite. + """ + + def test_default_encoder_parameters(self): + """Ensure that the encoder structure is clean upon init.""" + cparams = openjp2.set_default_encoder_parameters() + + self.assertEqual(cparams.res_spec, 0) + self.assertEqual(cparams.cblockw_init, 64) + self.assertEqual(cparams.cblockh_init, 64) + self.assertEqual(cparams.numresolution, 6) + self.assertEqual(cparams.subsampling_dx, 1) + self.assertEqual(cparams.subsampling_dy, 1) + self.assertEqual(cparams.mode, 0) + self.assertEqual(cparams.prog_order, glymur.core.LRCP) + self.assertEqual(cparams.roi_shift, 0) + self.assertEqual(cparams.cp_tx0, 0) + self.assertEqual(cparams.cp_ty0, 0) + + self.assertEqual(cparams.irreversible, 0) + + def test_default_decoder_parameters(self): + """Tests that the structure is clean upon initialization""" + dparams = openjp2.set_default_decoder_parameters() + + self.assertEqual(dparams.DA_x0, 0) + self.assertEqual(dparams.DA_y0, 0) + self.assertEqual(dparams.DA_x1, 0) + self.assertEqual(dparams.DA_y1, 0) + + def tile_macro(self, codec, stream, imagep, tidx): + """called only by j2k_random_tile_access""" + openjp2.get_decoded_tile(codec, stream, imagep, tidx) + for j in range(imagep.contents.numcomps): + self.assertIsNotNone(imagep.contents.comps[j].data) + + def j2k_random_tile_access(self, filename, codec_format=None): + """fixture called by the test_rtaX methods""" + dparam = openjp2.set_default_decoder_parameters() + + infile = filename.encode() + nelts = openjp2.PATH_LEN - len(infile) + infile += b'0' * nelts + dparam.infile = infile + + dparam.decod_format = codec_format + + codec = openjp2.create_decompress(codec_format) + + openjp2.set_info_handler(codec, None) + openjp2.set_warning_handler(codec, None) + openjp2.set_error_handler(codec, None) + + stream = openjp2.stream_create_default_file_stream_v3(filename, True) + + openjp2.setup_decoder(codec, dparam) + image = openjp2.read_header(stream, codec) + + cstr_info = openjp2.get_cstr_info(codec) + + tile_ul = 0 + tile_ur = cstr_info.contents.tw - 1 + tile_lr = cstr_info.contents.tw * cstr_info.contents.th - 1 + tile_ll = tile_lr - cstr_info.contents.tw + + self.tile_macro(codec, stream, image, tile_ul) + self.tile_macro(codec, stream, image, tile_ur) + self.tile_macro(codec, stream, image, tile_lr) + self.tile_macro(codec, stream, image, tile_ll) + + openjp2.destroy_cstr_info(cstr_info) + + openjp2.end_decompress(codec, stream) + openjp2.destroy_codec(codec) + openjp2.stream_destroy_v3(stream) + openjp2.image_destroy(image) + + def test_tte0(self): + """Runs test designated tte0 in OpenJPEG test suite.""" + with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: + ttx0_setup(tfile.name) + self.assertTrue(True) + + def test_ttd0(self): + """Runs test designated ttd0 in OpenJPEG test suite.""" + with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: + + # Produce the tte0 output file for ttd0 input. + ttx0_setup(tfile.name) + + kwargs = {'x0': 0, + 'y0': 0, + 'x1': 1000, + 'y1': 1000, + 'filename': tfile.name, + 'codec_format': openjp2.CODEC_J2K} + tile_decoder(**kwargs) + self.assertTrue(True) + + def xtx1_setup(self, filename): + """Runs tests tte1, rta1.""" + kwargs = {'filename': filename, + 'codec': openjp2.CODEC_J2K, + 'comp_prec': 8, + 'irreversible': 1, + 'num_comps': 3, + 'image_height': 256, + 'image_width': 256, + 'tile_height': 128, + 'tile_width': 128} + tile_encoder(**kwargs) + self.assertTrue(True) + + def test_tte1(self): + """Runs test designated tte1 in OpenJPEG test suite.""" + with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: + self.xtx1_setup(tfile.name) + + def test_ttd1(self): + """Runs test designated ttd1 in OpenJPEG test suite.""" + with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: + + # Produce the tte0 output file for ttd0 input. + self.xtx1_setup(tfile.name) + + kwargs = {'x0': 0, + 'y0': 0, + 'x1': 128, + 'y1': 128, + 'filename': tfile.name, + 'codec_format': openjp2.CODEC_J2K} + tile_decoder(**kwargs) + self.assertTrue(True) + + def test_rta1(self): + """Runs test designated rta1 in OpenJPEG test suite.""" + with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: + self.xtx1_setup(tfile.name) + + codec_format = openjp2.CODEC_J2K + self.j2k_random_tile_access(tfile.name, codec_format) + self.assertTrue(True) + + def test_tte2(self): + """Runs test designated tte2 in OpenJPEG test suite.""" + with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: + xtx2_setup(tfile.name) + self.assertTrue(True) + + def test_ttd2(self): + """Runs test designated ttd2 in OpenJPEG test suite.""" + with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: + # Produce the tte0 output file for ttd0 input. + xtx2_setup(tfile.name) + + kwargs = {'x0': 0, + 'y0': 0, + 'x1': 128, + 'y1': 128, + 'filename': tfile.name, + 'codec_format': openjp2.CODEC_JP2} + tile_decoder(**kwargs) + self.assertTrue(True) + + def test_rta2(self): + """Runs test designated rta2 in OpenJPEG test suite.""" + with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: + xtx2_setup(tfile.name) + + codec_format = openjp2.CODEC_JP2 + self.j2k_random_tile_access(tfile.name, codec_format) + + def test_tte3(self): + """Runs test designated tte3 in OpenJPEG test suite.""" + with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: + xtx3_setup(tfile.name) + self.assertTrue(True) + + def test_rta3(self): + """Runs test designated rta3 in OpenJPEG test suite.""" + with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: + xtx3_setup(tfile.name) + + codec_format = openjp2.CODEC_J2K + self.j2k_random_tile_access(tfile.name, codec_format) + self.assertTrue(True) + + def test_tte4(self): + """Runs test designated tte4 in OpenJPEG test suite.""" + with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: + xtx4_setup(tfile.name) + self.assertTrue(True) + + def test_rta4(self): + """Runs test designated rta4 in OpenJPEG test suite.""" + with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: + xtx4_setup(tfile.name) + + codec_format = openjp2.CODEC_J2K + self.j2k_random_tile_access(tfile.name, codec_format) + + def test_tte5(self): + """Runs test designated tte5 in OpenJPEG test suite.""" + with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: + xtx5_setup(tfile.name) + self.assertTrue(True) + + def test_rta5(self): + """Runs test designated rta5 in OpenJPEG test suite.""" + with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: + xtx5_setup(tfile.name) + + codec_format = openjp2.CODEC_J2K + self.j2k_random_tile_access(tfile.name, codec_format) + + +#def tile_encoder(num_comps=None, tile_width=None, tile_height=None, +# filename=None, codec=None, comp_prec=None, +# image_width=None, image_height=None, +# irreversible=None): +def tile_encoder(**kwargs): + """Fixture used by many tests.""" + num_tiles = ((kwargs['image_width'] / kwargs['tile_width']) * + (kwargs['image_height'] / kwargs['tile_height'])) + tile_size = ((kwargs['tile_width'] * kwargs['tile_height']) * + (kwargs['num_comps'] * kwargs['comp_prec'] / 8)) + + data = np.random.random((kwargs['tile_height'], + kwargs['tile_width'], + kwargs['num_comps'])) + data = (data * 255).astype(np.uint8) + + l_param = openjp2.set_default_encoder_parameters() + + l_param.tcp_numlayers = 1 + l_param.cp_fixed_quality = 1 + l_param.tcp_distoratio[0] = 20 + + # position of the tile grid aligned with the image + l_param.cp_tx0 = 0 + l_param.cp_ty0 = 0 + + # tile size, we are using tile based encoding + l_param.tile_size_on = 1 + l_param.cp_tdx = kwargs['tile_width'] + l_param.cp_tdy = kwargs['tile_height'] + + # use irreversible encoding + l_param.irreversible = kwargs['irreversible'] + + l_param.numresolution = 6 + + l_param.prog_order = glymur.core.LRCP + + l_params = (openjp2.ImageComptParmType * kwargs['num_comps'])() + for j in range(kwargs['num_comps']): + l_params[j].dx = 1 + l_params[j].dy = 1 + l_params[j].h = kwargs['image_height'] + l_params[j].w = kwargs['image_width'] + l_params[j].sgnd = 0 + l_params[j].prec = kwargs['comp_prec'] + l_params[j].x0 = 0 + l_params[j].y0 = 0 + + codec = openjp2.create_compress(kwargs['codec']) + + openjp2.set_info_handler(codec, None) + openjp2.set_warning_handler(codec, None) + openjp2.set_error_handler(codec, None) + + cspace = openjp2.CLRSPC_SRGB + l_image = openjp2.image_tile_create(l_params, cspace) + + l_image.contents.x0 = 0 + l_image.contents.y0 = 0 + l_image.contents.x1 = kwargs['image_width'] + l_image.contents.y1 = kwargs['image_height'] + l_image.contents.color_space = openjp2.CLRSPC_SRGB + + openjp2.setup_encoder(codec, l_param, l_image) + + stream = openjp2.stream_create_default_file_stream_v3(kwargs['filename'], + False) + openjp2.start_compress(codec, l_image, stream) + + for j in np.arange(num_tiles): + openjp2.write_tile(codec, j, data, tile_size, stream) + + openjp2.end_compress(codec, stream) + openjp2.stream_destroy_v3(stream) + openjp2.destroy_codec(codec) + openjp2.image_destroy(l_image) + +def tile_decoder(**kwargs): + """Fixture called with various configurations by many tests. + + Reads a tile. That's all it does. + """ + stream = openjp2.stream_create_default_file_stream_v3(kwargs['filename'], + True) + dparam = openjp2.set_default_decoder_parameters() + + dparam.decod_format = kwargs['codec_format'] + + # Do not use layer decoding limitation. + dparam.cp_layer = 0 + + # do not use resolution reductions. + dparam.cp_reduce = 0 + + codec = openjp2.create_decompress(kwargs['codec_format']) + + openjp2.set_info_handler(codec, None) + openjp2.set_warning_handler(codec, None) + openjp2.set_error_handler(codec, None) + + openjp2.setup_decoder(codec, dparam) + image = openjp2.read_header(stream, codec) + openjp2.set_decode_area(codec, image, + kwargs['x0'], kwargs['y0'], + kwargs['x1'], kwargs['y1']) + + data = np.zeros((1150, 2048, 3), dtype=np.uint8) + while True: + rargs = openjp2.read_tile_header(codec, stream) + tidx = rargs[0] + size = rargs[1] + go_on = rargs[-1] + if not go_on: + break + openjp2.decode_tile_data(codec, tidx, data, size, stream) + + openjp2.end_decompress(codec, stream) + openjp2.destroy_codec(codec) + openjp2.stream_destroy_v3(stream) + openjp2.image_destroy(image) + +def ttx0_setup(filename): + """Runs tests tte0, tte0.""" + kwargs = {'filename': filename, + 'codec': openjp2.CODEC_J2K, + 'comp_prec': 8, + 'irreversible': 1, + 'num_comps': 3, + 'image_height': 200, + 'image_width': 200, + 'tile_height': 100, + 'tile_width': 100} + tile_encoder(**kwargs) + +def xtx2_setup(filename): + """Runs tests rta2, tte2, ttd2.""" + kwargs = {'filename': filename, + 'codec': openjp2.CODEC_JP2, + 'comp_prec': 8, + 'irreversible': 1, + 'num_comps': 3, + 'image_height': 256, + 'image_width': 256, + 'tile_height': 128, + 'tile_width': 128} + tile_encoder(**kwargs) + +def xtx3_setup(filename): + """Runs tests tte3, rta3.""" + kwargs = {'filename': filename, + 'codec': openjp2.CODEC_J2K, + 'comp_prec': 8, + 'irreversible': 1, + 'num_comps': 1, + 'image_height': 256, + 'image_width': 256, + 'tile_height': 128, + 'tile_width': 128} + tile_encoder(**kwargs) + +def xtx4_setup(filename): + """Runs tests rta4, tte4.""" + kwargs = {'filename': filename, + 'codec': openjp2.CODEC_J2K, + 'comp_prec': 8, + 'irreversible': 0, + 'num_comps': 1, + 'image_height': 256, + 'image_width': 256, + 'tile_height': 128, + 'tile_width': 128} + tile_encoder(**kwargs) + +def xtx5_setup(filename): + """Runs tests rta5, tte5.""" + kwargs = {'filename': filename, + 'codec': openjp2.CODEC_J2K, + 'comp_prec': 8, + 'irreversible': 0, + 'num_comps': 1, + 'image_height': 512, + 'image_width': 512, + 'tile_height': 256, + 'tile_width': 256} + tile_encoder(**kwargs) + +if __name__ == "__main__": + unittest.main() diff --git a/glymur/version.py b/glymur/version.py index 2e6a8cb..4a9e4e5 100644 --- a/glymur/version.py +++ b/glymur/version.py @@ -15,7 +15,7 @@ from .lib import openjp2 as opj2 # Do not change the format of this next line! Doing so risks breaking # setup.py -version = "0.5.11" +version = "0.5.12" _sv = LooseVersion(version) version_tuple = _sv.version