From 1d23ffcfbf5e68102bb651ab450a6443479e9c87 Mon Sep 17 00:00:00 2001 From: John Evans Date: Thu, 25 Jul 2013 15:27:53 -0400 Subject: [PATCH 1/7] Not trying to running opj_version upon import anymore when no library. This should allow us to warn but not error out when neither library is present. We should be able to retrieve metadata on such configurations. --- glymur/lib/openjpeg.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/glymur/lib/openjpeg.py b/glymur/lib/openjpeg.py index 3dd0592..4f990df 100644 --- a/glymur/lib/openjpeg.py +++ b/glymur/lib/openjpeg.py @@ -23,7 +23,12 @@ def version(): # Need to get the minor version, make sure we are at least at 1.4.x #import pdb; pdb.set_trace() -_MINOR = version().split('.')[1] +if OPENJPEG is not None: + _MINOR = version().split('.')[1] +else: + # Does not really matter. But version should not be called if there is no + # OpenJPEG library found. + _MINOR = 0 class EventMgrType(ctypes.Structure): From 4d00cca77749e3d0f9827397baa61f136437a9fa Mon Sep 17 00:00:00 2001 From: John Evans Date: Thu, 25 Jul 2013 15:55:15 -0400 Subject: [PATCH 2/7] pep8 work --- glymur/codestream.py | 4 ++-- glymur/jp2box.py | 2 +- glymur/jp2k.py | 3 +-- glymur/test/test_conformance.py | 12 ++++++------ glymur/test/test_opj_suite.py | 1 - 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/glymur/codestream.py b/glymur/codestream.py index c4d8b4b..637f40e 100644 --- a/glymur/codestream.py +++ b/glymur/codestream.py @@ -140,7 +140,6 @@ class Codestream(object): fptr.seek(self._tile_offset[-1] + self._tile_length[-1]) - def _process_marker_segment(self, fptr, marker_id): """Process and return a segment from the codestream. """ @@ -207,7 +206,8 @@ class Codestream(object): segment = _parse_sot_segment(fptr) self._tile_offset.append(segment.offset) if segment.psot == 0: - tile_part_length = self.offset + self.length - segment.offset - 2 + tile_part_length = (self.offset + self.length - + segment.offset - 2) else: tile_part_length = segment.psot self._tile_length.append(tile_part_length) diff --git a/glymur/jp2box.py b/glymur/jp2box.py index b5637f6..4949752 100644 --- a/glymur/jp2box.py +++ b/glymur/jp2box.py @@ -571,7 +571,7 @@ class CodestreamHeaderBox(Jp2kBox): """ box = CodestreamHeaderBox(length=length, offset=offset) - # The codestream header box is a superbox, so go ahead and parse its + # The codestream header box is a superbox, so go ahead and parse its # child boxes. box.box = box.parse_superbox(fptr) diff --git a/glymur/jp2k.py b/glymur/jp2k.py index 319bf46..2d9b220 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -170,7 +170,7 @@ class Jp2k(Jp2kBox): if ftyp.brand == 'jp2 ': jp2h = [box for box in self.box if box.box_id == 'jp2h'][0] colrs = [box for box in jp2h.box if box.box_id == 'colr'] - for colr in colrs: + for colr in colrs: if colr.method not in (ENUMERATED_COLORSPACE, RESTRICTED_ICC_PROFILE): msg = "Color Specification box method must specify either " @@ -178,7 +178,6 @@ class Jp2k(Jp2kBox): msg += "profile if the file type box brand is 'jp2 '." warnings.warn(msg) - # pylint: disable-msg=W0221 def write(self, img_array, cratios=None, eph=False, psnr=None, numres=None, cbsize=None, psizes=None, grid_offset=None, sop=False, diff --git a/glymur/test/test_conformance.py b/glymur/test/test_conformance.py index 9f40b3e..9e1ad1a 100644 --- a/glymur/test/test_conformance.py +++ b/glymur/test/test_conformance.py @@ -46,7 +46,7 @@ class TestSuiteFormatCorpus(unittest.TestCase): j2k = Jp2k(jfile) with self.assertWarns(UserWarning): c = j2k.get_codestream(header_only=False) - + # The last segment is truncated, so there should not be an EOC marker. self.assertNotEqual(c.segment[-1].marker_id, 'EOC') @@ -61,7 +61,7 @@ class TestSuiteFormatCorpus(unittest.TestCase): j2k = Jp2k(jfile) with self.assertWarns(UserWarning): c = j2k.get_codestream(header_only=False) - + # The last segment is truncated, so there should not be an EOC marker. self.assertNotEqual(c.segment[-1].marker_id, 'EOC') @@ -76,7 +76,7 @@ class TestSuiteFormatCorpus(unittest.TestCase): j2k = Jp2k(jfile) with self.assertWarns(UserWarning): c = j2k.get_codestream(header_only=False) - + # The last segment is truncated, so there should not be an EOC marker. self.assertNotEqual(c.segment[-1].marker_id, 'EOC') @@ -91,7 +91,7 @@ class TestSuiteFormatCorpus(unittest.TestCase): 'balloon_eciRGBv2_ps_adobeplugin.jpf') with self.assertWarns(UserWarning): j2k = Jp2k(jfile) - + def test_jp2_brand_vs_any_icc_profile_multiple_colr(self): # Has colr box, one that conforms, one that does not. @@ -104,7 +104,7 @@ class TestSuiteFormatCorpus(unittest.TestCase): jfile = os.path.join(*lst) with self.assertWarns(UserWarning): j2k = Jp2k(jfile) - + @unittest.skipIf(opj_data_root is None, "OPJ_DATA_ROOT environment variable not set") @@ -124,6 +124,6 @@ class TestSuiteOpj(unittest.TestCase): 'input/nonregression/text_GBR.jp2') with self.assertWarns(UserWarning): j2k = Jp2k(filename) - + if __name__ == "__main__": unittest.main() diff --git a/glymur/test/test_opj_suite.py b/glymur/test/test_opj_suite.py index 4699b06..47d50f8 100644 --- a/glymur/test/test_opj_suite.py +++ b/glymur/test/test_opj_suite.py @@ -832,7 +832,6 @@ class TestSuite(unittest.TestCase): data = Jp2k(jfile).read() self.assertTrue(True) - @unittest.skipIf(sys.hexversion < 0x03020000, "Uses features introduced in 3.2.") def test_NR_DEC_broken3_jp2_6_decode(self): From 589ca8201d39da1c514bcf1488bb709ceef60c19 Mon Sep 17 00:00:00 2001 From: John Evans Date: Thu, 25 Jul 2013 17:50:44 -0400 Subject: [PATCH 3/7] Prepping for 0.2.7 release. --- CHANGES.txt | 3 +++ docs/source/conf.py | 2 +- setup.py | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index bf961a2..8461f8e 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,6 @@ +Jul 25, 2013 - v0.2.7 Warns but no longer errors out when neither library is + found (issue89). + Jul 24, 2013 - v0.2.6 No longer warning when configuration file not found. Added read support for jpch, jplh boxes. Added testing of files in format-corpus repository. diff --git a/docs/source/conf.py b/docs/source/conf.py index 26157b1..b501034 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.2' # The full version, including alpha/beta/rc tags. -release = '0.2.6' +release = '0.2.7' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/setup.py b/setup.py index 098a726..c56c683 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages import sys kwargs = {'name': 'Glymur', - 'version': '0.2.6', + 'version': '0.2.7rc1', 'description': 'Tools for accessing JPEG2000 files', 'long_description': open('README.md').read(), 'author': 'John Evans', From b909272181642a44b7ab46a31f6894c2767040a1 Mon Sep 17 00:00:00 2001 From: John Evans Date: Thu, 25 Jul 2013 18:41:38 -0400 Subject: [PATCH 4/7] Added warning when neither library found, monkey-patched version. Did some things I'm not proud of... Should revisit this. --- glymur/lib/__init__.py | 1 - glymur/lib/config.py | 7 +++++++ glymur/lib/openjpeg.py | 4 +++- glymur/test/test_jp2k.py | 3 +++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/glymur/lib/__init__.py b/glymur/lib/__init__.py index ebd4fa7..ba5915d 100644 --- a/glymur/lib/__init__.py +++ b/glymur/lib/__init__.py @@ -1,4 +1,3 @@ """This package organizes individual libraries employed by glymur.""" from . import openjp2 as _openjp2 from . import openjpeg as _openjpeg -#from . import test diff --git a/glymur/lib/config.py b/glymur/lib/config.py index c29579c..7fcaeb6 100644 --- a/glymur/lib/config.py +++ b/glymur/lib/config.py @@ -58,6 +58,9 @@ def load_openjpeg(libopenjpeg_path): 'bin', 'openjpeg.dll') if os.path.exists(path): libopenjpeg_path = path + else: + # No sense trying further on Linux + return None try: if os.name == "nt": @@ -124,6 +127,10 @@ def glymur_config(): libs = read_config_file() libopenjp2_handle = load_openjp2(libs['openjp2']) libopenjpeg_handle = load_openjpeg(libs['openjpeg']) + if libopenjp2_handle is None and libopenjpeg_handle is None: + msg = "Neither the openjp2 nor the openjpeg library could be loaded. " + msg += "Operating in severely degraded mode." + warnings.warn(msg, UserWarning) return libopenjp2_handle, libopenjpeg_handle diff --git a/glymur/lib/openjpeg.py b/glymur/lib/openjpeg.py index 4f990df..56bdfd3 100644 --- a/glymur/lib/openjpeg.py +++ b/glymur/lib/openjpeg.py @@ -22,13 +22,15 @@ def version(): return library_version # Need to get the minor version, make sure we are at least at 1.4.x -#import pdb; pdb.set_trace() if OPENJPEG is not None: _MINOR = version().split('.')[1] else: # Does not really matter. But version should not be called if there is no # OpenJPEG library found. _MINOR = 0 + # Redefine version so that we can use it. + def version(): + return '0.0.0' class EventMgrType(ctypes.Structure): diff --git a/glymur/test/test_jp2k.py b/glymur/test/test_jp2k.py index 43eaade..34d49a5 100644 --- a/glymur/test/test_jp2k.py +++ b/glymur/test/test_jp2k.py @@ -47,6 +47,9 @@ def load_tests(loader, tests, ignore): return tests +@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None and + glymur.lib.openjpeg.OPENJPEG is None, + "Missing openjp2 library.") class TestConfig(unittest.TestCase): def setUp(self): From 890580ce774e68fb2ac726e277c0c60ec306c770 Mon Sep 17 00:00:00 2001 From: jevans Date: Thu, 25 Jul 2013 19:18:51 -0400 Subject: [PATCH 5/7] Finalizing for 0.2.7 release. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c56c683..52df311 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages import sys kwargs = {'name': 'Glymur', - 'version': '0.2.7rc1', + 'version': '0.2.7', 'description': 'Tools for accessing JPEG2000 files', 'long_description': open('README.md').read(), 'author': 'John Evans', From 1ad3e9412908ddc1e8d8ab79aa60a848071f9151 Mon Sep 17 00:00:00 2001 From: John G Evans Date: Fri, 26 Jul 2013 14:32:53 -0400 Subject: [PATCH 6/7] Using os.path.expanduser on windows to figure out where to put config file. --- glymur/lib/config.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/glymur/lib/config.py b/glymur/lib/config.py index 7fcaeb6..21c1205 100644 --- a/glymur/lib/config.py +++ b/glymur/lib/config.py @@ -143,10 +143,11 @@ def get_configdir(): if 'XDG_CONFIG_HOME' in os.environ: return os.path.join(os.environ['XDG_CONFIG_HOME'], 'glymur') - if 'HOME' in os.environ: + if 'HOME' in os.environ and os.name != 'nt': + # HOME is set by WinPython to something unusual, so we don't + # want that. return os.path.join(os.environ['HOME'], '.config', 'glymur') - if 'USERPROFILE' in os.environ: - # Windows? - return os.path.join(os.environ['USERPROFILE'], 'Application Data', - 'glymur') + if os.name == 'nt': + # Windows. + return os.path.join(os.path.expanduser('~'), 'glymur') From 604d7908c4ae268adaae59f2e750a373dc02e1ec Mon Sep 17 00:00:00 2001 From: John Evans Date: Fri, 26 Jul 2013 14:57:21 -0400 Subject: [PATCH 7/7] Updated windows notes for configuation file location. Closes #91. --- docs/source/detailed_installation.rst | 31 +++++++++++++++++++-------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/docs/source/detailed_installation.rst b/docs/source/detailed_installation.rst index b737843..165868f 100644 --- a/docs/source/detailed_installation.rst +++ b/docs/source/detailed_installation.rst @@ -1,5 +1,5 @@ ---------------------------------- -Detailed Installation Instructions +Advanced Installation Instructions ---------------------------------- '''''''''''''''''''''' @@ -30,8 +30,22 @@ configparser module, i.e. :: openjp2: /opt/openjp2-svn/lib/libopenjp2.so This assumes, of course, that you've installed OpenJPEG into -/opt/openjp2-svn on a linux system. You may also substitute -**$XDG_CONFIG_HOME** for **$HOME/.config**. +/opt/openjp2-svn on a linux system. The location of the configuration file +is platform-dependent (of course). If you use either linux or mac, the path +to the configuration file would normally be :: + + $HOME/.config/glymur/glymurrc + +but if you have **$XDG_CONFIG_HOME** defined, the path will be :: + + $XDG_CONFIG_HOME/glymur/glymurrc + +On windows, the path to the configuration file can be determined by starting up Python +and typing :: + + import os + os.path.join(os.path.expanduser('~'), 'glymur', 'glymurrc') + You may also include a line for the version 1.x openjpeg library if you have it installed in a non-standard place, i.e. :: @@ -124,12 +138,11 @@ In addition, you must install contextlib2 and Pillow via pip. :: Windows ------- -The only configuration I've tested is Python(xy), which uses Python 2.7. -Python(xy) already comes with numpy, but you will have to install pip and then -contextlib2 and mock as well. Glymur seems to work with both 1.5.1 and the -svn development versions of openjpeg. +I would recommend using WinPython, but Python(xy) also seems to work. WinPython 3.3 +should work with no additional installations required, but 2.7 versions still require +contextlib2 and mock to be installed via pip. -Glymur has been tested **far less** extensively on Windows than on the other +Glymur has been tested far less extensively on Windows than on the other platforms. @@ -141,7 +154,7 @@ There are two environment variables you may wish to set before running the tests. * **OPJ_DATA_ROOT** - points to directory for OpenJPEG test data - * **FORMAT_CORPUS_ROOT** - points to directory for format-corpus repository (see https://github.com/openplanets/format-corpus) + * **FORMAT_CORPUS_ROOT** - points to directory for format-corpus repository (see https://github.com/openplanets/format-corpus if you wish, but you really don't need to bother with this) Setting these two environment variables is not required, as any tests using either of them will be skipped.