Merge branch 'issue67' into devel

This commit is contained in:
jevans 2013-07-06 22:04:18 -04:00
commit 162e6372c9
20 changed files with 1461 additions and 244 deletions

View file

@ -1,3 +1,4 @@
include *.txt *.md
prune build
exclude readthedocs-pip-requirements.txt
exclude release.txt

View file

@ -1,16 +1,54 @@
-----------------------------------------------------
Detailed Instructions for Package Management, Testing
-----------------------------------------------------
----------------------------------
Detailed Installation Instructions
----------------------------------
You only need to read this page if you want detailed
''''''''''''''''''''''
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. ::
$ svn co http://openjpeg.googlecode.com/svn/data
$ export OPJ_DATA_ROOT=`pwd`/data
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::
$ mkdir -p ~/.config/glymur
$ cd ~/.config/glymur
$ cat > glymurrc << EOF
> [library]
> openjp2: /opt/openjp2-svn/lib/libopenjp2.so
> EOF
That 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.
'''''''''''''''''''''''''''''''''''''''''''
Package Management Suggestions for Testing
'''''''''''''''''''''''''''''''''''''''''''
You only need to read this section if you want detailed
platform-specific instructions on running as many tests as possible or wish to
use your system's package manager to install as many required
packages/RPMs/ports/whatever without going through pip. Otherwise go on to
the next page.
packages/RPMs/ports/whatever without going through pip.
''''''''
Platform
''''''''
Mac OS X
--------
@ -58,8 +96,9 @@ repositories::
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.
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::
@ -79,8 +118,8 @@ one unexpected failure as of the time of writing.
Fedora 17
'''''''''
Fedora 17 ships with Python 3.2 and 2.7, so these steps detail working with
2.7.
Fedora 17 ships with Python 3.2 and 2.7, but OpenJPEG is only at version 1.4,
so these steps detail working with Python 2.7 and the svn version of OpenJPEG.
Required RPMs include::
@ -111,7 +150,10 @@ it was installable via pip::
Windows
-------
Not currently supported.
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.
'''''''
Testing

View file

@ -2,14 +2,9 @@
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
currently relies upon a development version of the OpenJPEG library, and so,
while useable, it is totally at the mercy of any upstream changes
made to the development version of OpenJPEG.
Glymur supports both reading and writing of JPEG 2000 images (part 1). Writing
**Glymur** is an interface to the OpenJPEG library
which allows one to read and write JPEG 2000 files from within Python.
Glymur supports both reading and writing of JPEG 2000 images. Writing
JPEG 2000 images is currently limited to images that can fit in memory,
however.
@ -23,34 +18,18 @@ Glymur works on Python 2.7 and 3.3. Python 3.3 is strongly recommended.
OpenJPEG Installation
=====================
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. You should 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. ::
The OpenJPEG library version must be either 1.5.1 or the trunk/development
version of OpenJPEG. Version 2.0.0 or versions earlier than 1.5.0
are not supported. Furthermore, the 1.5.x version of OpenJPEG is
currently only utilized for read-only purposes. For more information
about OpenJPEG, please consult http://www.openjpeg.org.
$ svn co http://openjpeg.googlecode.com/svn/data
$ export OPJ_DATA_ROOT=`pwd`/data
Earlier versions of OpenJPEG through the 2.0 official release will **NOT**
work and are not supported.
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::
$ mkdir -p ~/.config/glymur
$ cd ~/.config/glymur
$ cat > glymurrc << EOF
> [library]
> openjp2: /opt/openjp2-svn/lib/libopenjp2.so
> EOF
That assumes, of course, that you've installed OpenJPEG into /opt/openjp2-svn.
You may also substitute **$XDG_CONFIG_HOME** for **$HOME/.config**.
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
https://code.google.com/p/openjpeg/downloads/list .
Glymur Installation
===================
@ -76,5 +55,6 @@ You can run the tests from within python as follows::
>>> import glymur
>>> glymur.runtests()
Many tests are currently skipped; the important thing is whether or not any
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.

View file

@ -186,4 +186,3 @@ _reader_requirements_display = {
+ 'requirements in M.9.2.3',
73: 'YPbPr(1125/60) enumerated colourspace',
74: 'YPbPr(1250/50) enumerated colourspace'}

Binary file not shown.

View file

