diff --git a/CHANGES.txt b/CHANGES.txt index 7283bfb..1874042 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,6 @@ -Aug 11, 2013 - v0.3.1 Exposed mantissa, exponent, and guard_bits fields in QCC - and QCD segments. +Aug 13, 2013 - v0.3.1 Exposed mantissa, exponent, and guard_bits fields in QCC + and QCD segments. Exposed layers and code_block_size in COD segment. + Exposed precinct_size in COC segment. Jul 31, 2013 - v0.3.0 Added support for official 2.0.0. diff --git a/glymur/__init__.py b/glymur/__init__.py index fb1c504..cc80a72 100644 --- a/glymur/__init__.py +++ b/glymur/__init__.py @@ -8,6 +8,8 @@ from .jp2dump import jp2dump from . import data +# unittest2 only in python-2.6 (pylint/python2.7 issue) +# pylint: disable=F0401 def runtests(): """Discover and run all tests for the glymur package. """ diff --git a/glymur/codestream.py b/glymur/codestream.py index c60bc1b..7a32190 100644 --- a/glymur/codestream.py +++ b/glymur/codestream.py @@ -3,7 +3,19 @@ The module contains classes used to store information parsed from JPEG 2000 codestreams. """ -# pylint: disable=C0302,R0902,R0903,R0913 + +# The number of lines in the module is long and that's ok. It would not help +# matters to move anything out to another file. +# pylint: disable=C0302 + +# "Too many instance attributes", "Too many arguments" +# Some segments just have a lot of information. +# It doesn't make sense to subclass just for that. +# pylint: disable=R0902,R0913 + +# "Too few public methods" Some segments don't define any new methods from +# the base Segment class. +# pylint: disable=R0903 import math import struct @@ -1276,6 +1288,10 @@ class QCCsegment(Segment): Quantization style for this component. spqcc : iterable bytes Quantization value for each sub-band. + mantissa, exponent : iterable + Defines quantization factors. + guard_bits : int + Number of guard bits. References ---------- @@ -1323,6 +1339,10 @@ class QCDsegment(Segment): Quantization style for all components. spqcd : iterable bytes Quantization step size values (uninterpreted). + mantissa, exponent : iterable + Defines quantization factors. + guard_bits : int + Number of guard bits. References ---------- diff --git a/glymur/jp2k.py b/glymur/jp2k.py index 2994742..ea8ef5e 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -4,10 +4,14 @@ License: MIT """ import sys + +# Exitstack not found in contextlib in 2.7 +# pylint: disable=E0611 if sys.hexversion >= 0x03030000: from contextlib import ExitStack else: from contextlib2 import ExitStack + import ctypes import math import os @@ -22,63 +26,13 @@ from .core import GREYSCALE from .core import PROGRESSION_ORDER from .core import ENUMERATED_COLORSPACE, RESTRICTED_ICC_PROFILE from .jp2box import Jp2kBox -from .jp2box import JPEG2000SignatureBox -from .jp2box import FileTypeBox -from .jp2box import JP2HeaderBox -from .jp2box import ContiguousCodestreamBox +from .jp2box import JPEG2000SignatureBox, FileTypeBox, JP2HeaderBox +from .jp2box import ColourSpecificationBox, ContiguousCodestreamBox from .jp2box import ImageHeaderBox -from .jp2box import ColourSpecificationBox from .lib import openjpeg as opj from .lib import openjp2 as opj2 from .lib import c as libc -# Need to known if openjp2 library is the officially release v2.0.0 or not. -_OPENJP2_IS_OFFICIAL_V2 = False -if opj2.OPENJP2 is not None: - if opj2.version() == '2.0.0': - if not hasattr(opj2.OPENJP2, - 'opj_stream_create_default_file_stream_v3'): - _OPENJP2_IS_OFFICIAL_V2 = True - -_COLORSPACE_MAP = {'rgb': opj2.CLRSPC_SRGB, - 'gray': opj2.CLRSPC_GRAY, - 'grey': opj2.CLRSPC_GRAY, - 'ycc': opj2.CLRSPC_YCC} - -# Setup the default callback handlers. See the callback functions subsection -# in the ctypes section of the Python documentation for a solid explanation of -# what's going on here. -_CMPFUNC = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p) - - -def _default_error_handler(msg, _): - """Default error handler callback for openjpeg library.""" - msg = "OpenJPEG library error: {0}".format(msg.decode('utf-8').rstrip()) - opj2.set_error_message(msg) - - -def _default_info_handler(msg, _): - """Default info handler callback for openjpeg library.""" - print("[INFO] {0}".format(msg.decode('utf-8').rstrip())) - - -def _default_warning_handler(library_msg, _): - """Default warning handler callback for openjpeg library.""" - library_msg = library_msg.decode('utf-8').rstrip() - msg = "OpenJPEG library warning: {0}".format(library_msg) - warnings.warn(msg) - -_ERROR_CALLBACK = _CMPFUNC(_default_error_handler) -_INFO_CALLBACK = _CMPFUNC(_default_info_handler) -_WARNING_CALLBACK = _CMPFUNC(_default_warning_handler) - - -class LibraryNotFoundError(IOError): - """Raised if functionality is requested without the necessary library. - """ - def __init__(self, msg): - IOError.__init__(self, msg) - class Jp2k(Jp2kBox): """JPEG 2000 file. @@ -1313,3 +1267,50 @@ def _validate_compression_params(img_array, cparams): msg = "Only uint8 and uint16 images are currently supported." raise RuntimeError(msg) +# Need to known if openjp2 library is the officially release v2.0.0 or not. +_OPENJP2_IS_OFFICIAL_V2 = False +if opj2.OPENJP2 is not None: + if opj2.version() == '2.0.0': + if not hasattr(opj2.OPENJP2, + 'opj_stream_create_default_file_stream_v3'): + _OPENJP2_IS_OFFICIAL_V2 = True + +_COLORSPACE_MAP = {'rgb': opj2.CLRSPC_SRGB, + 'gray': opj2.CLRSPC_GRAY, + 'grey': opj2.CLRSPC_GRAY, + 'ycc': opj2.CLRSPC_YCC} + +# Setup the default callback handlers. See the callback functions subsection +# in the ctypes section of the Python documentation for a solid explanation of +# what's going on here. +_CMPFUNC = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p) + + +def _default_error_handler(msg, _): + """Default error handler callback for openjpeg library.""" + msg = "OpenJPEG library error: {0}".format(msg.decode('utf-8').rstrip()) + opj2.set_error_message(msg) + + +def _default_info_handler(msg, _): + """Default info handler callback for openjpeg library.""" + print("[INFO] {0}".format(msg.decode('utf-8').rstrip())) + + +def _default_warning_handler(library_msg, _): + """Default warning handler callback for openjpeg library.""" + library_msg = library_msg.decode('utf-8').rstrip() + msg = "OpenJPEG library warning: {0}".format(library_msg) + warnings.warn(msg) + +_ERROR_CALLBACK = _CMPFUNC(_default_error_handler) +_INFO_CALLBACK = _CMPFUNC(_default_info_handler) +_WARNING_CALLBACK = _CMPFUNC(_default_warning_handler) + + +class LibraryNotFoundError(IOError): + """Raised if functionality is requested without the necessary library. + """ + def __init__(self, msg): + IOError.__init__(self, msg) + diff --git a/glymur/test/test_jp2k.py b/glymur/test/test_jp2k.py index c018897..747782f 100644 --- a/glymur/test/test_jp2k.py +++ b/glymur/test/test_jp2k.py @@ -225,7 +225,7 @@ class TestJp2k(unittest.TestCase): Jp2k(filename) @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") - def test_write_with_JP2_suffix(self): + def test_write_with_jp2_in_caps(self): """should be able to write with JP2 suffix.""" j2k = Jp2k(self.j2kfile) expdata = j2k.read()