diff --git a/CHANGES.txt b/CHANGES.txt index efc70fc..167e2b0 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,7 @@ +Jul 11, 2013 - v0.2.2 Fixed mistakes with trove classifier, pypi releases. + +Jul 11, 2013 - v0.2.0 Support for Python 2.7 on windows, OpenJPEG 1.5.1. + Jun 27, 2013 - v0.1.10 Can wrap codestreams in custom JP2 jackets. Exposing parameter to specify multi component transform. Added a raw codestream file. diff --git a/docs/source/conf.py b/docs/source/conf.py index 6ddfcfb..13ea741 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.1' # The full version, including alpha/beta/rc tags. -release = '0.1.10' +release = '0.2.2' # 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 1e6fe4b..d05dae4 100644 --- a/docs/source/detailed_installation.rst +++ b/docs/source/detailed_installation.rst @@ -7,15 +7,15 @@ Glymur Configuration '''''''''''''''''''''' The default glymur installation process relies upon OpenJPEG version -1.5.1 being properly installed on your system. This will, however, -only give you you basic read capabilities, so if you wish to take -advantage of more of glymur's features, you should compile OpenJPEG as -a shared library from the developmental source that you can retrieve -via subversion. As of this time of writing, svn revision 2345 works. -You should also download the test data for the purpose of configuring -and running OpenJPEG's test suite, check their instructions for all this. -You should set the **OPJ_DATA_ROOT** environment variable for the purpose -of running Glymur's test suite. :: +1.5.1 being properly installed on your system. This will, however, only +give you you basic read capabilities, so if you wish to take advantage +of more of glymur's features, you should compile OpenJPEG as a shared +library (named *openjp2* instead of *openjpeg*) from the developmental +source that you can retrieve via subversion. As of this time of writing, +svn revision 2345 works. You should also download the test data for +the purpose of configuring and running OpenJPEG's test suite, check +their instructions for all this. You should set the **OPJ_DATA_ROOT** +environment variable for the purpose of running Glymur's test suite. :: $ svn co http://openjpeg.googlecode.com/svn/data $ export OPJ_DATA_ROOT=`pwd`/data @@ -32,13 +32,16 @@ the openjp2 library. You may create the configuration file as follows:: > openjp2: /opt/openjp2-svn/lib/libopenjp2.so > EOF -That assumes, of course, that you've installed OpenJPEG into +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**. -Again, though, the configuration file is not required if you only wish to -read JPEG 2000 files using OpenJPEG version 1.5.1. +You may also include a line for the version 1.5.1 library if you have it installed +in a non-standard place, i.e. :: + [library] + openjp2: /opt/openjp2-svn/lib/libopenjp2.so + openjpeg: /not/the/usual/location/lib/libopenjpeg.so ''''''''''''''''''''''''''''''''''''''''''' Package Management Suggestions for Testing @@ -65,13 +68,29 @@ additionally be installed: * py33-scikit-image and either py33-Pillow or freeimage * py33-matplotlib and py33-Pillow +MacPorts supplies both OpenJPEG 1.5.0 and OpenJPEG 2.0.0. As previously +mentioned, the 2.0.0 official release is not supported (although the 2.0+ +development version via SVN *is* supported). + Linux ----- +Fedora 19 +''''''''' +Fedora 18 ships with Python 3.3 and all the necessary RPMs are available to +run the maximum number of tests. + + * python3 + * python3-numpy + * python3-setuptools + * python3-matplotlib (for running tests) + * python3-matplotlib-tk (or whichever matplotlib backend you prefer) + * python3-pillow (for running tests) + Fedora 18 ''''''''' -Fedora 18 ships with Python 3.3, so all the necessary RPMs are available to -meet the minimal set of requirements. +Fedora 18 ships with Python 3.3 and the following RPMs are available to +meet the minimal set of requirements for running glymur. * python3 * python3-numpy @@ -94,28 +113,6 @@ repositories:: $ pip-python3 install Pillow --user $ export PYTHONPATH=$HOME/.local/lib/python3.3/site-packages:$PYTHONPATH -Raspbian -'''''''' -Yeah, this was the first thing I tried after getting my new Raspberry -Pi hooked up (couldn't help myself :-) Raspbian ships with Python -3.2 and 2.7, so these steps detail working with 2.7. - -Additional required OS packages include:: - - * python-pip - * python-pkg-resources - * python-mock - -You must install contextlib2 via pip, and then you can run at least -a minimal number of tests. To attempt to run more of the tests, -install the following debs:: - - * python-dev - * python-matplotlib - -and then install Pillow via pip. The tests take about 30 minutes to run, with -one unexpected failure as of the time of writing. - Fedora 17 ''''''''' Fedora 17 ships with Python 3.2 and 2.7, but OpenJPEG is only at version 1.4, @@ -152,20 +149,21 @@ 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 as well. This configuration assumes you've installed OpenJPEG -1.5.1. +contextlib2 and mock as well. Both 1.5.1 and the svn development versions of +openjpeg work. + ''''''' Testing ''''''' -If you wish to run the tests (strongly suggested :-), you can either run them +If you wish to run the tests (strongly recommended :-), you can either run them from within python as follows ... :: >>> import glymur >>> glymur.runtests() -or from the unix command line. :: +or from the command line. :: $ cd /to/where/you/unpacked/glymur $ python -m unittest discover diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index 5818c1b..3fbbb84 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -27,8 +27,8 @@ about OpenJPEG, please consult http://www.openjpeg.org. If you use MacPorts on the mac or if you have a sufficiently recent version of Linux, your package manager should already provide you with at least version 1.5.1 of OpenJPEG, which means that glymur can be installed ready to read JPEG -2000 images. If you use windows, I suggest using the 1.5.1 windows installer provided -to you by the OpenJPEG folks at +2000 images. If you use windows, I suggest using the 1.5.1 windows installer +provided to you by the OpenJPEG folks at https://code.google.com/p/openjpeg/downloads/list . Glymur Installation @@ -56,5 +56,5 @@ You can run the tests from within python as follows:: >>> glymur.runtests() Many tests are currently skipped; in fact most of them are skipped if you -are relying on OpenJPEG 1.5.1. But the important thing is whether or not any -tests fail. +are relying on OpenJPEG 1.5.1. But the important thing, though, is whether or +not any tests fail. diff --git a/glymur/data/__init__.py b/glymur/data/__init__.py index bebfb08..c95b144 100644 --- a/glymur/data/__init__.py +++ b/glymur/data/__init__.py @@ -17,8 +17,8 @@ def nemo(): file : str Platform-independent path to nemo.jp2. """ - file = pkg_resources.resource_filename(__name__, "nemo.jp2") - return file + filename = pkg_resources.resource_filename(__name__, "nemo.jp2") + return filename def goodstuff(): @@ -29,5 +29,5 @@ def goodstuff(): file : str Platform-independent path to goodstuff.j2k. """ - file = pkg_resources.resource_filename(__name__, "goodstuff.j2k") - return file + filename = pkg_resources.resource_filename(__name__, "goodstuff.j2k") + return filename diff --git a/glymur/jp2box.py b/glymur/jp2box.py index 164da61..7e5014c 100644 --- a/glymur/jp2box.py +++ b/glymur/jp2box.py @@ -38,11 +38,13 @@ _METHOD_DISPLAY = { ANY_ICC_PROFILE: 'any ICC profile', VENDOR_COLOR_METHOD: 'vendor color method'} -_ = {1: 'accurately represents correct colorspace definition', - 2: 'approximates correct colorspace definition, exceptional quality', - 3: 'approximates correct colorspace definition, reasonable quality', - 4: 'approximates correct colorspace definition, poor quality'} -_approximation_display = _ +_APPROX_DISPLAY = {1: 'accurately represents correct colorspace definition', + 2: 'approximates correct colorspace definition, ' + + 'exceptional quality', + 3: 'approximates correct colorspace definition, ' + + 'reasonable quality', + 4: 'approximates correct colorspace definition, ' + + 'poor quality'} class Jp2kBox(object): @@ -66,12 +68,15 @@ class Jp2kBox(object): self.offset = offset self.longname = longname + # should never be used except for last box in file. + self._file_size = -1 + def __str__(self): msg = "{0} Box ({1})".format(self.longname, self.box_id) msg += " @ ({0}, {1})".format(self.offset, self.length) return msg - def write(self, fptr): + def write(self, _): """Must be implemented in a subclass. """ msg = "Not supported for {0} box.".format(self.longname) @@ -120,7 +125,7 @@ class Jp2kBox(object): # Call the proper parser for the given box with ID "T". try: - box = _BOX_WITH_ID[box_id]._parse(fptr, start, num_bytes) + box = _BOX_WITH_ID[box_id].parse(fptr, start, num_bytes) except KeyError: msg = 'Unrecognized box ({0}) encountered.'.format(box_id) warnings.warn(msg) @@ -177,6 +182,7 @@ class ColourSpecificationBox(Jp2kBox): ICC profile header according to ICC profile specification. If colorspace is not None, then icc_profile must be empty. """ + def __init__(self, method=ENUMERATED_COLORSPACE, precedence=0, approximation=0, colorspace=None, icc_profile=None, length=0, offset=-1): @@ -203,8 +209,9 @@ class ColourSpecificationBox(Jp2kBox): msg += '\n Precedence: {0}'.format(self.precedence) if self.approximation is not 0: - dispvalue = _approximation_display[self.approximation] + dispvalue = _APPROX_DISPLAY[self.approximation] msg += '\n Approximation: {0}'.format(dispvalue) + if self.colorspace is not None: dispvalue = _COLORSPACE_MAP_DISPLAY[self.colorspace] msg += '\n Colorspace: {0}'.format(dispvalue) @@ -240,7 +247,7 @@ class ColourSpecificationBox(Jp2kBox): fptr.write(read_buffer) @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse JPEG 2000 color specification box. Parameters @@ -468,7 +475,7 @@ class ChannelDefinitionBox(Jp2kBox): self.association[j])) @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse component definition box. Parameters @@ -542,7 +549,7 @@ class ComponentMappingBox(Jp2kBox): return msg @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse component mapping box. Parameters @@ -607,7 +614,7 @@ class ContiguousCodestreamBox(Jp2kBox): return msg @staticmethod - def _parse(fptr, offset=0, length=0): + def parse(fptr, offset=0, length=0): """Parse a codestream box. Parameters @@ -685,7 +692,7 @@ class FileTypeBox(Jp2kBox): fptr.write(item.encode()) @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse JPEG 2000 file type box. Parameters @@ -812,7 +819,7 @@ class ImageHeaderBox(Jp2kBox): fptr.write(read_buffer) @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse JPEG 2000 image header box. Parameters @@ -883,7 +890,7 @@ class AssociationBox(Jp2kBox): return msg @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse association box. Parameters @@ -956,7 +963,7 @@ class JP2HeaderBox(Jp2kBox): fptr.seek(end_pos) @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse JPEG 2000 header box. Parameters @@ -1017,7 +1024,7 @@ class JPEG2000SignatureBox(Jp2kBox): fptr.write(struct.pack('>BBBB', *self.signature)) @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse JPEG 2000 signature box. Parameters @@ -1073,7 +1080,7 @@ class PaletteBox(Jp2kBox): return msg @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse palette box. Parameters @@ -1220,6 +1227,8 @@ _READER_REQUIREMENTS_DISPLAY = { + 'requirements in M.9.2.3', 73: 'YPbPr(1125/60) enumerated colourspace', 74: 'YPbPr(1250/50) enumerated colourspace'} + + class ReaderRequirementsBox(Jp2kBox): """Container for reader requirements box information. @@ -1276,7 +1285,7 @@ class ReaderRequirementsBox(Jp2kBox): return msg @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse reader requirements box. Parameters @@ -1380,7 +1389,7 @@ class ResolutionBox(Jp2kBox): return msg @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse Resolution box. Parameters @@ -1436,7 +1445,7 @@ class CaptureResolutionBox(Jp2kBox): return msg @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse Resolution box. Parameters @@ -1493,7 +1502,7 @@ class DisplayResolutionBox(Jp2kBox): return msg @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse Resolution box. Parameters @@ -1548,7 +1557,7 @@ class LabelBox(Jp2kBox): return msg @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse Label box. Parameters @@ -1633,7 +1642,7 @@ class XMLBox(Jp2kBox): fptr.write(read_buffer) @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse XML box. Parameters @@ -1697,7 +1706,7 @@ class UUIDListBox(Jp2kBox): return(msg) @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse UUIDList box. Parameters @@ -1760,7 +1769,7 @@ class UUIDInfoBox(Jp2kBox): return(msg) @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse UUIDInfo super box. Parameters @@ -1828,7 +1837,7 @@ class DataEntryURLBox(Jp2kBox): return msg @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse Data Entry URL box. Parameters @@ -1949,7 +1958,7 @@ class UUIDBox(Jp2kBox): return msg @staticmethod - def _parse(fptr, offset, length): + def parse(fptr, offset, length): """Parse UUID box. Parameters diff --git a/glymur/jp2k.py b/glymur/jp2k.py index e1d27cb..50801f4 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -98,7 +98,7 @@ class Jp2k(Jp2kBox): # Parse the file for JP2/JPX contents only if we are reading it. if mode == 'rb': - self._parse() + self.parse() def __str__(self): metadata = ['File: ' + os.path.basename(self.filename)] @@ -110,7 +110,7 @@ class Jp2k(Jp2kBox): metadata.append(str(codestream)) return '\n'.join(metadata) - def _parse(self): + def parse(self): """Parses the JPEG 2000 file. Raises @@ -425,7 +425,7 @@ class Jp2k(Jp2kBox): _opj2.destroy_codec(codec) _opj2.image_destroy(image) - self._parse() + self.parse() def wrap(self, filename, boxes=None): """Write the codestream back out to file, wrapped in new JP2 jacket. diff --git a/glymur/lib/config.py b/glymur/lib/config.py index da1c031..fc0e4cb 100644 --- a/glymur/lib/config.py +++ b/glymur/lib/config.py @@ -10,8 +10,10 @@ import warnings import sys if sys.hexversion <= 0x03000000: from ConfigParser import SafeConfigParser as ConfigParser + from ConfigParser import NoOptionError else: from configparser import ConfigParser + from configparser import NoOptionError def glymurrc_fname(): @@ -28,7 +30,6 @@ def glymurrc_fname(): if os.path.exists(fname): return fname - # Either GLYMURCONFIGDIR/glymurrc or $HOME/.glymur/glymurrc confdir = get_configdir() if confdir is not None: fname = os.path.join(confdir, 'glymurrc') @@ -39,10 +40,12 @@ def glymurrc_fname(): return None -def get_openjpeg_config(): - """ Try to find openjpeg library on the system path first. +def load_openjpeg(libopenjpeg_path): + """Load the openjpeg library, falling back on defaults if necessary. """ - libopenjpeg_path = find_library('openjpeg') + if libopenjpeg_path is None: + # Let ctypes try to find it. + libopenjpeg_path = find_library('openjpeg') # If we could not find it, then look in some likely locations. if libopenjpeg_path is None: @@ -74,19 +77,34 @@ def get_openjpeg_config(): return openjpeg_lib -def get_openjp2_config(): +def read_config_file(): """ We expect to not find openjp2 on the system path since the only version that we currently care about is still in the svn trunk at openjpeg.org. We must use a configuration file that the user must write. """ + lib = {'openjp2': None, 'openjpeg': None} filename = glymurrc_fname() if filename is not None: # Read the configuration file for the library location. parser = ConfigParser() parser.read(filename) - libopenjp2_path = parser.get('library', 'openjp2') - else: + try: + lib['openjp2'] = parser.get('library', 'openjp2') + except NoOptionError: + pass + try: + lib['openjpeg'] = parser.get('library', 'openjpeg') + except NoOptionError: + pass + + return lib + + +def load_openjp2(libopenjp2_path): + """Load the openjp2 library, falling back on defaults if necessary. + """ + if libopenjp2_path is None: # No help from the config file, try to find it ourselves. libopenjp2_path = find_library('openjp2') @@ -98,20 +116,22 @@ def get_openjp2_config(): openjp2_lib = ctypes.windll.LoadLibrary(libopenjp2_path) else: openjp2_lib = ctypes.CDLL(libopenjp2_path) - except OSError: + except (TypeError, OSError): msg = '"Library {0}" could not be loaded. Operating in degraded mode.' msg = msg.format(libopenjp2_path) warnings.warn(msg, UserWarning) openjp2_lib = None + return openjp2_lib def glymur_config(): """Try to ascertain locations of openjp2, openjpeg libraries. """ - openjp2_lib = get_openjp2_config() - openjpeg_lib = get_openjpeg_config() - return openjp2_lib, openjpeg_lib + libs = read_config_file() + libopenjp2_handle = load_openjp2(libs['openjp2']) + libopenjpeg_handle = load_openjpeg(libs['openjpeg']) + return libopenjp2_handle, libopenjpeg_handle def get_configdir(): diff --git a/glymur/lib/test/test_openjp2.py b/glymur/lib/test/test_openjp2.py index 61212ab..10b0084 100644 --- a/glymur/lib/test/test_openjp2.py +++ b/glymur/lib/test/test_openjp2.py @@ -1,3 +1,4 @@ +#pylint: disable-all import doctest import os import pkg_resources @@ -12,6 +13,7 @@ import numpy as np import glymur +@unittest.skipIf(os.name == "nt", "Temporary file issue on window.") @unittest.skipIf(glymur.lib._openjp2.OPENJP2 is None, "Missing openjp2 library.") class TestOpenJP2(unittest.TestCase): diff --git a/glymur/lib/test/test_openjpeg.py b/glymur/lib/test/test_openjpeg.py index 65dfeba..4f2d099 100644 --- a/glymur/lib/test/test_openjpeg.py +++ b/glymur/lib/test/test_openjpeg.py @@ -1,8 +1,10 @@ +#pylint: disable-all import ctypes import unittest import glymur + @unittest.skipIf(glymur.lib._openjpeg.OPENJPEG is None, "Missing openjpeg library.") class TestOpenJPEG(unittest.TestCase): @@ -35,4 +37,3 @@ class TestOpenJPEG(unittest.TestCase): self.assertEqual(dp.jpwl_max_tiles, 0) self.assertEqual(dp.cp_limit_decoding, 0) self.assertEqual(dp.flags, 0) - diff --git a/glymur/test/fixtures.py b/glymur/test/fixtures.py index ce52fae..3babc8a 100644 --- a/glymur/test/fixtures.py +++ b/glymur/test/fixtures.py @@ -3,19 +3,19 @@ import sys import numpy as np -def mse(A, B): + +def mse(amat, bmat): """Mean Square Error""" - diff = A.astype(np.double) - B.astype(np.double) - #e = np.sqrt(np.mean(diff**2)) - e = np.mean(diff**2) - return e + diff = amat.astype(np.double) - bmat.astype(np.double) + err = np.mean(diff**2) + return err -def peak_tolerance(A, B): +def peak_tolerance(amat, bmat): """Peak Tolerance""" - diff = np.abs(A.astype(np.double) - B.astype(np.double)) - p = diff.max() - return p + diff = np.abs(amat.astype(np.double) - bmat.astype(np.double)) + ptol = diff.max() + return ptol def read_pgx(pgx_file): @@ -28,42 +28,42 @@ def read_pgx(pgx_file): PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d" """ header = '' - with open(pgx_file, 'rb') as fp: + with open(pgx_file, 'rb') as fptr: while True: - x = fp.read(1) - if x[0] == 10 or x == '\n': - pos = fp.tell() + char = fptr.read(1) + if char[0] == 10 or char == '\n': + pos = fptr.tell() break else: if sys.hexversion < 0x03000000: - header += x + header += char else: - header += chr(x[0]) + header += chr(char[0]) header = header.rstrip() - n = re.split('\s', header) + tokens = re.split('\s', header) - if (n[1][0] == 'M') and (sys.byteorder == 'little'): + if (tokens[1][0] == 'M') and (sys.byteorder == 'little'): swapbytes = True - elif (n[1][0] == 'L') and (sys.byteorder == 'big'): + elif (tokens[1][0] == 'L') and (sys.byteorder == 'big'): swapbytes = True else: swapbytes = False - if (len(n) == 6): - bitdepth = int(n[3]) + if (len(tokens) == 6): + bitdepth = int(tokens[3]) signed = bitdepth < 0 if signed: bitdepth = -1 * bitdepth - nrows = int(n[5]) - ncols = int(n[4]) + nrows = int(tokens[5]) + ncols = int(tokens[4]) else: - bitdepth = int(n[2]) + bitdepth = int(tokens[2]) signed = bitdepth < 0 if signed: bitdepth = -1 * bitdepth - nrows = int(n[4]) - ncols = int(n[3]) + nrows = int(tokens[4]) + ncols = int(tokens[3]) if signed: if bitdepth <= 8: @@ -84,10 +84,8 @@ def read_pgx(pgx_file): # Reopen the file in binary mode and seek to the start of the binary # data - with open(pgx_file, 'rb') as fp: - fp.seek(pos) - data = np.fromfile(file=fp, dtype=dtype).reshape(shape) + with open(pgx_file, 'rb') as fptr: + fptr.seek(pos) + data = np.fromfile(file=fptr, dtype=dtype).reshape(shape) return(data.byteswap(swapbytes)) - - diff --git a/glymur/test/test_callbacks.py b/glymur/test/test_callbacks.py index 5b2dc6b..bb6ea07 100644 --- a/glymur/test/test_callbacks.py +++ b/glymur/test/test_callbacks.py @@ -1,3 +1,4 @@ +#pylint: disable-all import os import pkg_resources import re @@ -29,6 +30,7 @@ class TestCallbacks(unittest.TestCase): # Restore stdout. sys.stdout = self.stdout + @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_info_callback_on_write(self): # Verify the messages printed when writing an image in verbose mode. j = glymur.Jp2k(self.jp2file) @@ -96,9 +98,12 @@ class TestCallbacks15(unittest.TestCase): actual = sys.stdout.getvalue().strip() regex = re.compile(r"""\[INFO\]\stile\s1\sof\s1\s+ - \[INFO\]\s-\stiers-1\stook\s[0-9]+\.[0-9]+\ss\s+ - \[INFO\]\s-\sdwt\stook\s[0-9]+\.[0-9]+\ss\s+ - \[INFO\]\s-\stile\sdecoded\sin\s[0-9]+\.[0-9]+\ss""", + \[INFO\]\s-\stiers-1\stook\s + [0-9]+\.[0-9]+\ss\s+ + \[INFO\]\s-\sdwt\stook\s + (-){0,1}[0-9]+\.[0-9]+\ss\s+ + \[INFO\]\s-\stile\sdecoded\sin\s + [0-9]+\.[0-9]+\ss""", re.VERBOSE) if sys.hexversion <= 0x03020000: self.assertRegexpMatches(actual, regex) @@ -106,6 +111,5 @@ class TestCallbacks15(unittest.TestCase): self.assertRegex(actual, regex) - if __name__ == "__main__": unittest.main() diff --git a/glymur/test/test_codestream.py b/glymur/test/test_codestream.py index b19a042..d2e3b11 100644 --- a/glymur/test/test_codestream.py +++ b/glymur/test/test_codestream.py @@ -1,3 +1,4 @@ +#pylint: disable-all import os import struct import sys @@ -29,6 +30,7 @@ class TestCodestream(unittest.TestCase): def tearDown(self): pass + @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_reserved_marker_segment(self): # Some marker segments were reserved in FCD15444-1. Since that # standard is old, some of them may have come into use. @@ -58,6 +60,7 @@ class TestCodestream(unittest.TestCase): self.assertEqual(c.segment[2].length, 3) self.assertEqual(c.segment[2]._data, b'\x00') + @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") @unittest.skipIf(sys.hexversion < 0x03020000, "Uses features introduced in 3.2.") def test_unknown_marker_segment(self): diff --git a/glymur/test/test_config.py b/glymur/test/test_config.py index 206da05..bcc2327 100644 --- a/glymur/test/test_config.py +++ b/glymur/test/test_config.py @@ -1,6 +1,7 @@ -"""These tests are for edge cases where OPENJPEG does not exist, but +"""These tests are for edge cases where OPENJPEG does not exist, but OPENJP2 may be present in some form or other. """ +#pylint: disable-all import imp import os diff --git a/glymur/test/test_icc.py b/glymur/test/test_icc.py index b989bbe..30b4dc0 100644 --- a/glymur/test/test_icc.py +++ b/glymur/test/test_icc.py @@ -1,3 +1,4 @@ +#pylint: disable-all import datetime import os import struct diff --git a/glymur/test/test_jp2box.py b/glymur/test/test_jp2box.py index 3a38002..72bb476 100644 --- a/glymur/test/test_jp2box.py +++ b/glymur/test/test_jp2box.py @@ -1,3 +1,4 @@ +#pylint: disable-all import doctest import os import tempfile @@ -14,10 +15,14 @@ from glymur.jp2box import * # Doc tests should be run as well. def load_tests(loader, tests, ignore): + if os.name == "nt": + # Can't do it on windows, temporary file issue. + return tests tests.addTests(doctest.DocTestSuite('glymur.jp2box')) return tests +@unittest.skipIf(os.name == "nt", "Temporary file issue on window.") @unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None, "Missing openjp2 library.") class TestChannelDefinition(unittest.TestCase): @@ -232,6 +237,7 @@ class TestChannelDefinition(unittest.TestCase): association=[1, 2, 3]) +@unittest.skipIf(os.name == "nt", "Temporary file issue on window.") class TestXML(unittest.TestCase): def setUp(self): @@ -291,7 +297,7 @@ class TestXML(unittest.TestCase): with self.assertRaises((IOError, OSError)) as ce: xmlb = glymur.jp2box.XMLBox(filename=self.xmlfile, xml=xml_object) - @unittest.skipIf(os.name == "nt", + @unittest.skipIf(os.name == "nt", "Problems using NamedTemporaryFile on windows.") def test_basic_xml(self): # Should be able to write an XMLBox. @@ -313,7 +319,7 @@ class TestXML(unittest.TestCase): self.assertEqual(ET.tostring(jp2.box[3].xml), b'0') - @unittest.skipIf(os.name == "nt", + @unittest.skipIf(os.name == "nt", "Problems using NamedTemporaryFile on windows.") def test_xml_from_file(self): j2k = Jp2k(self.j2kfile) @@ -359,7 +365,7 @@ class TestColourSpecificationBox(unittest.TestCase): def tearDown(self): pass - @unittest.skipIf(os.name == "nt", + @unittest.skipIf(os.name == "nt", "Problems using NamedTemporaryFile on windows.") def test_color_specification_box_with_out_enumerated_colorspace(self): j2k = Jp2k(self.j2kfile) @@ -370,6 +376,7 @@ class TestColourSpecificationBox(unittest.TestCase): with self.assertRaises(NotImplementedError): j2k.wrap(tfile.name, boxes=boxes) + @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_missing_colr_box(self): j2k = Jp2k(self.j2kfile) boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] @@ -501,12 +508,14 @@ class TestJp2Boxes(unittest.TestCase): self.assertEqual(jp2.box[2].box[1].colorspace, glymur.core.SRGB) self.assertIsNone(jp2.box[2].box[1].icc_profile) + @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_wrap(self): j2k = Jp2k(self.j2kfile) with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: j2k.wrap(tfile.name) self.verify_wrapped_raw(tfile.name) + @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_wrap_jp2(self): j2k = Jp2k(self.j2kfile) with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: @@ -514,6 +523,7 @@ class TestJp2Boxes(unittest.TestCase): boxes = [box.box_id for box in jp2.box] self.assertEqual(boxes, ['jP ', 'ftyp', 'jp2h', 'jp2c']) + @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_default_layout_but_with_specified_boxes(self): j2k = Jp2k(self.j2kfile) boxes = [JPEG2000SignatureBox(), @@ -532,6 +542,7 @@ class TestJp2Boxes(unittest.TestCase): j2k.wrap(tfile.name, boxes=boxes) self.verify_wrapped_raw(tfile.name) + @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_image_header_box_not_first_in_jp2_header(self): # The specification says that ihdr must be the first box in jp2h. j2k = Jp2k(self.j2kfile) @@ -551,6 +562,7 @@ class TestJp2Boxes(unittest.TestCase): with self.assertRaises(IOError): j2k.wrap(tfile.name, boxes=boxes) + @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_first_2_boxes_not_jP_and_ftyp(self): j2k = Jp2k(self.j2kfile) c = j2k.get_codestream() @@ -571,6 +583,7 @@ class TestJp2Boxes(unittest.TestCase): with self.assertRaises(IOError): j2k.wrap(tfile.name, boxes=boxes) + @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_jp2h_not_preceeding_jp2c(self): j2k = Jp2k(self.j2kfile) c = j2k.get_codestream() @@ -591,6 +604,7 @@ class TestJp2Boxes(unittest.TestCase): with self.assertRaises(IOError): j2k.wrap(tfile.name, boxes=boxes) + @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_missing_codestream(self): j2k = Jp2k(self.j2kfile) c = j2k.get_codestream() diff --git a/glymur/test/test_jp2k.py b/glymur/test/test_jp2k.py index 5f04283..3c1197d 100644 --- a/glymur/test/test_jp2k.py +++ b/glymur/test/test_jp2k.py @@ -1,7 +1,5 @@ -import contextlib -import ctypes +# pylint: disable-all import doctest -import imp import os import re import shutil @@ -33,14 +31,18 @@ except: # Doc tests should be run as well. def load_tests(loader, tests, ignore): + if os.name == "nt": + # Can't do it on windows, temporary file issue. + return tests if glymur.lib.openjp2.OPENJP2 is not None: tests.addTests(doctest.DocTestSuite('glymur.jp2k')) return tests +@unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") @unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None, "Missing openjp2 library.") -class TestJp2k(unittest.TestCase): +class TestJp2kBadXmlFile(unittest.TestCase): @classmethod def setUpClass(cls): @@ -88,14 +90,6 @@ class TestJp2k(unittest.TestCase): with self.assertWarns(UserWarning) as cw: jp2k = Jp2k(self._bad_xml_file) - def test_rlevel_max(self): - # Verify that rlevel=-1 gets us the lowest resolution image - j = Jp2k(self.j2kfile) - thumbnail1 = j.read(rlevel=-1) - thumbnail2 = j.read(rlevel=5) - np.testing.assert_array_equal(thumbnail1, thumbnail2) - self.assertEqual(thumbnail1.shape, (25, 15, 3)) - def test_invalid_xml_box(self): # Should be able to recover from xml box with bad xml. with warnings.catch_warnings(): @@ -107,6 +101,26 @@ class TestJp2k(unittest.TestCase): self.assertEqual(jp2k.box[3].length, 28) self.assertIsNone(jp2k.box[3].xml) + +@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None, + "Missing openjp2 library.") +class TestJp2k(unittest.TestCase): + + def setUp(self): + self.jp2file = glymur.data.nemo() + self.j2kfile = glymur.data.goodstuff() + + def tearDown(self): + pass + + def test_rlevel_max(self): + # Verify that rlevel=-1 gets us the lowest resolution image + j = Jp2k(self.j2kfile) + thumbnail1 = j.read(rlevel=-1) + thumbnail2 = j.read(rlevel=5) + np.testing.assert_array_equal(thumbnail1, thumbnail2) + self.assertEqual(thumbnail1.shape, (25, 15, 3)) + def test_bad_area_parameter(self): # Verify that we error out appropriately if given a bad area parameter. j = Jp2k(self.jp2file) @@ -143,6 +157,7 @@ class TestJp2k(unittest.TestCase): filename = 'this file does not actually exist on the file system.' jp2k = Jp2k(filename) + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_write_srgb_without_mct(self): j2k = Jp2k(self.j2kfile) expdata = j2k.read() @@ -155,6 +170,7 @@ class TestJp2k(unittest.TestCase): c = ofile.get_codestream() self.assertEqual(c.segment[2].spcod[3], 0) # no mct + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_write_grayscale_with_mct(self): # MCT usage makes no sense for grayscale images. j2k = Jp2k(self.j2kfile) @@ -164,6 +180,7 @@ class TestJp2k(unittest.TestCase): with self.assertRaises(IOError): ofile.write(expdata[:, :, 0], mct=True) + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_write_cprl(self): # Issue 17 j = Jp2k(self.jp2file) @@ -244,6 +261,7 @@ class TestJp2k(unittest.TestCase): jp2k = Jp2k(filename) self.assertEqual(len(jp2k.box), 0) + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_64bit_XL_field(self): # Verify that boxes with the XL field are properly read. # Don't have such a file on hand, so we create one. Copy our example @@ -276,6 +294,7 @@ class TestJp2k(unittest.TestCase): self.assertEqual(jp2k.box[5].offset, 3127) self.assertEqual(jp2k.box[5].length, 1133427 + 8) + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_L_is_zero(self): # Verify that boxes with the L field as zero are correctly read. # This should only happen in the last box of a JPEG 2000 file. @@ -331,6 +350,7 @@ class TestJp2k(unittest.TestCase): j = Jp2k(filename) self.assertEqual(j.box, []) + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_code_block_height_different_than_width(self): # Verify that we can set a code block size where height does not equal # width. @@ -346,6 +366,7 @@ class TestJp2k(unittest.TestCase): # Code block size is reported as XY in the codestream. self.assertEqual(tuple(c.segment[2].spcod[5:7]), (3, 2)) + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_negative_too_many_dimensions(self): # OpenJP2 only allows 2D or 3D images. with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: @@ -354,6 +375,7 @@ class TestJp2k(unittest.TestCase): data = np.zeros((128, 128, 2, 2), dtype=np.uint8) j.write(data) + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_unrecognized_jp2_colorspace(self): # We only allow RGB and GRAYSCALE. with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: @@ -362,6 +384,7 @@ class TestJp2k(unittest.TestCase): data = np.zeros((128, 128, 3), dtype=np.uint8) j.write(data, colorspace='cmyk') + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_2D_rgb(self): # RGB must have at least 3 components. with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: @@ -370,6 +393,7 @@ class TestJp2k(unittest.TestCase): data = np.zeros((128, 128, 2), dtype=np.uint8) j.write(data, colorspace='rgb') + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_colorspace_with_j2k(self): # Specifying a colorspace with J2K does not make sense. with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: @@ -378,6 +402,7 @@ class TestJp2k(unittest.TestCase): data = np.zeros((128, 128, 3), dtype=np.uint8) j.write(data, colorspace='rgb') + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_specify_rgb(self): with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: j = Jp2k(tfile.name, 'wb') @@ -385,6 +410,7 @@ class TestJp2k(unittest.TestCase): j.write(data, colorspace='rgb') self.assertEqual(j.box[2].box[1].colorspace, glymur.core.SRGB) + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_specify_gray(self): with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: j = Jp2k(tfile.name, 'wb') @@ -393,6 +419,7 @@ class TestJp2k(unittest.TestCase): self.assertEqual(j.box[2].box[1].colorspace, glymur.core.GREYSCALE) + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_specify_grey(self): with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: j = Jp2k(tfile.name, 'wb') @@ -401,6 +428,7 @@ class TestJp2k(unittest.TestCase): self.assertEqual(j.box[2].box[1].colorspace, glymur.core.GREYSCALE) + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_grey_with_extra_component(self): with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: j = Jp2k(tfile.name, 'wb') @@ -412,6 +440,7 @@ class TestJp2k(unittest.TestCase): self.assertEqual(j.box[2].box[1].colorspace, glymur.core.GREYSCALE) + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_grey_with_two_extra_components(self): with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: j = Jp2k(tfile.name, 'wb') @@ -423,6 +452,7 @@ class TestJp2k(unittest.TestCase): self.assertEqual(j.box[2].box[1].colorspace, glymur.core.GREYSCALE) + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_rgb_with_extra_component(self): with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: j = Jp2k(tfile.name, 'wb') @@ -441,6 +471,7 @@ class TestJp2k(unittest.TestCase): data = np.zeros((128, 128, 3), dtype=np.uint8) j.write(data, colorspace='ycc') + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_uinf_ulst_url_boxes(self): # Verify that we can read UINF, ULST, and URL boxes. I don't have # easy access to such a file, and there's no such file in the @@ -497,6 +528,7 @@ class TestJp2k(unittest.TestCase): self.assertEqual(jp2k.box[3].box[1].flag, (0, 0, 0)) self.assertEqual(jp2k.box[3].box[1].url, 'abcd') + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_xml_box_with_trailing_nulls(self): # ElementTree does not like trailing null chars after valid XML # text. @@ -526,6 +558,7 @@ class TestJp2k(unittest.TestCase): self.assertEqual(jp2k.box[3].offset, 77) self.assertEqual(jp2k.box[3].length, 36) + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_asoc_label_box(self): # Construct a fake file with an asoc and a label box, as # OpenJPEG doesn't have such a file. @@ -572,6 +605,7 @@ class TestJp2k(unittest.TestCase): self.assertEqual(jasoc.box[3].box[0].label, 'label') self.assertEqual(jasoc.box[3].box[1].box_id, 'xml ') + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_openjpeg_library_message(self): # Verify the error message produced by the openjpeg library. # This will confirm that the error callback mechanism is working. @@ -599,10 +633,10 @@ class TestJp2k(unittest.TestCase): Invalid\svalues\sfor\scomp\s=\s0\s+ :\sdx=1\sdy=0''', re.VERBOSE) if sys.hexversion < 0x03020000: - with self.assertRaisesRegexp((IOError, OSError), regexp) as ce: + with self.assertRaisesRegexp((IOError, OSError), regexp): d = j.read(rlevel=1) else: - with self.assertRaisesRegex((IOError, OSError), regexp) as ce: + with self.assertRaisesRegex((IOError, OSError), regexp): d = j.read(rlevel=1) def test_xmp_attribute(self): @@ -616,6 +650,7 @@ class TestJp2k(unittest.TestCase): attr_value = elt.attrib['{0}CreatorTool'.format(ns1)] self.assertEqual(attr_value, 'glymur') + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_unrecognized_exif_tag(self): # An unrecognized exif tag should be handled gracefully. with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: @@ -671,42 +706,48 @@ class TestJp2k15(unittest.TestCase): pass def test_bands(self): - # Reading individual bands is an advanced maneuver. + """Reading individual bands is an advanced maneuver. + """ jp2k = Jp2k(self.j2kfile) - with self.assertRaises(NotImplementedError) as ce: - jpdata = jp2k.read_bands() + with self.assertRaises(NotImplementedError): + jp2k.read_bands() def test_area(self): - # Area option not allowed for 1.5.1. + """Area option not allowed for 1.5.1. + """ j2k = Jp2k(self.j2kfile) - with self.assertRaises(TypeError) as ce: - d = j2k.read(area=(0, 0, 100, 100)) + with self.assertRaises(TypeError): + j2k.read(area=(0, 0, 100, 100)) def test_tile(self): - # tile option not allowed for 1.5.1. + """tile option not allowed for 1.5.1. + """ j2k = Jp2k(self.j2kfile) - with self.assertRaises(TypeError) as ce: - d = j2k.read(tile=0) + with self.assertRaises(TypeError): + j2k.read(tile=0) def test_layer(self): - # layer option not allowed for 1.5.1. + """layer option not allowed for 1.5.1. + """ j2k = Jp2k(self.j2kfile) - with self.assertRaises(TypeError) as ce: - d = j2k.read(layer=1) + with self.assertRaises(TypeError): + j2k.read(layer=1) def test_basic_jp2(self): - # This test is only useful when openjp2 is not available - # and OPJ_DATA_ROOT is not set. We need at least one - # working JP2 test. + """This test is only useful when openjp2 is not available + and OPJ_DATA_ROOT is not set. We need at least one + working JP2 test. + """ j2k = Jp2k(self.jp2file) - d = j2k.read(rlevel=1) + j2k.read(rlevel=1) def test_basic_j2k(self): - # This test is only useful when openjp2 is not available - # and OPJ_DATA_ROOT is not set. We need at least one - # working J2K test. + """This test is only useful when openjp2 is not available + and OPJ_DATA_ROOT is not set. We need at least one + working J2K test. + """ j2k = Jp2k(self.j2kfile) - d = j2k.read() + j2k.read() if __name__ == "__main__": diff --git a/glymur/test/test_opj_suite.py b/glymur/test/test_opj_suite.py index 4ba12c6..41d4f8b 100644 --- a/glymur/test/test_opj_suite.py +++ b/glymur/test/test_opj_suite.py @@ -2,6 +2,7 @@ The tests defined here roughly correspond to what is in the OpenJPEG test suite. """ +#pylint: disable-all from contextlib import contextmanager import os @@ -4215,7 +4216,8 @@ class TestSuiteDump(unittest.TestCase): # Jp2 Header # Colour specification - self.assertEqual(jp2.box[3].box[1].method, glymur.core.RESTRICTED_ICC_PROFILE) # enumerated + self.assertEqual(jp2.box[3].box[1].method, + glymur.core.RESTRICTED_ICC_PROFILE) # enumerated self.assertEqual(jp2.box[3].box[1].precedence, 0) self.assertEqual(jp2.box[3].box[1].approximation, 1) # JPX exact self.assertEqual(jp2.box[3].box[1].icc_profile['Size'], 546) @@ -4312,7 +4314,8 @@ class TestSuiteDump(unittest.TestCase): # Jp2 Header # Colour specification - self.assertEqual(jp2.box[3].box[1].method, glymur.core.RESTRICTED_ICC_PROFILE) + self.assertEqual(jp2.box[3].box[1].method, + glymur.core.RESTRICTED_ICC_PROFILE) self.assertEqual(jp2.box[3].box[1].precedence, 0) self.assertEqual(jp2.box[3].box[1].approximation, 1) # JPX exact self.assertEqual(jp2.box[3].box[1].icc_profile['Size'], 13332) @@ -4362,7 +4365,8 @@ class TestSuiteDump(unittest.TestCase): # Jp2 Header # Colour specification - self.assertEqual(jp2.box[2].box[1].method, glymur.core.RESTRICTED_ICC_PROFILE) # enumerated + self.assertEqual(jp2.box[2].box[1].method, + glymur.core.RESTRICTED_ICC_PROFILE) # enumerated self.assertEqual(jp2.box[2].box[1].precedence, 0) self.assertEqual(jp2.box[2].box[1].approximation, 1) # JPX exact self.assertEqual(jp2.box[2].box[1].icc_profile['Size'], 414) @@ -7079,7 +7083,8 @@ class TestSuiteDump(unittest.TestCase): # Jp2 Header # Colour specification - self.assertEqual(jp2.box[2].box[1].method, glymur.core.RESTRICTED_ICC_PROFILE) # res icc + self.assertEqual(jp2.box[2].box[1].method, + glymur.core.RESTRICTED_ICC_PROFILE) self.assertEqual(jp2.box[2].box[1].precedence, 0) self.assertEqual(jp2.box[2].box[1].approximation, 0) # JP2 self.assertIsNone(jp2.box[2].box[1].icc_profile) diff --git a/glymur/test/test_opj_suite_neg.py b/glymur/test/test_opj_suite_neg.py index 8220f24..8a89d09 100644 --- a/glymur/test/test_opj_suite_neg.py +++ b/glymur/test/test_opj_suite_neg.py @@ -2,6 +2,7 @@ The tests here do not correspond directly to the OpenJPEG test suite, but seem like logical negative tests to add. """ +#pylint: disable-all import os import sys import tempfile @@ -71,6 +72,7 @@ class TestSuiteNegative(unittest.TestCase): def tearDown(self): pass + @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_negative_psnr_with_cratios(self): # Using psnr with cratios options is not allowed. # Not an OpenJPEG test, but close. @@ -126,6 +128,7 @@ class TestSuiteNegative(unittest.TestCase): # the end of SOT. self.assertEqual(c.segment[-1].marker_id, 'SOD') + @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_code_block_dimensions(self): # opj_compress doesn't allow the dimensions of a codeblock # to be too small or too big, so neither will we. @@ -154,6 +157,7 @@ class TestSuiteNegative(unittest.TestCase): with self.assertWarns(UserWarning) as cw: j = Jp2k(infile) + @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_precinct_size_not_multiple_of_two(self): # Seems like precinct sizes should be powers of two. ifile = Jp2k(self.j2kfile) @@ -163,6 +167,7 @@ class TestSuiteNegative(unittest.TestCase): with self.assertRaises(IOError) as ce: ofile.write(data, psizes=[(13, 13)]) + @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_codeblock_size_not_multiple_of_two(self): # Seems like code block sizes should be powers of two. ifile = Jp2k(self.j2kfile) @@ -172,6 +177,7 @@ class TestSuiteNegative(unittest.TestCase): with self.assertRaises(IOError) as ce: ofile.write(data, cbsize=(13, 12)) + @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_codeblock_size_with_precinct_size(self): # Seems like code block sizes should never exceed half that of # precinct size. diff --git a/glymur/test/test_opj_suite_write.py b/glymur/test/test_opj_suite_write.py index ccdc651..4023239 100644 --- a/glymur/test/test_opj_suite_write.py +++ b/glymur/test/test_opj_suite_write.py @@ -2,6 +2,7 @@ The tests defined here roughly correspond to what is in the OpenJPEG test suite. """ +#pylint: disable-all import os import platform import sys @@ -57,6 +58,7 @@ def read_image(infile): return data +@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) diff --git a/glymur/test/test_printing.py b/glymur/test/test_printing.py index 4ced196..3b920cc 100644 --- a/glymur/test/test_printing.py +++ b/glymur/test/test_printing.py @@ -1,3 +1,4 @@ +#pylint: disable-all import os import pkg_resources import struct @@ -21,6 +22,7 @@ except: raise +@unittest.skipIf(os.name == "nt", "Temporary file issue on window.") @unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None, "Missing openjp2 library.") class TestPrintingNeedsLib(unittest.TestCase): @@ -782,8 +784,7 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - @unittest.skipIf(os.name == "nt", - "Problems using NamedTemporaryFile on windows.") + @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_less_common_boxes(self): with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: with open(self.jp2file, 'rb') as ifile: diff --git a/release.txt b/release.txt index c553960..4f2b068 100644 --- a/release.txt +++ b/release.txt @@ -1,22 +1,30 @@ -| OS | Python 2.7 | Python 3.3 | Notes | -+------------+------------+------------+----------------------------------+ -| Windows | X | | Python(xy) with OpenJPEG 1.5.1. | -| | | | At least 25 tests should pass | -+------------+------------+------------+----------------------------------+ -| Mac | X | | MacPorts with both OpenJPEG 1.5.1| -| | | | and OpenJPEG svn. Maximum number| -| | | | of tests should pass. | -+------------+------------+------------+----------------------------------+ -| Mac | | X | MacPorts with both OpenJPEG 1.5.1| -| | | | and OpenJPEG svn. Maximum number| -| | | | of tests should pass. | -+------------+------------+------------+----------------------------------+ -| Raspberry | X | | Ships with only 1.3. Should | -| | | | error out gracefully. | -+------------+------------+------------+----------------------------------+ -| Fedora 17 | X | | Ships with 1.4. Should error out| -| | | | gracefully. | -+------------+------------+------------+----------------------------------+ -| Fedora 18 | | X | Ships with 1.5.1. Some tests | -| | | | should pass. | -+------------+------------+------------+----------------------------------+ +| OS | Python 2.7 | Python 3.3 | Notes | ++------------+------------+------------+--------------------------------------+ +| Windows | X | | Python(xy) with OpenJPEG 1.5.1. At | +| | | | least 155 of 444 tests should pass. | ++------------+------------+------------+--------------------------------------+ +| Windows | X | | Python(xy) with OpenJPEG 1.5.1 and | +| | | | OpenJPEG svn. At least 282 of 444 | +| | | | tests should pass. | ++------------+------------+------------+--------------------------------------+ +| Mac | X | | MacPorts with both OpenJPEG 1.5.1 | +| | | | and OpenJPEG svn. 370 of 450 tests | +| | | | should pass. | ++------------+------------+------------+--------------------------------------+ +| Mac | | X | MacPorts with both OpenJPEG 1.5.1 | +| | | | and OpenJPEG svn. 390 of 450 | +| | | | tests should pass. | ++------------+------------+------------+--------------------------------------+ +| Fedora 19 | | X | Ships with 1.5.1. 390 of 450 tests | +| | | | should pass. | ++------------+------------+------------+--------------------------------------+ +| Fedora 18 | | X | Ships with 1.5.1. 167 of 445 tests | +| | | | should pass. | ++------------+------------+------------+--------------------------------------+ +| Fedora 17 | X | | Ships with 1.4. Should error out | +| | | | gracefully. | ++------------+------------+------------+--------------------------------------+ + +Pylint on entire package should be at least 0.95. +pep8 should be pass cleanly. +Coverage should exceed 95%. diff --git a/setup.py b/setup.py index 0e213a3..1590fa9 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages import sys kwargs = {'name': 'Glymur', - 'version': '0.1.10', + 'version': '0.2.2', 'description': 'Tools for accessing JPEG2000 files', 'long_description': open('README.md').read(), 'author': 'John Evans', @@ -26,9 +26,10 @@ clssfrs = ["Programming Language :: Python", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: Implementation :: CPython", "License :: OSI Approved :: MIT License", - "Development Status :: 3 - Alpha", + "Development Status :: 5 - Production/Stable", "Operating System :: MacOS", "Operating System :: POSIX :: Linux", + "Operating System :: Microsoft :: Windows :: Windows XP", "Intended Audience :: Science/Research", "Intended Audience :: Information Technology", "Topic :: Software Development :: Libraries :: Python Modules"]