Merge branch 'master' into devel

This commit is contained in:
John Evans 2013-05-28 11:27:43 -04:00
commit 555f84275f
8 changed files with 152 additions and 118 deletions

View file

@ -1 +1,7 @@
May 28, 2013 - Added jp2 boxes to rst docs, XMLBox.indent method made private.
May 27, 2013 - v0.1.1, Changed write example to not rely on matplotlib. Fixed
readthedocs.org setup to build documentation automatically. Can import
glymur without libopenjp2 actually being present.
May 27, 2013 - Changed write example to not rely on matplotlib.

View file

@ -1,4 +1,3 @@
=========================================
glymur: a Python interface for JPEG 2000
=========================================
@ -6,8 +5,4 @@ glymur: a Python interface for JPEG 2000
which allows linux and mac users to read and write JPEG 2000 files.
**glymur** works on Python 2.7 and 3.3. Python 3.3 is strongly recommended.
Until I figure out how to get readthedocs.org to handle numpydoc, you'll have
to do as follows to build the documentation first::
$ make -C docs html
$ open docs/build/html/index.html
Please read the docs, https://glymur.readthedocs.org/en/latest/

View file

@ -13,6 +13,29 @@
import sys, os
class Mock(object):
def __init__(self, *args, **kwargs):
pass
def __call__(self, *args, **kwargs):
return Mock()
@classmethod
def __getattr__(cls, name):
if name in ('__file__', '__path__'):
return '/dev/null'
elif name[0] == name[0].upper():
mockType = type(name, (), {})
mockType.__module__ = __name__
return mockType
else:
return Mock()
MOCK_MODULES = ['numpy']
for mod_name in MOCK_MODULES:
sys.modules[mod_name] = Mock()
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
@ -52,7 +75,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.0.a1'
release = '0.1.1'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View file

@ -4,10 +4,10 @@ glymur: a Python interface for JPEG 2000
**glymur** contains a Python interface to the OpenJPEG library
which allows linux and mac users to read and write JPEG 2000 files. For more
information about OpenJPEG, please consult http://www.openjpeg.org. **glymur**
information about OpenJPEG, please consult http://www.openjpeg.org. glymur
should be considered to be alpha-quality software.
**glymur** tries to support reading (including all metadata) and writing of
glymur tries to support reading (including all metadata) and writing of
JP2 and J2C files. Writing J2C/JP2 files is currently limited to images that
can fit in memory, however.
@ -18,7 +18,7 @@ metadata can be retrieved from such JPX files.
------------
Requirements
------------
**glymur** works on Python 2.7 and 3.3. Python 3.3 is strongly recommended.
glymur works on Python 2.7 and 3.3. Python 3.3 is strongly recommended.
OpenJPEG
========
@ -26,7 +26,7 @@ OpenJPEG must be built as a shared library. In addition, you
currently must compile OpenJPEG from the developmental source that
you can retrieve via subversion. As of this time of writing, svn
revision 2345 works. In addition, you should also retrieve their test data, as
you will need it when running **glymur**'s test suite.
you will need it when running glymur's test suite.
Earlier versions of OpenJPEG through the 2.0 official release are not supported.
@ -50,7 +50,7 @@ OS
Mac OS X
--------
All the necessary packages are available to use **glymur** with Python 3.3 via
All the necessary packages are available to use glymur with Python 3.3 via
MacPorts. A minimal set of ports includes
* python33
@ -83,12 +83,12 @@ combinations of RPMs / Python packages is installed.
* scikit-image and either Pillow or freeimage
* matplotlib and Pillow
The 2nd route is probably the easiest, so go ahead and install **Pillow**
via **pip** since **Pillow** is not yet available in Fedora 18 default
The 2nd route is probably the easiest, so go ahead and install Pillow
via pip since Pillow is not yet available in Fedora 18 default
repositories::
$ yum install python3-devel # pip needs this in order to compile Pillow
$ yum install python3-pip # First one must install pip of course!
$ yum install python3-pip
$ pip-python3 install Pillow --user
$ export PYTHONPATH=$HOME/.local/lib/python3.3/site-packages:$PYTHONPATH
@ -105,7 +105,7 @@ Required RPMs include::
* python-setuptools
* numpy
In addition, you must install **contextlib2** via pip.
In addition, you must install contextlib2 via pip.
A few tests still will not run, however, unless one of the following
combinations of RPMs / Python packages is installed.
@ -113,8 +113,8 @@ combinations of RPMs / Python packages is installed.
* scikit-image and either Pillow or freeimage
* matplotlib and Pillow
**scikit-image** is not available in the Fedora 17 default repositories, but
it may be installed via **pip**::
scikit-image is not available in the Fedora 17 default repositories, but
it may be installed via pip::
$ yum install Cython # pip needs this in order to compile scikit-image
$ yum install python-devel # pip needs this in order to compile scikit-image
@ -137,7 +137,7 @@ From this point forward, python3 will be referred to as just "python".
Installation
============
In addition to merely installing **glymur**, you should adjust your **$PATH**
In addition to merely installing glymur, you should adjust your **$PATH**
environment variable in order to be able to use the **jp2dump** script from
the unix command line.
@ -150,8 +150,8 @@ the unix command line.
Configuration
=============
glymur uses **ctypes** (for the moment) to access the openjp2 library, and
because **ctypes** access libraries in a platform-dependent manner, it is
glymur uses ctypes (for the moment) to access the openjp2 library, and
because ctypes access libraries in a platform-dependent manner, it is
recommended that you create a configuration file to help glymur properly find
the openjp2 library. You may create the configuration file as follows::