@ -18,6 +18,7 @@ import numpy as np
from .codestream import Codestream
from .core import *
from .jp2box import *
from .lib import openjpeg as opj
from .lib import openjp2 as opj2
_cspace_map = {'rgb': opj2._CLRSPC_SRGB,
@ -202,7 +203,7 @@ class Jp2k(Jp2kBox):
>>> import glymur
>>> jfile = glymur.data.nemo()
>>> jp2 = glymur.Jp2k(jfile)
>>> data = jp2.read(reduce=3)
>>> data = jp2.read(reduce=1)
>>> from tempfile import NamedTemporaryFile
>>> tfile = NamedTemporaryFile(suffix='.jp2', delete=False)
>>> j = Jp2k(tfile.name, mode='wb')
@ -544,16 +545,17 @@ class Jp2k(Jp2kBox):
jp2 = Jp2k(filename)
return jp2
def read(self, reduce=0, layer=0, area=None, tile=None, verbose=False):
def read(self, **kwargs):
"""Read a JPEG 2000 image.
Parameters
----------
layer : int, optional
Number of quality layer to decode.
reduce : int, optional
Factor by which to reduce output resolution. Use -1 to get the
lowest resolution thumbnail.
lowest resolution thumbnail. This is the only keyword option
available to use when only OpenJPEG version 1.5.1 is present.
layer : int, optional
Number of quality layer to decode.
area : tuple, optional
Specifies decoding image area,
(first_row, first_col, last_row, last_col)
@ -585,7 +587,156 @@ class Jp2k(Jp2kBox):
>>> thumbnail = jp.read(reduce=-1)
>>> thumbnail.shape
(46, 81, 3)
(728, 1296, 3)
"""
if opj2._OPENJP2 is not None:
img = self._read_openjp2(**kwargs)
else:
img = self._read_openjpeg(**kwargs)
return img
def _read_openjpeg(self, reduce=0, verbose=False):
"""Read a JPEG 2000 image using libopenjpeg.
Parameters
----------
reduce : int, optional
Factor by which to reduce output resolution. Use -1 to get the
lowest resolution thumbnail.
verbose : bool, optional
Print informational messages produced by the OpenJPEG library.
Returns
-------
img_array : ndarray
The image data.
Raises
------
RuntimeError
If the image has differing subsample factors.
"""
# Check for differing subsample factors.
codestream = self.get_codestream(header_only=True)
dxs = np.array(codestream.segment[1].XRsiz)
dys = np.array(codestream.segment[1].YRsiz)
if np.any(dxs - dxs[0]) or np.any(dys - dys[0]):
msg = "Components must all have the same subsampling factors "
msg += "to use this method with OpenJPEG 1.5.1. Please consider "
msg += "using OPENJP2 instead."
raise RuntimeError(msg)
with ExitStack() as stack:
# Set decoding parameters.
dparameters = opj.dparameters_t()
opj._set_default_decoder_parameters(ctypes.byref(dparameters))
dparameters.cp_reduce = reduce
dparameters.decod_format = self._codec_format
infile = self.filename.encode()
nelts = opj._PATH_LEN - len(infile)
infile += b'0' * nelts
dparameters.infile = infile
dinfo = opj._create_decompress(dparameters.decod_format)
event_mgr = opj.event_mgr_t()
info_handler = ctypes.cast(_info_callback, ctypes.c_void_p)
event_mgr.info_handler = info_handler if verbose else None
event_mgr.warning_handler = ctypes.cast(_warning_callback,
ctypes.c_void_p)
event_mgr.error_handler = ctypes.cast(_error_callback,
ctypes.c_void_p)
opj._set_event_mgr(dinfo, ctypes.byref(event_mgr))
opj._setup_decoder(dinfo, dparameters)
with open(self.filename, 'rb') as fp:
src = fp.read()
cio = opj._cio_open(dinfo, src)
image = opj._decode(dinfo, cio)
stack.callback(opj._image_destroy, image)
stack.callback(opj._destroy_decompress, dinfo)
stack.callback(opj._cio_close, cio)
ncomps = image.contents.numcomps
component = image.contents.comps[0]
if component.sgnd:
if component.prec <= 8:
dtype = np.int8
elif component.prec <= 16:
dtype = np.int16
else:
raise RuntimeError("Unhandled precision, datatype")
else:
if component.prec <= 8:
dtype = np.uint8
elif component.prec <= 16:
dtype = np.uint16
else:
raise RuntimeError("Unhandled precision, datatype")
nrows = image.contents.comps[0].h
ncols = image.contents.comps[0].w
ncomps = image.contents.numcomps
data = np.zeros((nrows, ncols, ncomps), dtype)
for k in range(image.contents.numcomps):
component = image.contents.comps[k]
nrows = component.h
ncols = component.w
if nrows == 0 or ncols == 0:
# Letting this situation continue would segfault
# Python.
msg = "Component {0} has dimensions {1} x {2}"
msg = msg.format(k, nrows, ncols)
raise IOError(msg)
addr = ctypes.addressof(component.data.contents)
with warnings.catch_warnings():
warnings.simplefilter("ignore")
nelts = nrows * ncols
x = np.ctypeslib.as_array((ctypes.c_int32 * nelts).from_address(addr))
data[:, :, k] = np.reshape(x.astype(dtype), (nrows, ncols))
if data.shape[2] == 1:
data = data.view()
data.shape = data.shape[0:2]
return data
def _read_openjp2(self, reduce=0, layer=0, area=None, tile=None,
verbose=False):
"""Read a JPEG 2000 image using libopenjp2.
Parameters
----------
layer : int, optional
Number of quality layer to decode.
reduce : int, optional
Factor by which to reduce output resolution. Use -1 to get the
lowest resolution thumbnail.
area : tuple, optional
Specifies decoding image area,
(first_row, first_col, last_row, last_col)
tile : int, optional
Number of tile to decode.
verbose : bool, optional
Print informational messages produced by the OpenJPEG library.
Returns
-------
img_array : ndarray
The image data.
Raises
------
RuntimeError
If the image has differing subsample factors.
"""
# Check for differing subsample factors.
codestream = self.get_codestream(header_only=True)
@ -593,7 +744,7 @@ class Jp2k(Jp2kBox):
dys = np.array(codestream.segment[1].YRsiz)
if np.any(dxs - dxs[0]) or np.any(dys - dys[0]):
msg = "Components must all have the same subsampling factors."
raise IOError(msg)
raise RuntimeError(msg)
img_array = self._read_common(reduce=reduce,
layer=layer,
@ -780,7 +931,16 @@ class Jp2k(Jp2kBox):
>>> jfile = glymur.data.nemo()
>>> jp = glymur.Jp2k(jfile)
>>> components_lst = jp.read_bands(reduce=1)
Raises
------
NotImplementedError
If the openjp2 library is not available.
"""
if opj2._OPENJP2 is None:
msg = "Requires openjp2 library."
raise NotImplementedError(msg)
lst = self._read_common(reduce=reduce,
layer=layer,
area=area,
@ -807,14 +967,14 @@ class Jp2k(Jp2kBox):
--------
>>> import glymur
>>> jfile = glymur.data.nemo()
>>> jp = glymur.Jp2k(jfile)
>>> codestream = jp.get_codestream()
>>> jp2 = glymur.Jp2k(jfile)
>>> codestream = jp2.get_codestream()
>>> print(codestream.segment[1])
SIZ marker segment @ (3137, 47)
Profile: 2
Reference Grid Height, Width: (1456 x 2592)
Vertical, Horizontal Reference Grid Offset: (0 x 0)
Reference Tile Height, Width: (512 x 512)
Reference Tile Height, Width: (1456 x 2592)
Vertical, Horizontal Reference Tile Offset: (0 x 0)
Bitdepth: (8, 8, 8)
Signed: (False, False, False)

View file

@ -1,3 +1,4 @@
"""This package organizes individual libraries employed by glymur."""
from . import openjp2
from . import test
from . import openjpeg
#from . import test

View file

@ -1,6 +1,9 @@
"""
Wraps individual functions in openjp2 library.
"""
import ctypes
import platform
from ctypes.util import find_library
def _glymurrc_fname():
@ -23,19 +26,46 @@ def _glymurrc_fname():
fname = os.path.join(confdir, 'glymurrc')
if os.path.exists(fname):
return fname
else:
msg = "Configuration file '{0}' does not exist.".format(confdir)
warnings.warn(msg, UserWarning)
# didn't find a configuration file.
return None
def _config():
"""Read configuration file.
def _get_openjpeg_config():
libopenjpeg_path = find_library('openjpeg')
# If we could not find it, then look in some likely locations.
if libopenjpeg_path is None:
if platform.system() == 'Darwin':
path = '/opt/local/lib/libopenjpeg.dylib'
if os.path.exists(path):
libopenjpeg_path = path
elif os.name == 'nt':
path = os.path.join('C:\\', 'Program files', 'OpenJPEG 1.5',
'bin', 'openjpeg.dll')
if os.path.exists(path):
libopenjpeg_path = path
Based on matplotlib.
"""
try:
if os.name == "nt":
_OPENJPEG = ctypes.windll.LoadLibrary(libopenjpeg_path)
else:
_OPENJPEG = ctypes.CDLL(libopenjpeg_path)
except OSError:
_OPENJPEG = None
if _OPENJPEG is not None:
# Must be at least 1.5.0
_OPENJPEG.opj_version.restype = ctypes.c_char_p
v = _OPENJPEG.opj_version()
v = v.decode('utf-8')
major, minor, patch = v.split('.')
if minor != '5':
_OPENJPEG = None
return _OPENJPEG
def _get_openjp2_config():
filename = _glymurrc_fname()
if filename is not None:
# Read the configuration file for the library location.
@ -44,14 +74,16 @@ def _config():
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:
return None
try:
_OPENJP2 = ctypes.CDLL(libopenjp2_path)
if os.name == "nt":
_OPENJP2 = ctypes.windll.LoadLibrary(libopenjp2_path)
else:
_OPENJP2 = ctypes.CDLL(libopenjp2_path)
except OSError:
msg = '"Library {0}" could not be loaded. Operating in degraded mode.'
msg = msg.format(libopenjp2_path)
@ -60,6 +92,13 @@ def _config():
return _OPENJP2
def _config():
"""Read configuration file.
"""
_OPENJP2 = _get_openjp2_config()
_OPENJPEG = _get_openjpeg_config()
return _OPENJP2, _OPENJPEG
def _get_configdir():
"""Return string representing the configuration directory.
@ -73,7 +112,9 @@ def _get_configdir():
if 'HOME' in os.environ:
return os.path.join(os.environ['HOME'], '.config', 'glymur')
import ctypes
if 'USERPROFILE' in os.environ:
return os.path.join(os.environ['USERPROFILE'], 'Application Data', 'glymur')
import os
import warnings
@ -85,7 +126,12 @@ else:
from configparser import ConfigParser
from configparser import NoOptionError
_OPENJP2 = _config()
_OPENJP2, _OPENJPEG = _config()
if _OPENJP2 is None and _OPENJPEG is None:
msg = "Neither the glymur configuration file could not be located "
msg += "nor could openjpeg 1.5.1 be located. Glymur can only "
msg += "operate under extremely degraded conditions."
warnings.warn(msg, UserWarning)
import numpy as np
@ -616,8 +662,8 @@ class _codestream_info_v2_t(ctypes.Structure):
# Restrict the input and output argument types for each function used in the
# API.
if _OPENJP2 is not None:
_OPENJP2.opj_create_compress.argtypes = [_codec_format_t]
_OPENJP2.opj_create_compress.restype = _codec_t_p
_OPENJP2.opj_create_compress.argtypes = [_codec_format_t]
_OPENJP2.opj_create_decompress.argtypes = [_codec_format_t]
_OPENJP2.opj_create_decompress.restype = _codec_t_p

189
glymur/lib/openjpeg.py Normal file
View file

@ -0,0 +1,189 @@
"""Wraps library calls to openjpeg.
"""
import ctypes
from ctypes.util import find_library
import platform
import os
if os.name == "nt":
path = os.path.join('C:\\', 'Program files', 'OpenJPEG 1.5',
'bin', 'openjpeg.dll')
_OPENJPEG = ctypes.windll.LoadLibrary(path)
else:
if platform.system() == 'Darwin':
_OPENJPEG = ctypes.CDLL('/opt/local/lib/libopenjpeg.dylib')
elif platform.system() == 'Linux':
_OPENJPEG = ctypes.CDLL(find_library('openjpeg'))
_PATH_LEN = 4096 # maximum allowed size for filenames
class event_mgr_t(ctypes.Structure):
"""Message handler object.
"""
_fields_ = [("error_handler", ctypes.c_void_p),
("warning_handler", ctypes.c_void_p),
("info_handler", ctypes.c_void_p)]
class common_struct_t(ctypes.Structure):
"""Common fields between JPEG 2000 compression and decompression contextx.
"""
_fields_ = [("event_mgr", ctypes.POINTER(event_mgr_t)),
("client_data", ctypes.c_void_p),
("is_decompressor", ctypes.c_bool),
("codec_format", ctypes.c_int),
("j2k_handle", ctypes.c_void_p),
("jp2_handle", ctypes.c_void_p),
("mj2_handle", ctypes.c_void_p)]
class dinfo_t(ctypes.Structure):
"""Common fields between JPEG 2000 compression and decompression contextx.
This is for decompression contexts.
"""
pass
class cio_t(ctypes.Structure):
_fields_ = [# codec context
("cinfo", ctypes.POINTER(common_struct_t)),
# STREAM_READ or STREAM_WRITE
("openmode", ctypes.c_int),
# pointer to start of buffer
("buffer", ctypes.POINTER(ctypes.c_char)),
# buffer size in bytes
("length", ctypes.c_int),
# pointer to start of stream
("start", ctypes.c_char_p),
# pointer to end of stream
("end", ctypes.c_char_p),
# pointer to current position
("bp", ctypes.c_char_p)]
class dparameters_t(ctypes.Structure):
# cp_reduce: the number of highest resolution levels to be discarded
_fields_ = [("cp_reduce", ctypes.c_int),
# cp_layer: the maximum number of quality layers to decode
("cp_layer", ctypes.c_int),
# infile: input file name
("infile", ctypes.c_char * _PATH_LEN),
# outfile: output file name
("outfile", ctypes.c_char * _PATH_LEN),
# decod_format: input file format 0: J2K, 1: JP2, 2: JPT
("decod_format", ctypes.c_int),
# cod_format: output file format 0: PGX, 1: PxM, 2: BMP
("cod_format", ctypes.c_int),
# jpwl_correct: activates the JPWL correction capabilities
("jpwl_correct", ctypes.c_bool),
# jpwl_exp_comps: expected number of components
("jpwl_exp_comps", ctypes.c_int),
# jpwl_max_tiles: maximum number of tiles
("jpwl_max_tiles", ctypes.c_int),
# cp_limit_decoding: whether decoding should be done on the
# entire codestream or be limited to the main header
("cp_limit_decoding", ctypes.c_int),
("flags", ctypes.c_uint)]
class image_comp_t(ctypes.Structure):
"""Defines a single image component. """
_fields_ = [("dx", ctypes.c_int),
("dy", ctypes.c_int),
("w", ctypes.c_int),
("h", ctypes.c_int),
("x0", ctypes.c_int),
("y0", ctypes.c_int),
("prec", ctypes.c_int),
("bpp", ctypes.c_int),
("sgnd", ctypes.c_int),
("resno_decoded", ctypes.c_int),
("factor", ctypes.c_int),
("data", ctypes.POINTER(ctypes.c_int))]
class image_t(ctypes.Structure):
"""Defines image data and characteristics."""
_fields_ = [("x0", ctypes.c_int),
("y0", ctypes.c_int),
("x1", ctypes.c_int),
("y1", ctypes.c_int),
("numcomps", ctypes.c_int),
("color_space", ctypes.c_int),
("comps", ctypes.POINTER(image_comp_t)),
("icc_profile_buf", ctypes.c_char_p),
("icc_profile_len", ctypes.c_int)]
def _cio_open(cinfo, src):
"""Wrapper for openjpeg library function opj_cio_open."""
argtypes = [ctypes.POINTER(common_struct_t), ctypes.c_char_p, ctypes.c_int]
_OPENJPEG.opj_cio_open.argtypes = argtypes
_OPENJPEG.opj_cio_open.restype = ctypes.POINTER(cio_t)
cio = _OPENJPEG.opj_cio_open(ctypes.cast(cinfo, ctypes.POINTER(common_struct_t)),
src, len(src))
return cio
def _cio_close(cio):
"""Wraps openjpeg library function cio_close.
"""
_OPENJPEG.opj_cio_close.argtypes = [ctypes.POINTER(cio_t)]
_OPENJPEG.opj_cio_close(cio)
def _create_decompress(fmt):
"""Wraps openjpeg library function opj_create_decompress.
"""
_OPENJPEG.opj_create_decompress.argtypes = [ctypes.c_int]
_OPENJPEG.opj_create_decompress.restype = ctypes.POINTER(dinfo_t)
dinfo = _OPENJPEG.opj_create_decompress(fmt)
return dinfo
def _decode(dinfo, cio):
"""Wrapper for opj_decode.
"""
argtypes = [ctypes.POINTER(dinfo_t), ctypes.POINTER(cio_t)]
_OPENJPEG.opj_decode.argtypes = argtypes
_OPENJPEG.opj_decode.restype = ctypes.POINTER(image_t)
image = _OPENJPEG.opj_decode(dinfo, cio)
return image
def _destroy_decompress(dinfo):
"""Wraps openjpeg library function opj_destroy_decompress."""
_OPENJPEG.opj_destroy_decompress.argtypes = [ctypes.POINTER(dinfo_t)]
_OPENJPEG.opj_destroy_decompress(dinfo)
def _image_destroy(image):
"""Wraps openjpeg library function opj_image_destroy."""
_OPENJPEG.opj_image_destroy.argtypes = [ctypes.POINTER(image_t)]
_OPENJPEG.opj_image_destroy(image)
def _set_default_decoder_parameters(dparams_p):
"""Wrapper for opj_set_default_decoder_parameters.
"""
argtypes = [ctypes.POINTER(dparameters_t)]
_OPENJPEG.opj_set_default_decoder_parameters.argtypes = argtypes
_OPENJPEG.opj_set_default_decoder_parameters(dparams_p)
def _set_event_mgr(dinfo, event_mgr, context=None):
"""Wrapper for openjpeg library function opj_set_event_mgr.
"""
argtypes = [ctypes.POINTER(common_struct_t),
ctypes.POINTER(event_mgr_t),
ctypes.c_void_p]
_OPENJPEG.opj_set_event_mgr(ctypes.cast(dinfo,
ctypes.POINTER(common_struct_t)),
event_mgr, context)
def _setup_decoder(dinfo, dparams):
"""Wrapper for openjpeg library function opj_setup_decoder."""
argtypes = [ctypes.POINTER(dinfo_t), ctypes.POINTER(dparameters_t)]
_OPENJPEG.opj_setup_decoder.argtypes = argtypes
_OPENJPEG.opj_setup_decoder(dinfo, dparams)
def _version():
"""Wrapper for opj_version library routine."""
_OPENJPEG.opj_version.restype = ctypes.c_char_p
v = _OPENJPEG.opj_version()
return v.decode('utf-8')

View file

@ -0,0 +1,38 @@
import ctypes
import unittest
import glymur
@unittest.skipIf(glymur.lib.openjpeg._OPENJPEG is None,
"Missing openjpeg library.")
class TestOpenJPEG(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def test_version(self):
v = glymur.lib.openjpeg._version()
parts = v.split('.')
self.assertEqual(parts[0], '1')
self.assertEqual(parts[1], '5')
def test_set_default_decoder_parameters(self):
# Verify that we properly set the default decode parameters.
dp = glymur.lib.openjpeg.dparameters_t()
glymur.lib.openjpeg._set_default_decoder_parameters(ctypes.byref(dp))
self.assertEqual(dp.cp_reduce, 0)
self.assertEqual(dp.cp_layer, 0)
self.assertEqual(dp.infile, b'')
self.assertEqual(dp.outfile, b'')
self.assertEqual(dp.decod_format, -1)
self.assertEqual(dp.cod_format, -1)
self.assertEqual(dp.jpwl_correct, 0)
self.assertEqual(dp.jpwl_exp_comps, 0)
self.assertEqual(dp.jpwl_max_tiles, 0)
self.assertEqual(dp.cp_limit_decoding, 0)
self.assertEqual(dp.flags, 0)

View file

@ -1,5 +1,6 @@
from .test_callbacks import TestCallbacks as callbacks
from .test_codestream import TestCodestream as codestream
from .test_config import TestSuite as config
from .test_jp2k import TestJp2k as jp2k
from .test_icc import TestICC as icc
from .test_printing import TestPrinting as printing

93
glymur/test/fixtures.py Normal file
View file

@ -0,0 +1,93 @@
import re
import sys
import numpy as np
def mse(A, B):
"""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
def peak_tolerance(A, B):
"""Peak Tolerance"""
diff = np.abs(A.astype(np.double) - B.astype(np.double))
p = diff.max()
return p
def read_pgx(pgx_file):
"""Helper function for reading the PGX comparison files.
Open the file in ascii mode and read the header line.
Will look something like
PG ML + 8 128 128
PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d"
"""
header = ''
with open(pgx_file, 'rb') as fp:
while True:
x = fp.read(1)
if x[0] == 10 or x == '\n':
pos = fp.tell()
break
else:
if sys.hexversion < 0x03000000:
header += x
else:
header += chr(x[0])
header = header.rstrip()
n = re.split('\s', header)
if (n[1][0] == 'M') and (sys.byteorder == 'little'):
swapbytes = True
elif (n[1][0] == 'L') and (sys.byteorder == 'big'):
swapbytes = True
else:
swapbytes = False
if (len(n) == 6):
bitdepth = int(n[3])
signed = bitdepth < 0
if signed:
bitdepth = -1 * bitdepth
nrows = int(n[5])
ncols = int(n[4])
else:
bitdepth = int(n[2])
signed = bitdepth < 0
if signed:
bitdepth = -1 * bitdepth
nrows = int(n[4])
ncols = int(n[3])
if signed:
if bitdepth <= 8:
dtype = np.int8
elif bitdepth <= 16:
dtype = np.int16
else:
raise RuntimeError("unhandled bitdepth")
else:
if bitdepth <= 8:
dtype = np.uint8
elif bitdepth <= 16:
dtype = np.uint16
else:
raise RuntimeError("unhandled bitdepth")
shape = [nrows, ncols]
# 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)
return(data.byteswap(swapbytes))

View file

@ -1,5 +1,6 @@
import os
import pkg_resources
import re
import sys
import tempfile
import unittest
@ -21,8 +22,8 @@ class TestCallbacks(unittest.TestCase):
# Save sys.stdout.
self.stdout = sys.stdout
sys.stdout = StringIO()
self.jp2file = pkg_resources.resource_filename(glymur.__name__,
"data/nemo.jp2")
self.jp2file = glymur.data.nemo()
self.j2kfile = glymur.data.goodstuff()
def tearDown(self):
# Restore stdout.
@ -44,24 +45,67 @@ class TestCallbacks(unittest.TestCase):
def test_info_warning_callbacks_on_read(self):
# Verify that we get the expected stdio output when our internal info
# callback handler is enabled.
j = glymur.Jp2k(self.jp2file)
d = j.read(reduce=3, verbose=True, area=(0, 0, 512, 1024))
j = glymur.Jp2k(self.j2kfile)
d = j.read(reduce=1, verbose=True, area=(0, 0, 200, 150))
actual = sys.stdout.getvalue().strip()
lines = ['[INFO] Start to read j2k main header (3135).',
lines = ['[INFO] Start to read j2k main header (0).',
'[INFO] Main header has been correctly decoded.',
'[INFO] Setting decoding area to 0,0,1024,512',
'[INFO] Header of tile 0 / 17 has been read.',
'[INFO] Tile 1/18 has been decoded.',
'[INFO] Image data has been updated with tile 1.',
'[INFO] Header of tile 1 / 17 has been read.',
'[INFO] Tile 2/18 has been decoded.',
'[INFO] Image data has been updated with tile 2.',
'[INFO] Stream reached its end !']
'[INFO] Setting decoding area to 0,0,150,200',
'[INFO] Header of tile 0 / 0 has been read.',
'[INFO] Tile 1/1 has been decoded.',
'[INFO] Image data has been updated with tile 1.']
expected = '\n'.join(lines)
self.assertEqual(actual, expected)
@unittest.skipIf(glymur.lib.openjp2._OPENJPEG is None,
"Missing openjpeg library.")
class TestCallbacks15(unittest.TestCase):
"""This test suite is for OpenJPEG 1.5.1 properties.
"""
@classmethod
def setUpClass(cls):
# Monkey patch the package so as to use OPENJPEG instead of OPENJP2
cls.openjp2 = glymur.lib.openjp2._OPENJP2
glymur.lib.openjp2._OPENJP2 = None
@classmethod
def tearDownClass(cls):
# Restore OPENJP2
glymur.lib.openjp2._OPENJP2 = cls.openjp2
def setUp(self):
# Save sys.stdout.
self.stdout = sys.stdout
sys.stdout = StringIO()
self.jp2file = glymur.data.nemo()
self.j2kfile = glymur.data.goodstuff()
def tearDown(self):
# Restore stdout.
sys.stdout = self.stdout
def test_info_callbacks_on_read(self):
# Verify that we get the expected stdio output when our internal info
# callback handler is enabled.
j = glymur.Jp2k(self.j2kfile)
d = j.read(reduce=1, verbose=True)
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""",
re.VERBOSE)
if sys.hexversion <= 0x03020000:
self.assertRegexpMatches(actual, regex)
else:
self.assertRegex(actual, regex)
if __name__ == "__main__":
unittest.main()

View file

@ -1,3 +1,7 @@
"""These tests are for edge cases where OPENJPEG does not exist, but
OPENJP2 may be present in some form or other.
"""
import imp
import os
import sys
@ -16,14 +20,28 @@ from glymur import Jp2k
from glymur.lib import openjp2 as opj2
@unittest.skip("Cannot work when both OPENJPEG and OPENJP2 are both present.")
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
"Needs openjp2 library first before these tests make sense.")
@unittest.skipIf(sys.hexversion < 0x03020000,
"Uses features introduced in 3.2.")
class TestJp2k(unittest.TestCase):
class TestSuite(unittest.TestCase):
@classmethod
def setUpClass(cls):
# Monkey patch the package so as to ignore OPENJPEG if it exists.
cls.openjpeg = glymur.lib.openjpeg._OPENJPEG
glymur.lib.openjp2._OPENJPEG = None
@classmethod
def tearDownClass(cls):
# Restore OPENJPEG
glymur.lib.openjpeg._OPENJPEG = cls.openjpeg
def setUp(self):
self.jp2file = pkg_resources.resource_filename(glymur.__name__,
"data/nemo.jp2")
imp.reload(glymur)
imp.reload(glymur.lib.openjp2)
self.jp2file = glymur.data.nemo()
def tearDown(self):
imp.reload(glymur)

View file

@ -1,4 +1,5 @@
import doctest
import os
import tempfile
import xml.etree.cElementTree as ET
import unittest
@ -17,6 +18,8 @@ def load_tests(loader, tests, ignore):
return tests
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
"Missing openjp2 library.")
class TestChannelDefinition(unittest.TestCase):
@classmethod
@ -288,6 +291,8 @@ 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",
"Problems using NamedTemporaryFile on windows.")
def test_basic_xml(self):
# Should be able to write an XMLBox.
j2k = Jp2k(self.j2kfile)
@ -308,6 +313,8 @@ class TestXML(unittest.TestCase):
self.assertEqual(ET.tostring(jp2.box[3].xml),
b'<data>0</data>')
@unittest.skipIf(os.name == "nt",
"Problems using NamedTemporaryFile on windows.")
def test_xml_from_file(self):
j2k = Jp2k(self.j2kfile)
@ -352,6 +359,8 @@ class TestColourSpecificationBox(unittest.TestCase):
def tearDown(self):
pass
@unittest.skipIf(os.name == "nt",
"Problems using NamedTemporaryFile on windows.")
def test_color_specification_box_with_out_enumerated_colorspace(self):
j2k = Jp2k(self.j2kfile)