View file

@ -23,8 +23,12 @@ def _glymurrc_fname():
fname = os.path.join(path, 'glymurrc')
if os.path.exists(fname):
return fname
else:
msg = "glymurrc file hinted at by GLYMURCONFIGDIR does not "
msg += "exist."
warnings.warn(msg, UserWarning)
# HOME/.glymur/jptoolrsc
# HOME/.glymur/glymurrc
confdir = _get_configdir()
if confdir is not None:
fname = os.path.join(_get_configdir(), 'glymurrc')
@ -45,26 +49,22 @@ def _config():
# Read the configuration file for the library location.
parser = ConfigParser()
parser.read(filename)
try:
libopenjp2_path = parser.get('library', 'openjp2')
if not os.path.exists(libopenjp2_path):
msg = 'OpenJP2 library path specified by configuration file '
msg += 'does not exist.'
raise ImportError(msg)
except NoOptionError as e:
msg = "Error parsing configuration file '{0}': {1}"
msg = msg.format(fname, e.message)
warnings.warn(msg, UserWarning)
except:
raise
libopenjp2_path = parser.get('library', 'openjp2')
else:
# No help from the config file, try to find it ourselves.
from ctypes.util import find_library
libopenjp2_path = find_library('openjp2')
if libopenjp2_path is None:
raise ImportError('OpenJP2 library not found.')
_OPENJP2 = ctypes.CDLL(libopenjp2_path)
if libopenjp2_path is None:
return None
try:
_OPENJP2 = ctypes.CDLL(libopenjp2_path)
except OSError:
msg = '"Library {0}" could not be loaded. Operating in degraded mode.'
msg = msg.format(libopenjp2_path)
warnings.warn(msg, UserWarning)
_OPENJP2 = None
return _OPENJP2
@ -81,6 +81,7 @@ def _get_configdir():
if 'HOME' in os.environ:
return os.path.join(os.environ['HOME'], '.glymur')
import warnings
import sys
if sys.hexversion <= 0x03000000:
from ConfigParser import SafeConfigParser as ConfigParser

View file

@ -528,105 +528,110 @@ class _codestream_info_v2_t(ctypes.Structure):
# Restrict the input and output argument types for each function used in the
# API.
_OPENJP2.opj_create_compress.argtypes = [_codec_format_t]
_OPENJP2.opj_create_compress.restype = _codec_t_p
if _OPENJP2 is not None:
_OPENJP2.opj_create_compress.argtypes = [_codec_format_t]
_OPENJP2.opj_create_compress.restype = _codec_t_p
_OPENJP2.opj_create_decompress.argtypes = [_codec_format_t]
_OPENJP2.opj_create_decompress.restype = _codec_t_p
_OPENJP2.opj_create_decompress.argtypes = [_codec_format_t]
_OPENJP2.opj_create_decompress.restype = _codec_t_p
_argtypes = [_codec_t_p, _stream_t_p, ctypes.POINTER(_image_t)]
_OPENJP2.opj_decode.argtypes = _argtypes
_argtypes = [_codec_t_p, _stream_t_p, ctypes.POINTER(_image_t)]
_OPENJP2.opj_decode.argtypes = _argtypes
_argtypes = [_codec_t_p, ctypes.c_uint32,
ctypes.POINTER(ctypes.c_uint8),
ctypes.c_uint32,
_stream_t_p]
_OPENJP2.opj_decode_tile_data.argtypes = _argtypes
_argtypes = [_codec_t_p, ctypes.c_uint32,
ctypes.POINTER(ctypes.c_uint8),
ctypes.c_uint32,
_stream_t_p]
_OPENJP2.opj_decode_tile_data.argtypes = _argtypes
_argtypes = [ctypes.POINTER(ctypes.POINTER(_codestream_info_v2_t))]
_OPENJP2.opj_destroy_cstr_info.argtypes = _argtypes
_OPENJP2.opj_destroy_cstr_info.restype = ctypes.c_void_p
_argtypes = [ctypes.POINTER(ctypes.POINTER(_codestream_info_v2_t))]
_OPENJP2.opj_destroy_cstr_info.argtypes = _argtypes
_OPENJP2.opj_destroy_cstr_info.restype = ctypes.c_void_p
_argtypes = [_codec_t_p, _stream_t_p]
_OPENJP2.opj_encode.argtypes = _argtypes
_argtypes = [_codec_t_p, _stream_t_p]
_OPENJP2.opj_encode.argtypes = _argtypes
_OPENJP2.opj_get_cstr_info.argtypes = [_codec_t_p]
_OPENJP2.opj_get_cstr_info.restype = ctypes.POINTER(_codestream_info_v2_t)
_OPENJP2.opj_get_cstr_info.argtypes = [_codec_t_p]
_OPENJP2.opj_get_cstr_info.restype = ctypes.POINTER(_codestream_info_v2_t)
_argtypes = [_codec_t_p,
_stream_t_p,
ctypes.POINTER(_image_t),
ctypes.c_uint32]
_OPENJP2.opj_get_decoded_tile.argtypes = _argtypes
_argtypes = [_codec_t_p,
_stream_t_p,
ctypes.POINTER(_image_t),
ctypes.c_uint32]
_OPENJP2.opj_get_decoded_tile.argtypes = _argtypes
_argtypes = [ctypes.c_uint32,
ctypes.POINTER(_image_comptparm_t),
color_space_t]
_OPENJP2.opj_image_create.argtypes = _argtypes
_OPENJP2.opj_image_create.restype = ctypes.POINTER(_image_t)
_argtypes = [ctypes.c_uint32,
ctypes.POINTER(_image_comptparm_t),
color_space_t]
_OPENJP2.opj_image_create.argtypes = _argtypes
_OPENJP2.opj_image_create.restype = ctypes.POINTER(_image_t)
_argtypes = [ctypes.c_uint32,
ctypes.POINTER(_image_comptparm_t),
color_space_t]
_OPENJP2.opj_image_tile_create.argtypes = _argtypes
_OPENJP2.opj_image_tile_create.restype = ctypes.POINTER(_image_t)
_argtypes = [ctypes.c_uint32,
ctypes.POINTER(_image_comptparm_t),
color_space_t]
_OPENJP2.opj_image_tile_create.argtypes = _argtypes
_OPENJP2.opj_image_tile_create.restype = ctypes.POINTER(_image_t)
_OPENJP2.opj_image_destroy.argtypes = [ctypes.POINTER(_image_t)]
_OPENJP2.opj_image_destroy.argtypes = [ctypes.POINTER(_image_t)]
_argtypes = [_stream_t_p, _codec_t_p, ctypes.POINTER(ctypes.POINTER(_image_t))]
_OPENJP2.opj_read_header.argtypes = _argtypes
_argtypes = [_stream_t_p, _codec_t_p,
ctypes.POINTER(ctypes.POINTER(_image_t))]
_OPENJP2.opj_read_header.argtypes = _argtypes
_argtypes = [_codec_t_p,
_stream_t_p,
ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32),
ctypes.POINTER(ctypes.c_int32), ctypes.POINTER(ctypes.c_int32),
ctypes.POINTER(ctypes.c_int32), ctypes.POINTER(ctypes.c_int32),
ctypes.POINTER(ctypes.c_uint32),
ctypes.POINTER(_bool_t)]
_OPENJP2.opj_read_tile_header.argtypes = _argtypes
_argtypes = [_codec_t_p,
_stream_t_p,
ctypes.POINTER(ctypes.c_uint32),
ctypes.POINTER(ctypes.c_uint32),
ctypes.POINTER(ctypes.c_int32),
ctypes.POINTER(ctypes.c_int32),
ctypes.POINTER(ctypes.c_int32),
ctypes.POINTER(ctypes.c_int32),
ctypes.POINTER(ctypes.c_uint32),
ctypes.POINTER(_bool_t)]
_OPENJP2.opj_read_tile_header.argtypes = _argtypes
_argtypes = [_codec_t_p, ctypes.POINTER(_image_t), ctypes.c_int32,
ctypes.c_int32, ctypes.c_int32, ctypes.c_int32]
_OPENJP2.opj_set_decode_area.argtypes = _argtypes
_argtypes = [_codec_t_p, ctypes.POINTER(_image_t), ctypes.c_int32,
ctypes.c_int32, ctypes.c_int32, ctypes.c_int32]
_OPENJP2.opj_set_decode_area.argtypes = _argtypes
_argtypes = [ctypes.POINTER(_cparameters_t)]
_OPENJP2.opj_set_default_encoder_parameters.argtypes = _argtypes
_argtypes = [ctypes.POINTER(_cparameters_t)]
_OPENJP2.opj_set_default_encoder_parameters.argtypes = _argtypes
_argtypes = [ctypes.POINTER(_dparameters_t)]
_OPENJP2.opj_set_default_decoder_parameters.argtypes = _argtypes
_argtypes = [ctypes.POINTER(_dparameters_t)]
_OPENJP2.opj_set_default_decoder_parameters.argtypes = _argtypes
_argtypes = [_codec_t_p, ctypes.c_void_p, ctypes.c_void_p]
_OPENJP2.opj_set_error_handler.argtypes = _argtypes
_OPENJP2.opj_set_info_handler.argtypes = _argtypes
_OPENJP2.opj_set_warning_handler.argtypes = _argtypes
_argtypes = [_codec_t_p, ctypes.c_void_p, ctypes.c_void_p]
_OPENJP2.opj_set_error_handler.argtypes = _argtypes
_OPENJP2.opj_set_info_handler.argtypes = _argtypes
_OPENJP2.opj_set_warning_handler.argtypes = _argtypes
_argtypes = [_codec_t_p, ctypes.POINTER(_dparameters_t)]
_OPENJP2.opj_setup_decoder.argtypes = _argtypes
_argtypes = [_codec_t_p, ctypes.POINTER(_dparameters_t)]
_OPENJP2.opj_setup_decoder.argtypes = _argtypes
_argtypes = [_codec_t_p,
ctypes.POINTER(_cparameters_t),
ctypes.POINTER(_image_t)]
_OPENJP2.opj_setup_encoder.argtypes = _argtypes
_argtypes = [_codec_t_p,
ctypes.POINTER(_cparameters_t),
ctypes.POINTER(_image_t)]
_OPENJP2.opj_setup_encoder.argtypes = _argtypes
_argtypes = [ctypes.c_char_p, ctypes.c_int32]
_OPENJP2.opj_stream_create_default_file_stream_v3.argtypes = _argtypes
_OPENJP2.opj_stream_create_default_file_stream_v3.restype = _stream_t_p
_argtypes = [ctypes.c_char_p, ctypes.c_int32]
_OPENJP2.opj_stream_create_default_file_stream_v3.argtypes = _argtypes
_OPENJP2.opj_stream_create_default_file_stream_v3.restype = _stream_t_p
_argtypes = [_codec_t_p, ctypes.POINTER(_image_t), _stream_t_p]
_OPENJP2.opj_start_compress.argtypes = _argtypes
_argtypes = [_codec_t_p, ctypes.POINTER(_image_t), _stream_t_p]
_OPENJP2.opj_start_compress.argtypes = _argtypes
_OPENJP2.opj_end_compress.argtypes = [_codec_t_p, _stream_t_p]
_OPENJP2.opj_end_decompress.argtypes = [_codec_t_p, _stream_t_p]
_OPENJP2.opj_end_compress.argtypes = [_codec_t_p, _stream_t_p]
_OPENJP2.opj_end_decompress.argtypes = [_codec_t_p, _stream_t_p]
_OPENJP2.opj_stream_destroy_v3.argtypes = [_stream_t_p]
_OPENJP2.opj_destroy_codec.argtypes = [_codec_t_p]
_OPENJP2.opj_stream_destroy_v3.argtypes = [_stream_t_p]
_OPENJP2.opj_destroy_codec.argtypes = [_codec_t_p]
_argtypes = [_codec_t_p,
ctypes.c_uint32,
ctypes.POINTER(ctypes.c_uint8),
ctypes.c_uint32,
_stream_t_p]
_OPENJP2.opj_write_tile.argtypes = _argtypes
_argtypes = [_codec_t_p,
ctypes.c_uint32,
ctypes.POINTER(ctypes.c_uint8),
ctypes.c_uint32,
_stream_t_p]
_OPENJP2.opj_write_tile.argtypes = _argtypes
def _check_error(status):
@ -655,9 +660,10 @@ _fcns = ['opj_decode', 'opj_decode_tile_data', 'opj_end_compress',
'opj_set_warning_handler',
'opj_setup_decoder', 'opj_setup_encoder', 'opj_start_compress',
'opj_write_tile']
for _fcn in _fcns:
_attr = getattr(_OPENJP2, _fcn)
setattr(_attr, 'restype', _check_error)
if _OPENJP2 is not None:
for _fcn in _fcns:
_attr = getattr(_OPENJP2, _fcn)
setattr(_attr, 'restype', _check_error)
def _create_compress(codec_format):

View file

@ -582,7 +582,7 @@ class TestJp2k(unittest.TestCase):
with patch.dict('os.environ', {'GLYMURCONFIGDIR': tdir}):
# Misconfigured new configuration file should
# be rejected.
with self.assertRaises(ImportError) as ce:
with self.assertWarns(UserWarning) as cw:
imp.reload(glymur)
@unittest.skipIf(sys.hexversion < 0x03020000,
@ -594,7 +594,7 @@ class TestJp2k(unittest.TestCase):
with patch.dict('os.environ', {'GLYMURCONFIGDIR': tdir}):
# Misconfigured new configuration file should
# be rejected.
with self.assertRaises(ImportError) as ce:
with self.assertWarns(UserWarning) as cw:
imp.reload(glymur)

View file

@ -0,0 +1,3 @@
numpydoc==0.4
contextlib2==0.4.0
mock==1.0.1