View file

@ -74,10 +74,8 @@ class TestJp2k(unittest.TestCase):
os.unlink(cls._bad_xml_file)
def setUp(self):
self.jp2file = pkg_resources.resource_filename(glymur.__name__,
"data/nemo.jp2")
self.j2kfile = pkg_resources.resource_filename(glymur.__name__,
"data/goodstuff.j2k")
self.jp2file = glymur.data.nemo()
self.j2kfile = glymur.data.goodstuff()
def tearDown(self):
pass
@ -92,11 +90,11 @@ class TestJp2k(unittest.TestCase):
def test_reduce_max(self):
# Verify that reduce=-1 gets us the lowest resolution image
j = Jp2k(self.jp2file)
j = Jp2k(self.j2kfile)
thumbnail1 = j.read(reduce=-1)
thumbnail2 = j.read(reduce=5)
np.testing.assert_array_equal(thumbnail1, thumbnail2)
self.assertEqual(thumbnail1.shape, (46, 81, 3))
self.assertEqual(thumbnail1.shape, (25, 15, 3))
def test_invalid_xml_box(self):
# Should be able to recover from xml box with bad xml.
@ -145,15 +143,6 @@ class TestJp2k(unittest.TestCase):
filename = 'this file does not actually exist on the file system.'
jp2k = Jp2k(filename)
def test_nemo_tile(self):
# Issue 134, trouble reading first nemo tile.
j = Jp2k(self.jp2file)
with warnings.catch_warnings():
warnings.simplefilter("ignore")
tiledata = j.read(tile=0)
subsetdata = j.read(area=(0, 0, 512, 512))
np.testing.assert_array_equal(tiledata, subsetdata)
def test_write_srgb_without_mct(self):
j2k = Jp2k(self.j2kfile)
expdata = j2k.read()
@ -178,7 +167,7 @@ class TestJp2k(unittest.TestCase):
def test_write_cprl(self):
# Issue 17
j = Jp2k(self.jp2file)
expdata = j.read(reduce=2)
expdata = j.read(reduce=1)
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
ofile = Jp2k(tfile.name, 'wb')
ofile.write(expdata, prog='CPRL')
@ -220,7 +209,7 @@ class TestJp2k(unittest.TestCase):
self.assertEqual(jp2k.box[5].id, 'jp2c')
self.assertEqual(jp2k.box[5].offset, 3127)
self.assertEqual(jp2k.box[5].length, 1133427)
self.assertEqual(jp2k.box[5].length, 1132296)
# jp2h super box
self.assertEqual(len(jp2k.box[2].box), 2)
@ -330,7 +319,7 @@ class TestJp2k(unittest.TestCase):
# Issue 86.
filename = os.path.join(data_root, 'input/conformance/p0_05.j2k')
j = Jp2k(filename)
with self.assertRaises(IOError):
with self.assertRaises(RuntimeError):
j.read()
@unittest.skipIf(data_root is None,
@ -540,7 +529,7 @@ class TestJp2k(unittest.TestCase):
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.
data = Jp2k(self.jp2file).read(reduce=3)
data = Jp2k(self.jp2file).read(reduce=1)
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
j = Jp2k(tfile.name, 'wb')
j.write(data)
@ -659,5 +648,66 @@ class TestJp2k(unittest.TestCase):
self.assertFalse('Make' in exif['Image'].keys())
@unittest.skipIf(glymur.lib.openjpeg._OPENJPEG is None,
"Missing openjpeg library.")
class TestJp2k15(unittest.TestCase):
@classmethod
def setUpClass(cls):
# Monkey patch the package so as to use OPENJPEG instead of OPENJP2
cls.openjp2 = glymur.lib.openjp2._OPENJP2
glymur.lib.openjp2._OPENJP2 = None
@classmethod
def tearDownClass(cls):
# Restore OPENJP2
glymur.lib.openjp2._OPENJP2 = cls.openjp2
def setUp(self):
self.jp2file = glymur.data.nemo()
self.j2kfile = glymur.data.goodstuff()
def tearDown(self):
pass
def test_bands(self):
# Reading individual bands is an advanced maneuver.
jp2k = Jp2k(self.j2kfile)
with self.assertRaises(NotImplementedError) as ce:
jpdata = jp2k.read_bands()
def test_area(self):
# 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))
def test_tile(self):
# tile option not allowed for 1.5.1.
j2k = Jp2k(self.j2kfile)
with self.assertRaises(TypeError) as ce:
d = j2k.read(tile=0)
def test_layer(self):
# layer option not allowed for 1.5.1.
j2k = Jp2k(self.j2kfile)
with self.assertRaises(TypeError) as ce:
d = 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.
j2k = Jp2k(self.jp2file)
d = j2k.read(reduce=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.
j2k = Jp2k(self.j2kfile)
d = j2k.read()
if __name__ == "__main__":
unittest.main()

View file

@ -24,6 +24,8 @@ import numpy as np
from glymur import Jp2k
import glymur
from .fixtures import *
try:
data_root = os.environ['OPJ_DATA_ROOT']
except KeyError:
@ -32,94 +34,6 @@ except:
raise
def mse(A, B):
"""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
def peak_tolerance(A, B):
"""Peak Tolerance"""
diff = np.abs(A.astype(np.double) - B.astype(np.double))
p = diff.max()
return p
def read_pgx(pgx_file):
"""Helper function for reading the PGX comparison files.
Open the file in ascii mode and read the header line.
Will look something like
PG ML + 8 128 128
PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d"
"""
header = ''
with open(pgx_file, 'rb') as fp:
while True:
x = fp.read(1)
if x[0] == 10 or x == '\n':
pos = fp.tell()
break
else:
if sys.hexversion < 0x03000000:
header += x
else:
header += chr(x[0])
header = header.rstrip()
n = re.split('\s', header)
if (n[1][0] == 'M') and (sys.byteorder == 'little'):
swapbytes = True
elif (n[1][0] == 'L') and (sys.byteorder == 'big'):
swapbytes = True
else:
swapbytes = False
if (len(n) == 6):
bitdepth = int(n[3])
signed = bitdepth < 0
if signed:
bitdepth = -1 * bitdepth
nrows = int(n[5])
ncols = int(n[4])
else:
bitdepth = int(n[2])
signed = bitdepth < 0
if signed:
bitdepth = -1 * bitdepth
nrows = int(n[4])
ncols = int(n[3])
if signed:
if bitdepth <= 8:
dtype = np.int8
elif bitdepth <= 16:
dtype = np.int16
else:
raise RuntimeError("unhandled bitdepth")
else:
if bitdepth <= 8:
dtype = np.uint8
elif bitdepth <= 16:
dtype = np.uint16
else:
raise RuntimeError("unhandled bitdepth")
shape = [nrows, ncols]
# 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)
return(data.byteswap(swapbytes))
@unittest.skipIf(glymur.lib.openjp2._OPENJP2 is None,
"Missing openjp2 library.")
@unittest.skipIf(data_root is None,
@ -1155,7 +1069,7 @@ class TestSuite(unittest.TestCase):
def test_NR_DEC_file_409752_jp2_40_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/file409752.jp2')
with self.assertRaises(IOError):
with self.assertRaises(RuntimeError):
data = Jp2k(jfile).read()
@unittest.skipIf(sys.hexversion < 0x03020000,
@ -7418,5 +7332,615 @@ class TestSuiteDump(unittest.TestCase):
self.assertEqual(c.segment[3]._exponent,
[8, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10])
@unittest.skipIf(glymur.lib.openjpeg._OPENJPEG is None,
"Missing openjpeg library.")
@unittest.skipIf(data_root is None,
"OPJ_DATA_ROOT environment variable not set")
class TestSuite15(unittest.TestCase):
"""Suite of tests for libopenjpeg 1.5.1"""
@classmethod
def setUpClass(cls):
# Monkey patch the package so as to use OPENJPEG instead of OPENJP2
cls.openjp2 = glymur.lib.openjp2._OPENJP2
glymur.lib.openjp2._OPENJP2 = None
@classmethod
def tearDownClass(cls):
# Restore OPENJP2
glymur.lib.openjp2._OPENJP2 = cls.openjp2
def setUp(self):
pass
def tearDown(self):
pass
def test_ETS_C0P0_p0_01_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_01.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root, 'baseline/conformance/c0p0_01.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata, pgxdata)
def test_ETS_C0P0_p0_02_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_02.j2k')
with warnings.catch_warnings():
# There's a 0xff30 marker segment. Not illegal, but we don't
# really know what to do with it. Just ignore.
warnings.simplefilter("ignore")
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root, 'baseline/conformance/c0p0_02.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata, pgxdata)
def test_ETS_C0P0_p0_09_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_09.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=2)
pgxfile = os.path.join(data_root,
'baseline/conformance/c0p0_09.pgx')
pgxdata = read_pgx(pgxfile)
self.assertTrue(peak_tolerance(jpdata, pgxdata) < 4)
self.assertTrue(mse(jpdata, pgxdata) < 1.47)
def test_ETS_C0P0_p0_11_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_11.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root,
'baseline/conformance/c0p0_11.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata, pgxdata)
@unittest.skip("fprintf stderr output in r2343.")
def test_ETS_C0P0_p0_12_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_12.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root,
'baseline/conformance/c0p0_12.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata, pgxdata)
def test_ETS_C0P0_p0_16_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_16.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root,
'baseline/conformance/c0p0_16.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata, pgxdata)
def test_ETS_C0P1_p1_01_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p1_01.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root,
'baseline/conformance/c0p1_01.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata, pgxdata)
def test_ETS_C1P0_p0_01_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_01.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_01_0.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata, pgxdata)
def test_ETS_C1P0_p0_02_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_02.j2k')
with warnings.catch_warnings():
# There's a 0xff30 marker segment. Not illegal, but we don't
# really know what to do with it. Just ignore.
warnings.simplefilter("ignore")
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_02_0.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata, pgxdata)
def test_ETS_C1P0_p0_03_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_03.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_03_0.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata, pgxdata)
def test_ETS_C1P0_p0_04_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_04.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_04_0.pgx')
pgxdata = read_pgx(pgxfile)
self.assertTrue(peak_tolerance(jpdata[:, :, 0], pgxdata) < 5)
self.assertTrue(mse(jpdata[:, :, 0], pgxdata) < 0.776)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_04_1.pgx')
pgxdata = read_pgx(pgxfile)
self.assertTrue(peak_tolerance(jpdata[:, :, 1], pgxdata) < 4)
self.assertTrue(mse(jpdata[:, :, 1], pgxdata) < 0.626)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_04_2.pgx')
pgxdata = read_pgx(pgxfile)
self.assertTrue(peak_tolerance(jpdata[:, :, 2], pgxdata) < 6)
self.assertTrue(mse(jpdata[:, :, 2], pgxdata) < 1.07)
def test_ETS_C1P0_p0_08_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_08.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=1)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_08_0.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata[:, :, 0], pgxdata)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_08_1.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata[:, :, 1], pgxdata)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_08_2.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata[:, :, 2], pgxdata)
def test_ETS_C1P0_p0_09_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_09.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_09_0.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata, pgxdata)
def test_ETS_C1P0_p0_10_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_10.j2k')
jp2k = Jp2k(jfile)
with warnings.catch_warnings():
# This file has an invalid ICC profile
warnings.simplefilter("ignore")
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_10_0.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata[:, :, 0], pgxdata)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_10_1.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata[:, :, 1], pgxdata)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_10_2.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata[:, :, 2], pgxdata)
def test_ETS_C1P0_p0_11_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_11.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_11_0.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata, pgxdata)
@unittest.skip("fprintf stderr output in r2343.")
def test_ETS_C1P0_p0_12_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_12.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_12_0.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata, pgxdata)
@unittest.skip("fprintf stderr output in r2343.")
def test_ETS_C1P0_p0_13_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_13.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_13_0.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata[:, :, 0], pgxdata)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_13_1.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata[:, :, 1], pgxdata)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_13_2.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata[:, :, 2], pgxdata)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_13_3.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata[:, :, 3], pgxdata)
def test_ETS_C1P0_p0_14_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_14.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_14_0.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata[:, :, 0], pgxdata)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_14_1.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata[:, :, 1], pgxdata)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_14_2.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata[:, :, 2], pgxdata)
def test_ETS_C1P0_p0_15_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_15.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_15_0.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata, pgxdata)
def test_ETS_C1P0_p0_16_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p0_16.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p0_16_0.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata, pgxdata)
def test_ETS_C1P1_p1_01_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p1_01.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p1_01_0.pgx')
pgxdata = read_pgx(pgxfile)
np.testing.assert_array_equal(jpdata, pgxdata)
def test_ETS_C1P1_p1_02_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p1_02.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read(reduce=0)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p1_02_0.pgx')
pgxdata = read_pgx(pgxfile)
self.assertTrue(peak_tolerance(jpdata[:, :, 0], pgxdata) < 5)
self.assertTrue(mse(jpdata[:, :, 0], pgxdata) < 0.765)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p1_02_1.pgx')
pgxdata = read_pgx(pgxfile)
self.assertTrue(peak_tolerance(jpdata[:, :, 1], pgxdata) < 4)
self.assertTrue(mse(jpdata[:, :, 1], pgxdata) < 0.616)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p1_02_2.pgx')
pgxdata = read_pgx(pgxfile)
self.assertTrue(peak_tolerance(jpdata[:, :, 2], pgxdata) < 6)
self.assertTrue(mse(jpdata[:, :, 2], pgxdata) < 1.051)
def test_ETS_C1P1_p1_04_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p1_04.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read()
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p1_04_0.pgx')
pgxdata = read_pgx(pgxfile)
self.assertTrue(peak_tolerance(jpdata, pgxdata) < 624)
self.assertTrue(mse(jpdata, pgxdata) < 3080)
@unittest.skip("fprintf stderr output in r2343.")
def test_ETS_C1P1_p1_05_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p1_05.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read()
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p1_05_0.pgx')
pgxdata = read_pgx(pgxfile)
self.assertTrue(peak_tolerance(jpdata[:, :, 0], pgxdata) < 40)
self.assertTrue(mse(jpdata[:, :, 0], pgxdata) < 8.458)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p1_05_1.pgx')
pgxdata = read_pgx(pgxfile)
self.assertTrue(peak_tolerance(jpdata[:, :, 1], pgxdata) < 40)
self.assertTrue(mse(jpdata[:, :, 1], pgxdata) < 9.816)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p1_05_2.pgx')
pgxdata = read_pgx(pgxfile)
self.assertTrue(peak_tolerance(jpdata[:, :, 2], pgxdata) < 40)
self.assertTrue(mse(jpdata[:, :, 2], pgxdata) < 10.154)
@unittest.skip("fprintf stderr output in r2343.")
def test_ETS_C1P1_p1_06_j2k(self):
jfile = os.path.join(data_root, 'input/conformance/p1_06.j2k')
jp2k = Jp2k(jfile)
jpdata = jp2k.read()
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p1_06_0.pgx')
pgxdata = read_pgx(pgxfile)
self.assertTrue(peak_tolerance(jpdata[:, :, 0], pgxdata) < 2)
self.assertTrue(mse(jpdata[:, :, 0], pgxdata) < 0.6)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p1_06_1.pgx')
pgxdata = read_pgx(pgxfile)
self.assertTrue(peak_tolerance(jpdata[:, :, 1], pgxdata) < 2)
self.assertTrue(mse(jpdata[:, :, 1], pgxdata) < 0.6)
pgxfile = os.path.join(data_root, 'baseline/conformance/c1p1_06_2.pgx')
pgxdata = read_pgx(pgxfile)
self.assertTrue(peak_tolerance(jpdata[:, :, 2], pgxdata) < 2)
self.assertTrue(mse(jpdata[:, :, 2], pgxdata) < 0.6)
def test_ETS_JP2_file1(self):
jfile = os.path.join(data_root, 'input/conformance/file1.jp2')
jp2k = Jp2k(jfile)
jpdata = jp2k.read()
self.assertEqual(jpdata.shape, (512, 768, 3))
def test_ETS_JP2_file2(self):
jfile = os.path.join(data_root, 'input/conformance/file2.jp2')
jp2k = Jp2k(jfile)
jpdata = jp2k.read()
self.assertEqual(jpdata.shape, (640, 480, 3))
def test_ETS_JP2_file4(self):
jfile = os.path.join(data_root, 'input/conformance/file4.jp2')
jp2k = Jp2k(jfile)
jpdata = jp2k.read()
self.assertEqual(jpdata.shape, (512, 768))
def test_ETS_JP2_file5(self):
jfile = os.path.join(data_root, 'input/conformance/file5.jp2')
jp2k = Jp2k(jfile)
jpdata = jp2k.read()
self.assertEqual(jpdata.shape, (512, 768, 3))
def test_ETS_JP2_file6(self):
jfile = os.path.join(data_root, 'input/conformance/file6.jp2')
jp2k = Jp2k(jfile)
jpdata = jp2k.read()
self.assertEqual(jpdata.shape, (512, 768))
def test_ETS_JP2_file7(self):
jfile = os.path.join(data_root, 'input/conformance/file7.jp2')
jp2k = Jp2k(jfile)
jpdata = jp2k.read()
self.assertEqual(jpdata.shape, (640, 480, 3))
def test_ETS_JP2_file8(self):
jfile = os.path.join(data_root, 'input/conformance/file8.jp2')
jp2k = Jp2k(jfile)
jpdata = jp2k.read()
self.assertEqual(jpdata.shape, (400, 700))
def test_ETS_JP2_file9(self):
jfile = os.path.join(data_root, 'input/conformance/file9.jp2')
jp2k = Jp2k(jfile)
jpdata = jp2k.read()
self.assertEqual(jpdata.shape, (512, 768, 3))
def test_NR_DEC_Bretagne2_j2k_1_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/Bretagne2.j2k')
jp2 = Jp2k(jfile)
data = jp2.read()
self.assertTrue(True)
def test_NR_DEC__00042_j2k_2_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/_00042.j2k')
jp2 = Jp2k(jfile)
data = jp2.read()
self.assertTrue(True)
@unittest.skip("fprintf stderr output in r2343.")
def test_NR_DEC_123_j2c_3_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/123.j2c')
jp2 = Jp2k(jfile)
data = jp2.read()
self.assertTrue(True)
@unittest.skipIf(sys.hexversion < 0x03020000,
"Uses features introduced in 3.2.")
def test_NR_DEC_broken_jp2_4_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/broken.jp2')
with self.assertWarns(UserWarning) as cw:
# colr box has bad length.
jp2 = Jp2k(jfile)
with self.assertRaises(ValueError):
data = jp2.read()
self.assertTrue(True)
def test_NR_DEC_broken2_jp2_5_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/broken2.jp2')
with self.assertRaises(IOError):
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):
jfile = os.path.join(data_root,
'input/nonregression/broken3.jp2')
with self.assertWarns(UserWarning) as cw:
# colr box has bad length.
j = Jp2k(jfile)
with self.assertRaises(ValueError) as ce:
d = j.read()
def test_NR_DEC_broken4_jp2_7_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/broken4.jp2')
with self.assertRaises(IOError):
data = Jp2k(jfile).read()
self.assertTrue(True)
@unittest.skip("fprintf stderr output in r2343.")
def test_NR_DEC_bug_j2c_8_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/bug.j2c')
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_buxI_j2k_9_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/buxI.j2k')
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_buxR_j2k_10_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/buxR.j2k')
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_Cannotreaddatawithnosizeknown_j2k_11_decode(self):
relpath = 'input/nonregression/Cannotreaddatawithnosizeknown.j2k'
jfile = os.path.join(data_root, relpath)
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_cthead1_j2k_12_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/cthead1.j2k')
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_CT_Phillips_JPEG2K_Decompr_Problem_j2k_13_decode(self):
relpath = 'input/nonregression/CT_Phillips_JPEG2K_Decompr_Problem.j2k'
jfile = os.path.join(data_root, relpath)
data = Jp2k(jfile).read()
self.assertTrue(True)
@unittest.skip("fprintf stderr output in r2343.")
def test_NR_DEC_illegalcolortransform_j2k_14_decode(self):
# Stream too short, expected SOT.
jfile = os.path.join(data_root,
'input/nonregression/illegalcolortransform.j2k')
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_j2k32_j2k_15_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/j2k32.j2k')
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_kakadu_v4_4_openjpegv2_broken_j2k_16_decode(self):
relpath = 'input/nonregression/kakadu_v4-4_openjpegv2_broken.j2k'
jfile = os.path.join(data_root, relpath)
with warnings.catch_warnings():
# This file has an invalid ICC profile
warnings.simplefilter("ignore")
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_MarkerIsNotCompliant_j2k_17_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/MarkerIsNotCompliant.j2k')
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_Marrin_jp2_18_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/Marrin.jp2')
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_movie_00000_j2k_20_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/movie_00000.j2k')
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_movie_00001_j2k_21_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/movie_00001.j2k')
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_movie_00002_j2k_22_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/movie_00002.j2k')
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_orb_blue_lin_j2k_j2k_23_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/orb-blue10-lin-j2k.j2k')
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_orb_blue_win_j2k_j2k_24_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/orb-blue10-win-j2k.j2k')
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_orb_blue_lin_jp2_25_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/orb-blue10-lin-jp2.jp2')
with warnings.catch_warnings():
# This file has an invalid ICC profile
warnings.simplefilter("ignore")
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_orb_blue_win_jp2_26_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/orb-blue10-win-jp2.jp2')
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_relax_jp2_27_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/relax.jp2')
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_test_lossless_j2k_28_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/test_lossless.j2k')
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_issue104_jpxstream_jp2_33_decode(self):
jfile = os.path.join(data_root,
'input/nonregression/issue104_jpxstream.jp2')
data = Jp2k(jfile).read()
self.assertTrue(True)
def test_NR_DEC_file_409752_jp2_40_decode(self):
jfile = os.path.join(data_root, 'input/nonregression/file409752.jp2')
j = Jp2k(jfile)
with self.assertRaises(RuntimeError) as ce:
data = j.read()
if __name__ == "__main__":
unittest.main()

View file

@ -65,8 +65,8 @@ def read_image(infile):
class TestSuiteNegative(unittest.TestCase):
def setUp(self):
self.jp2file = pkg_resources.resource_filename(glymur.__name__,
"data/nemo.jp2")
self.jp2file = glymur.data.nemo()
self.j2kfile = glymur.data.goodstuff()
def tearDown(self):
pass
@ -156,8 +156,8 @@ class TestSuiteNegative(unittest.TestCase):
def test_precinct_size_not_multiple_of_two(self):
# Seems like precinct sizes should be powers of two.
ifile = Jp2k(self.jp2file)
data = ifile.read(reduce=3)
ifile = Jp2k(self.j2kfile)
data = ifile.read(reduce=2)
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
ofile = Jp2k(tfile.name, 'wb')
with self.assertRaises(IOError) as ce:
@ -165,8 +165,8 @@ class TestSuiteNegative(unittest.TestCase):
def test_codeblock_size_not_multiple_of_two(self):
# Seems like code block sizes should be powers of two.
ifile = Jp2k(self.jp2file)
data = ifile.read(reduce=3)
ifile = Jp2k(self.j2kfile)
data = ifile.read(reduce=2)
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
ofile = Jp2k(tfile.name, 'wb')
with self.assertRaises(IOError) as ce:
@ -175,8 +175,8 @@ class TestSuiteNegative(unittest.TestCase):
def test_codeblock_size_with_precinct_size(self):
# Seems like code block sizes should never exceed half that of
# precinct size.
ifile = Jp2k(self.jp2file)
data = ifile.read(reduce=3)
ifile = Jp2k(self.j2kfile)
data = ifile.read(reduce=2)
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
ofile = Jp2k(tfile.name, 'wb')
with self.assertRaises(IOError) as ce:

View file

@ -34,7 +34,7 @@ class TestPrintingNeedsLib(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix='.jp2', delete=False) as tfile:
cls._plain_nemo_file = tfile.name
ijfile = Jp2k(jp2file)
data = ijfile.read(reduce=3)
data = ijfile.read(reduce=1)
ojfile = Jp2k(cls._plain_nemo_file, 'wb')
ojfile.write(data)
@ -43,8 +43,9 @@ class TestPrintingNeedsLib(unittest.TestCase):
os.unlink(cls._plain_nemo_file)
def setUp(self):
self.jp2file = pkg_resources.resource_filename(glymur.__name__,
"data/nemo.jp2")
self.jp2file = glymur.data.nemo()
self.j2kfile = glymur.data.goodstuff()
# Save sys.stdout.
self.stdout = sys.stdout
sys.stdout = StringIO()
@ -57,7 +58,7 @@ class TestPrintingNeedsLib(unittest.TestCase):
" Compatibility: ['jp2 ']",
'JP2 Header Box (jp2h) @ (32, 45)',
' Image Header Box (ihdr) @ (40, 22)',
' Size: [182 324 3]',
' Size: [728 1296 3]',
' Bitdepth: 8',
' Signed: False',
' Compression: wavelet',
@ -66,15 +67,15 @@ class TestPrintingNeedsLib(unittest.TestCase):
' Method: enumerated colorspace',
' Precedence: 0',
' Colorspace: sRGB',
'Contiguous Codestream Box (jp2c) @ (77, 112814)',
'Contiguous Codestream Box (jp2c) @ (77, 1632355)',
' Main header:',
' SOC marker segment @ (85, 0)',
' SIZ marker segment @ (87, 47)',
' Profile: 2',
' Reference Grid Height, Width: (182 x 324)',
' Reference Grid Height, Width: (728 x 1296)',
' Vertical, Horizontal Reference Grid Offset: '
+ '(0 x 0)',
' Reference Tile Height, Width: (182 x 324)',
' Reference Tile Height, Width: (728 x 1296)',
' Vertical, Horizontal Reference Tile Offset: '
+ '(0 x 0)',
' Bitdepth: (8, 8, 8)',
@ -121,7 +122,7 @@ class TestPrintingNeedsLib(unittest.TestCase):
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.
data = glymur.Jp2k(self.jp2file).read(reduce=3)
data = glymur.Jp2k(self.jp2file).read(reduce=1)
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
j = glymur.Jp2k(tfile.name, 'wb')
j.write(data)
@ -177,7 +178,7 @@ class TestPrintingNeedsLib(unittest.TestCase):
lst = actual.split('\n')
lst = lst[1:]
actual = '\n'.join(lst)
self.maxDiff = None
self.assertEqual(actual, self.expectedPlain)
def test_entire_file(self):
@ -209,15 +210,15 @@ class TestPrinting(unittest.TestCase):
def test_COC_segment(self):
j = glymur.Jp2k(self.jp2file)
codestream = j.get_codestream(header_only=False)
print(codestream.segment[5])
print(codestream.segment[6])
actual = sys.stdout.getvalue().strip()
lines = ['COC marker segment @ (3233, 9)',
lines = ['COC marker segment @ (3260, 9)',
' Associated component: 1',
' Coding style for this component: '
+ 'Entropy coder, PARTITION = 0',
' Coding style parameters:',
' Number of resolutions: 6',
' Number of resolutions: 2',
' Code block height, width: (64 x 64)',
' Wavelet transform: 5-3 reversible',
' Code block context:',
@ -230,6 +231,7 @@ class TestPrinting(unittest.TestCase):
' Segmentation symbols: False']
expected = '\n'.join(lines)
self.maxDiff = None
self.assertEqual(actual, expected)
def test_COD_segment(self):
@ -245,10 +247,10 @@ class TestPrinting(unittest.TestCase):
' EPH marker segments: False',
' Coding style parameters:',
' Progression order: LRCP',
' Number of layers: 3',
' Number of layers: 2',
' Multiple component transformation usage: '
+ 'reversible',
' Number of resolutions: 6',
' Number of resolutions: 2',
' Code block height, width: (64 x 64)',
' Wavelet transform: 5-3 reversible',
' Precinct size: default, 2^15 x 2^15',
@ -392,7 +394,7 @@ class TestPrinting(unittest.TestCase):
print(codestream.segment[-1])
actual = sys.stdout.getvalue().strip()
lines = ['EOC marker segment @ (1136552, 0)']
lines = ['EOC marker segment @ (1135421, 0)']
expected = '\n'.join(lines)
self.assertEqual(actual, expected)
@ -476,15 +478,13 @@ class TestPrinting(unittest.TestCase):
def test_QCC_segment(self):
j = glymur.Jp2k(self.jp2file)
codestream = j.get_codestream(header_only=False)
print(codestream.segment[6])
print(codestream.segment[7])
actual = sys.stdout.getvalue().strip()
lines = ['QCC marker segment @ (3244, 20)',
lines = ['QCC marker segment @ (3271, 8)',
' Associated Component: 1',
' Quantization style: no quantization, 2 guard bits',
' Step size: [(0, 8), (0, 9), (0, 9), (0, 10), (0, 9), '
+ '(0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), '
+ '(0, 10), (0, 9), (0, 9), (0, 10)]']
' Step size: [(0, 8), (0, 9), (0, 9), (0, 10)]']
expected = '\n'.join(lines)
self.assertEqual(actual, expected)
@ -495,11 +495,9 @@ class TestPrinting(unittest.TestCase):
print(codestream.segment[3])
actual = sys.stdout.getvalue().strip()
lines = ['QCD marker segment @ (3200, 19)',
lines = ['QCD marker segment @ (3200, 7)',
' Quantization style: no quantization, 2 guard bits',
' Step size: [(0, 8), (0, 9), (0, 9), (0, 10), (0, 9), '
+ '(0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), '
+ '(0, 9), (0, 10), (0, 9), (0, 9), (0, 10)]']
' Step size: [(0, 8), (0, 9), (0, 9), (0, 10)]']
expected = '\n'.join(lines)
self.assertEqual(actual, expected)
@ -514,7 +512,7 @@ class TestPrinting(unittest.TestCase):
' Profile: 2',
' Reference Grid Height, Width: (1456 x 2592)',
' Vertical, Horizontal Reference Grid Offset: (0 x 0)',
' Reference Tile Height, Width: (512 x 512)',
' Reference Tile Height, Width: (1456 x 2592)',
' Vertical, Horizontal Reference Tile Offset: (0 x 0)',
' Bitdepth: (8, 8, 8)',
' Signed: (False, False, False)',
@ -537,26 +535,27 @@ class TestPrinting(unittest.TestCase):
def test_SOD_segment(self):
j = glymur.Jp2k(self.jp2file)
codestream = j.get_codestream(header_only=False)
print(codestream.segment[9])
print(codestream.segment[10])
actual = sys.stdout.getvalue().strip()
lines = ['SOD marker segment @ (3299, 0)']
lines = ['SOD marker segment @ (3302, 0)']
expected = '\n'.join(lines)
self.assertEqual(actual, expected)
def test_SOT_segment(self):
j = glymur.Jp2k(self.jp2file)
codestream = j.get_codestream(header_only=False)
print(codestream.segment[4])
print(codestream.segment[5])
actual = sys.stdout.getvalue().strip()
lines = ['SOT marker segment @ (3221, 10)',
lines = ['SOT marker segment @ (3248, 10)',
' Tile part index: 0',
' Tile part length: 78629',
' Tile part length: 1132173',
' Tile part instance: 0',
' Number of tile parts: 1']
expected = '\n'.join(lines)
self.maxDiff = None
self.assertEqual(actual, expected)
@unittest.skipIf(data_root is None,
@ -606,7 +605,7 @@ class TestPrinting(unittest.TestCase):
' Profile: 2',
' Reference Grid Height, Width: (1456 x 2592)',
' Vertical, Horizontal Reference Grid Offset: (0 x 0)',
' Reference Tile Height, Width: (512 x 512)',
' Reference Tile Height, Width: (1456 x 2592)',
' Vertical, Horizontal Reference Tile Offset: (0 x 0)',
' Bitdepth: (8, 8, 8)',
' Signed: (False, False, False)',
@ -619,10 +618,10 @@ class TestPrinting(unittest.TestCase):
' EPH marker segments: False',
' Coding style parameters:',
' Progression order: LRCP',
' Number of layers: 3',
' Number of layers: 2',
' Multiple component transformation usage: '
+ 'reversible',
' Number of resolutions: 6',
' Number of resolutions: 2',
' Code block height, width: (64 x 64)',
' Wavelet transform: 5-3 reversible',
' Precinct size: default, 2^15 x 2^15',
@ -634,13 +633,12 @@ class TestPrinting(unittest.TestCase):
' Vertically stripe causal context: False',
' Predictable termination: False',
' Segmentation symbols: False',
' QCD marker segment @ (3200, 19)',
' QCD marker segment @ (3200, 7)',
' Quantization style: no quantization, '
+ '2 guard bits',
' Step size: [(0, 8), (0, 9), (0, 9), '
+ '(0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), '
+ '(0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), '
+ '(0, 10)]']
' Step size: [(0, 8), (0, 9), (0, 9), (0, 10)]',
' CME marker segment @ (3209, 37)',
' "Created by OpenJPEG version 2.0.0"']
expected = '\n'.join(lst)
self.assertEqual(actual, expected)
@ -783,6 +781,8 @@ class TestPrinting(unittest.TestCase):
expected = '\n'.join(lines)
self.assertEqual(actual, expected)
@unittest.skipIf(os.name == "nt",
"Problems using NamedTemporaryFile on windows.")
def test_less_common_boxes(self):
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
with open(self.jp2file, 'rb') as ifile:

22
release.txt Normal file
View file

@ -0,0 +1,22 @@
| 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. |
+------------+------------+------------+----------------------------------+