Merge branch 'release-0.2.3'
This commit is contained in:
commit
85df7f615d
27 changed files with 623 additions and 378 deletions
|
|
@ -1,3 +1,6 @@
|
||||||
|
Jul 18, 2013 - v0.2.3 Support for Python 2.6, OpenJPEG 1.4. Incompatible
|
||||||
|
change to ChannelDefinitionBox constructor. Added RGBA example.
|
||||||
|
|
||||||
Jul 11, 2013 - v0.2.2 Fixed mistakes with trove classifier, pypi releases.
|
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.
|
Jul 11, 2013 - v0.2.0 Support for Python 2.7 on windows, OpenJPEG 1.5.1.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ glymur: a Python interface for JPEG 2000
|
||||||
|
|
||||||
**glymur** contains a Python interface to the OpenJPEG library
|
**glymur** contains a Python interface to the OpenJPEG library
|
||||||
which allows linux and mac users to read and write JPEG 2000 files.
|
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.
|
**glymur** works on Python 2.6, 2.7 and 3.3. Python 3.3 is strongly
|
||||||
|
recommended.
|
||||||
|
|
||||||
Please read the docs, https://glymur.readthedocs.org/en/latest/
|
Please read the docs, https://glymur.readthedocs.org/en/latest/
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ copyright = u'2013, John Evans'
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = '0.1'
|
version = '0.1'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = '0.2.2'
|
release = '0.2.3'
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ Glymur Configuration
|
||||||
''''''''''''''''''''''
|
''''''''''''''''''''''
|
||||||
|
|
||||||
The default glymur installation process relies upon OpenJPEG version
|
The default glymur installation process relies upon OpenJPEG version
|
||||||
1.5.1 being properly installed on your system. This will, however, only
|
1.X being properly installed on your system. This will, however, only
|
||||||
give you you basic read capabilities, so if you wish to take advantage
|
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
|
of more of glymur's features, you should compile OpenJPEG as a shared
|
||||||
library (named *openjp2* instead of *openjpeg*) from the developmental
|
library (named *openjp2* instead of *openjpeg*) from the developmental
|
||||||
|
|
@ -23,21 +23,18 @@ environment variable for the purpose of running Glymur's test suite. ::
|
||||||
Glymur uses ctypes (for the moment) to access the openjp2 library, and
|
Glymur uses ctypes (for the moment) to access the openjp2 library, and
|
||||||
because ctypes access libraries in a platform-dependent manner, it is
|
because ctypes access libraries in a platform-dependent manner, it is
|
||||||
recommended that you create a configuration file to help Glymur properly find
|
recommended that you create a configuration file to help Glymur properly find
|
||||||
the openjp2 library. You may create the configuration file as follows::
|
the openjp2 library. The configuration format is the same as used by Python's
|
||||||
|
configparser module, i.e. ::
|
||||||
|
|
||||||
$ mkdir -p ~/.config/glymur
|
[library]
|
||||||
$ cd ~/.config/glymur
|
openjp2: /opt/openjp2-svn/lib/libopenjp2.so
|
||||||
$ cat > glymurrc << EOF
|
|
||||||
> [library]
|
|
||||||
> openjp2: /opt/openjp2-svn/lib/libopenjp2.so
|
|
||||||
> EOF
|
|
||||||
|
|
||||||
This 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
|
/opt/openjp2-svn on a linux system. You may also substitute
|
||||||
**$XDG_CONFIG_HOME** for **$HOME/.config**.
|
**$XDG_CONFIG_HOME** for **$HOME/.config**.
|
||||||
|
|
||||||
You may also include a line for the version 1.5.1 library if you have it installed
|
You may also include a line for the version 1.x openjpeg library if you have it
|
||||||
in a non-standard place, i.e. ::
|
installed in a non-standard place, i.e. ::
|
||||||
|
|
||||||
[library]
|
[library]
|
||||||
openjp2: /opt/openjp2-svn/lib/libopenjp2.so
|
openjp2: /opt/openjp2-svn/lib/libopenjp2.so
|
||||||
|
|
@ -56,17 +53,13 @@ packages/RPMs/ports/whatever without going through pip.
|
||||||
Mac OS X
|
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
|
MacPorts. You should install the following set of ports:
|
||||||
|
|
||||||
* python33
|
* python33
|
||||||
* py33-numpy
|
* py33-numpy
|
||||||
* py33-distribute
|
* py33-distribute
|
||||||
|
* py33-matplotlib (optional, for running certain tests)
|
||||||
To run all the testing, one of the following combinations of ports must
|
* py33-Pillow (optional, for running certain tests)
|
||||||
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
|
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+
|
mentioned, the 2.0.0 official release is not supported (although the 2.0+
|
||||||
|
|
@ -95,18 +88,15 @@ meet the minimal set of requirements for running glymur.
|
||||||
* python3
|
* python3
|
||||||
* python3-numpy
|
* python3-numpy
|
||||||
* python3-setuptools
|
* python3-setuptools
|
||||||
* python3-matplotlib (for running tests)
|
|
||||||
|
For running the maximal number of tests, you also need
|
||||||
|
|
||||||
|
* python3-matplotlib
|
||||||
* python3-matplotlib-tk (or whichever matplotlib backend you prefer)
|
* python3-matplotlib-tk (or whichever matplotlib backend you prefer)
|
||||||
|
|
||||||
A few tests still will not run, however, unless one of the following
|
Pillow is also needed in order to run the maximum number of tests, so
|
||||||
combinations of RPMs / Python packages is installed.
|
go ahead and install Pillow via pip since Pillow is not available
|
||||||
|
in Fedora 18 default repositories::
|
||||||
* 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
|
|
||||||
repositories::
|
|
||||||
|
|
||||||
$ yum install python3-devel # pip needs this in order to compile Pillow
|
$ yum install python3-devel # pip needs this in order to compile Pillow
|
||||||
$ yum install python3-pip
|
$ yum install python3-pip
|
||||||
|
|
@ -115,33 +105,20 @@ repositories::
|
||||||
|
|
||||||
Fedora 17
|
Fedora 17
|
||||||
'''''''''
|
'''''''''
|
||||||
Fedora 17 ships with Python 3.2 and 2.7, but OpenJPEG is only at version 1.4,
|
Fedora 17 ships with Python 2.7 and OpenJPEG 1.4. You should have the
|
||||||
so these steps detail working with Python 2.7 and the svn version of OpenJPEG.
|
following RPMs installed.
|
||||||
|
|
||||||
Required RPMs include::
|
|
||||||
|
|
||||||
* python
|
* python
|
||||||
* python-mock
|
* python-mock
|
||||||
* python-pip
|
* python-pip
|
||||||
* python-setuptools
|
* python-setuptools
|
||||||
* numpy
|
* numpy
|
||||||
|
* matplotlib (optional)
|
||||||
|
|
||||||
In addition, you must install contextlib2 via pip.
|
In addition, you must install contextlib2 and Pillow via pip.
|
||||||
|
|
||||||
A few tests still will not run, however, unless one of the following
|
$ yum install python-devel # pip needs this in order to compile Pillow
|
||||||
combinations of RPMs / Python packages is installed.
|
$ pip-python install Pillow --user
|
||||||
|
|
||||||
* scikit-image and either Pillow or freeimage
|
|
||||||
* matplotlib and Pillow
|
|
||||||
|
|
||||||
scikit-image was not available in the Fedora 17 default repositories, but
|
|
||||||
it was installable 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
|
|
||||||
$ yum install freeimage # scikit-image uses this as a backend
|
|
||||||
$ yum install scipy # needed by scikit-image
|
|
||||||
$ pip-python install scikit-image --user
|
|
||||||
$ pip-python install contextlib2 --user
|
$ pip-python install contextlib2 --user
|
||||||
$ export PYTHONPATH=$HOME/.local/lib/python2.7/site-packages:$PYTHONPATH
|
$ export PYTHONPATH=$HOME/.local/lib/python2.7/site-packages:$PYTHONPATH
|
||||||
|
|
||||||
|
|
|
||||||
BIN
docs/source/goodstuff_alpha.png
Normal file
BIN
docs/source/goodstuff_alpha.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 480 KiB |
|
|
@ -38,8 +38,8 @@ Add XML Metadata?
|
||||||
=================
|
=================
|
||||||
An existing raw codestream (or JP2 file) can be wrapped (re-wrapped) in a
|
An existing raw codestream (or JP2 file) can be wrapped (re-wrapped) in a
|
||||||
user-defined set of JP2 boxes. To get just a minimal JP2 jacket on the
|
user-defined set of JP2 boxes. To get just a minimal JP2 jacket on the
|
||||||
codestream provided by `goodstuff.j2k`, you can use the **wrap** method with
|
codestream provided by `goodstuff.j2k` (a file consisting of a raw codestream),
|
||||||
no box argument: ::
|
you can use the **wrap** method with no box argument: ::
|
||||||
|
|
||||||
>>> import glymur
|
>>> import glymur
|
||||||
>>> jfile = glymur.data.goodstuff()
|
>>> jfile = glymur.data.goodstuff()
|
||||||
|
|
@ -119,6 +119,68 @@ and add it after the JP2 header box, but before the codestream box ::
|
||||||
. (truncated)
|
. (truncated)
|
||||||
.
|
.
|
||||||
|
|
||||||
|
Create an image with an alpha layer?
|
||||||
|
====================================
|
||||||
|
|
||||||
|
OpenJPEG can create JP2 files with more than 3 components, but by default, any
|
||||||
|
extra components are not described as such. In order to do so,
|
||||||
|
we need to rewrap such an image in a set of boxes that includes a channel
|
||||||
|
definition box.
|
||||||
|
|
||||||
|
This example is based on SciPy example code found at
|
||||||
|
http://scipy-lectures.github.io/advanced/image_processing/#basic-manipulations .
|
||||||
|
Instead of a circular mask, however, we'll make it an ellipse since the source
|
||||||
|
image isn't square.
|
||||||
|
|
||||||
|
>>> import numpy as np
|
||||||
|
>>> import glymur
|
||||||
|
>>> from glymur import Jp2k
|
||||||
|
>>> rgb = Jp2k(glymur.data.goodstuff()).read()
|
||||||
|
>>> lx, ly = rgb.shape[0:2]
|
||||||
|
>>> X, Y = np.ogrid[0:lx, 0:ly]
|
||||||
|
>>> mask = ly**2*(X - lx / 2) ** 2 + lx**2*(Y - ly / 2) ** 2 > (lx * ly / 2)**2
|
||||||
|
>>> alpha = 255 * np.ones((lx, ly, 1), dtype=np.uint8)
|
||||||
|
>>> alpha[mask] = 0
|
||||||
|
>>> rgba = np.concatenate((rgb, alpha), axis=2)
|
||||||
|
>>> jp2 = Jp2k('tmp.jp2', 'wb')
|
||||||
|
>>> jp2.write(rgba)
|
||||||
|
|
||||||
|
Next we need to specify what types of channels we have.
|
||||||
|
The first three channels are color channels, but we identify the fourth as
|
||||||
|
an alpha channel::
|
||||||
|
|
||||||
|
>>> from glymur.core import COLOR, OPACITY
|
||||||
|
>>> ctype = [COLOR, COLOR, COLOR, OPACITY]
|
||||||
|
|
||||||
|
And finally we have to specify just exactly how each channel is to be
|
||||||
|
interpreted. The color channels are straightforward, they correspond to R-G-B,
|
||||||
|
but the alpha (or opacity) channel in this case is to be applied against the
|
||||||
|
entire image (it is possible to apply an alpha channel to a single color
|
||||||
|
channel, but we aren't doing that). ::
|
||||||
|
|
||||||
|
>>> from glymur.core import RED, GREEN, BLUE, WHOLE_IMAGE
|
||||||
|
>>> asoc = [RED, GREEN, BLUE, WHOLE_IMAGE]
|
||||||
|
>>> cdef = glymur.jp2box.ChannelDefinitionBox(channel_type=ctype, association=asoc)
|
||||||
|
>>> print(cdef)
|
||||||
|
Channel Definition Box (cdef) @ (0, 0)
|
||||||
|
Channel 0 (color) ==> (1)
|
||||||
|
Channel 1 (color) ==> (2)
|
||||||
|
Channel 2 (color) ==> (3)
|
||||||
|
Channel 3 (opacity) ==> (whole image)
|
||||||
|
|
||||||
|
It's easiest to take the existing jp2 jacket and just add the channel
|
||||||
|
definition box in the appropriate spot. The channel definition box **must**
|
||||||
|
go into the jp2 header box, and then we can rewrap the image. ::
|
||||||
|
|
||||||
|
>>> boxes = jp2.box # The box attribute is the list of JP2 boxes
|
||||||
|
>>> boxes[2].box.append(cdef)
|
||||||
|
>>> jp2_rgba = jp2.wrap("goodstuff_rgba.jp2", boxes=boxes)
|
||||||
|
|
||||||
|
Here's how the Preview application on the mac shows the RGBA image.
|
||||||
|
|
||||||
|
.. image:: goodstuff_alpha.png
|
||||||
|
|
||||||
|
|
||||||
Work with XMP UUIDs?
|
Work with XMP UUIDs?
|
||||||
====================
|
====================
|
||||||
The example JP2 file shipped with glymur has an XMP UUID. ::
|
The example JP2 file shipped with glymur has an XMP UUID. ::
|
||||||
|
|
|
||||||
|
|
@ -14,22 +14,23 @@ some very limited support for reading JPX metadata. For instance,
|
||||||
**asoc** and **labl** boxes are recognized, so GMLJP2 metadata can
|
**asoc** and **labl** boxes are recognized, so GMLJP2 metadata can
|
||||||
be retrieved from such JPX files.
|
be retrieved from such JPX files.
|
||||||
|
|
||||||
Glymur works on Python 2.7 and 3.3. Python 3.3 is strongly recommended.
|
Glymur works on Python 2.6, 2.7, and 3.3. Python 3.3 is strongly recommended.
|
||||||
|
|
||||||
OpenJPEG Installation
|
OpenJPEG Installation
|
||||||
=====================
|
=====================
|
||||||
The OpenJPEG library version must be either 1.5.1 or the trunk/development
|
OpenJPEG should be version 1.4, 1.5, or the trunk/development
|
||||||
version of OpenJPEG. Version 2.0.0 or versions earlier than 1.5.0
|
version of OpenJPEG. The official 2.0.0 release or versions earlier than 1.3.0
|
||||||
are not supported. Furthermore, the 1.5.x version of OpenJPEG is
|
are not supported. Furthermore, the 1.X versions of OpenJPEG are
|
||||||
currently only utilized for read-only purposes. For more information
|
currently only utilized for read-only purposes. In order to write JPEG 2000
|
||||||
|
images, you must compile the the trunk/development version. For more information
|
||||||
about OpenJPEG, please consult http://www.openjpeg.org.
|
about OpenJPEG, please consult http://www.openjpeg.org.
|
||||||
|
|
||||||
If you use MacPorts on the mac or if you have a sufficiently recent version of
|
If you use MacPorts on the mac or if you have a sufficiently recent
|
||||||
Linux, your package manager should already provide you with at least version
|
version of Linux, your package manager should already provide you
|
||||||
1.5.1 of OpenJPEG, which means that glymur can be installed ready to read JPEG
|
with a version of OpenJPEG 1.X with which glymur can already use
|
||||||
2000 images. If you use windows, I suggest using the 1.5.1 windows installer
|
for read-only purposes. If your platform is windows, I suggest
|
||||||
provided to you by the OpenJPEG folks at
|
using the 1.5.1 windows installer provided to you by the OpenJPEG
|
||||||
https://code.google.com/p/openjpeg/downloads/list .
|
folks at https://code.google.com/p/openjpeg/downloads/list .
|
||||||
|
|
||||||
Glymur Installation
|
Glymur Installation
|
||||||
===================
|
===================
|
||||||
|
|
@ -56,5 +57,5 @@ You can run the tests from within python as follows::
|
||||||
>>> glymur.runtests()
|
>>> glymur.runtests()
|
||||||
|
|
||||||
Many tests are currently skipped; in fact most of them are skipped if you
|
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, though, is whether or
|
are relying on OpenJPEG 1.4 or 1.5. The important thing, though, is whether or
|
||||||
not any tests fail.
|
not any tests fail.
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,20 @@
|
||||||
"""glymur - read, write, and interrogate JPEG 2000 files
|
"""glymur - read, write, and interrogate JPEG 2000 files
|
||||||
"""
|
"""
|
||||||
|
import sys
|
||||||
|
|
||||||
from .jp2k import Jp2k
|
from .jp2k import Jp2k
|
||||||
from .jp2dump import jp2dump
|
from .jp2dump import jp2dump
|
||||||
|
|
||||||
from . import data
|
from . import data
|
||||||
from . import test
|
#from . import test
|
||||||
|
|
||||||
|
|
||||||
def runtests():
|
def runtests():
|
||||||
"""Discover and run all tests for the glymur package.
|
"""Discover and run all tests for the glymur package.
|
||||||
"""
|
"""
|
||||||
import unittest
|
if sys.hexversion <= 0x02070000:
|
||||||
|
import unittest2 as unittest
|
||||||
|
else:
|
||||||
|
import unittest
|
||||||
suite = unittest.defaultTestLoader.discover(__path__[0])
|
suite = unittest.defaultTestLoader.discover(__path__[0])
|
||||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
unittest.TextTestRunner(verbosity=2).run(suite)
|
||||||
|
|
|
||||||
|
|
@ -43,14 +43,14 @@ _COLORSPACE_MAP_DISPLAY = {
|
||||||
ROMM_RGB: 'ROMM-RGB'}
|
ROMM_RGB: 'ROMM-RGB'}
|
||||||
|
|
||||||
# enumerated color channel types
|
# enumerated color channel types
|
||||||
_COLOR = 0
|
COLOR = 0
|
||||||
_OPACITY = 1
|
OPACITY = 1
|
||||||
_PRE_MULTIPLIED_OPACITY = 2
|
PRE_MULTIPLIED_OPACITY = 2
|
||||||
_UNSPECIFIED = 65535
|
_UNSPECIFIED = 65535
|
||||||
_COLOR_TYPE_MAP_DISPLAY = {
|
_COLOR_TYPE_MAP_DISPLAY = {
|
||||||
_COLOR: 'color',
|
COLOR: 'color',
|
||||||
_OPACITY: 'opacity',
|
OPACITY: 'opacity',
|
||||||
_PRE_MULTIPLIED_OPACITY: 'pre-multiplied opacity',
|
PRE_MULTIPLIED_OPACITY: 'pre-multiplied opacity',
|
||||||
_UNSPECIFIED: 'unspecified'}
|
_UNSPECIFIED: 'unspecified'}
|
||||||
|
|
||||||
# color channel definitions.
|
# color channel definitions.
|
||||||
|
|
@ -58,6 +58,7 @@ RED = 1
|
||||||
GREEN = 2
|
GREEN = 2
|
||||||
BLUE = 3
|
BLUE = 3
|
||||||
GREY = 1
|
GREY = 1
|
||||||
|
WHOLE_IMAGE = 0
|
||||||
|
|
||||||
# enumerated color channel associations
|
# enumerated color channel associations
|
||||||
_COLORSPACE = {SRGB: {"R": 1, "G": 2, "B": 3},
|
_COLORSPACE = {SRGB: {"R": 1, "G": 2, "B": 3},
|
||||||
|
|
|
||||||
|
|
@ -13,16 +13,22 @@ References
|
||||||
|
|
||||||
# pylint: disable=C0302,R0903,R0913
|
# pylint: disable=C0302,R0903,R0913
|
||||||
|
|
||||||
import collections
|
|
||||||
import copy
|
import copy
|
||||||
import datetime
|
import datetime
|
||||||
import math
|
import math
|
||||||
|
import os
|
||||||
import pprint
|
import pprint
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import uuid
|
import uuid
|
||||||
import warnings
|
import warnings
|
||||||
import xml.etree.cElementTree as ET
|
import xml.etree.cElementTree as ET
|
||||||
|
if sys.hexversion < 0x02070000:
|
||||||
|
from ordereddict import OrderedDict
|
||||||
|
from xml.etree.cElementTree import XMLParserError as ParseError
|
||||||
|
else:
|
||||||
|
from xml.etree.cElementTree import ParseError
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
|
@ -68,9 +74,6 @@ class Jp2kBox(object):
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
self.longname = longname
|
self.longname = longname
|
||||||
|
|
||||||
# should never be used except for last box in file.
|
|
||||||
self._file_size = -1
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
msg = "{0} Box ({1})".format(self.longname, self.box_id)
|
msg = "{0} Box ({1})".format(self.longname, self.box_id)
|
||||||
msg += " @ ({0}, {1})".format(self.offset, self.length)
|
msg += " @ ({0}, {1})".format(self.offset, self.length)
|
||||||
|
|
@ -113,7 +116,7 @@ class Jp2kBox(object):
|
||||||
if box_length == 0:
|
if box_length == 0:
|
||||||
# The length of the box is presumed to last until the end of
|
# The length of the box is presumed to last until the end of
|
||||||
# the file. Compute the effective length of the box.
|
# the file. Compute the effective length of the box.
|
||||||
num_bytes = self._file_size - fptr.tell() + 8
|
num_bytes = os.path.getsize(fptr.name) - fptr.tell() + 8
|
||||||
|
|
||||||
elif box_length == 1:
|
elif box_length == 1:
|
||||||
# The length of the box is in the XL field, a 64-bit value.
|
# The length of the box is in the XL field, a 64-bit value.
|
||||||
|
|
@ -342,7 +345,7 @@ class _ICCProfile(object):
|
||||||
|
|
||||||
def __init__(self, read_buffer):
|
def __init__(self, read_buffer):
|
||||||
self._raw_buffer = read_buffer
|
self._raw_buffer = read_buffer
|
||||||
header = collections.OrderedDict()
|
header = OrderedDict()
|
||||||
|
|
||||||
data = struct.unpack('>IIBB', self._raw_buffer[0:10])
|
data = struct.unpack('>IIBB', self._raw_buffer[0:10])
|
||||||
header['Size'] = data[0]
|
header['Size'] = data[0]
|
||||||
|
|
@ -423,14 +426,24 @@ class ChannelDefinitionBox(Jp2kBox):
|
||||||
longname : str
|
longname : str
|
||||||
more verbose description of the box.
|
more verbose description of the box.
|
||||||
index : int
|
index : int
|
||||||
number of the channel
|
number of the channel. Defaults to monotonically increasing sequence,
|
||||||
|
i.e. [0, 1, 2, ...]
|
||||||
channel_type : int
|
channel_type : int
|
||||||
type of the channel
|
type of the channel
|
||||||
association : int
|
association : int
|
||||||
index of the associated color
|
index of the associated color
|
||||||
"""
|
"""
|
||||||
def __init__(self, index, channel_type, association, **kwargs):
|
def __init__(self, index=None, channel_type=None, association=None,
|
||||||
|
**kwargs):
|
||||||
Jp2kBox.__init__(self, box_id='cdef', longname='Channel Definition')
|
Jp2kBox.__init__(self, box_id='cdef', longname='Channel Definition')
|
||||||
|
|
||||||
|
# channel type and association must be specified.
|
||||||
|
if channel_type is None or association is None:
|
||||||
|
raise IOError("channel_type and association must be specified.")
|
||||||
|
|
||||||
|
if index is None:
|
||||||
|
index = list(range(len(channel_type)))
|
||||||
|
|
||||||
if len(index) != len(channel_type) or len(index) != len(association):
|
if len(index) != len(channel_type) or len(index) != len(association):
|
||||||
msg = "Length of channel definition box inputs must be the same."
|
msg = "Length of channel definition box inputs must be the same."
|
||||||
raise IOError(msg)
|
raise IOError(msg)
|
||||||
|
|
@ -501,8 +514,9 @@ class ChannelDefinitionBox(Jp2kBox):
|
||||||
channel_type = data[1:num_components * 6:3]
|
channel_type = data[1:num_components * 6:3]
|
||||||
association = data[2:num_components * 6:3]
|
association = data[2:num_components * 6:3]
|
||||||
|
|
||||||
box = ChannelDefinitionBox(index, channel_type, association,
|
box = ChannelDefinitionBox(index=index, channel_type=channel_type,
|
||||||
length=length, offset=offset)
|
association=association, length=length,
|
||||||
|
offset=offset)
|
||||||
return box
|
return box
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1012,8 +1026,9 @@ class JPEG2000SignatureBox(Jp2kBox):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
msg = Jp2kBox.__str__(self)
|
msg = Jp2kBox.__str__(self)
|
||||||
msg += '\n Signature: {:02x}{:02x}{:02x}{:02x}'
|
msg += '\n Signature: {0:02x}{1:02x}{2:02x}{3:02x}'
|
||||||
msg = msg.format(*self.signature)
|
msg = msg.format(self.signature[0], self.signature[1],
|
||||||
|
self.signature[2], self.signature[3])
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
def write(self, fptr):
|
def write(self, fptr):
|
||||||
|
|
@ -1634,7 +1649,8 @@ class XMLBox(Jp2kBox):
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
read_buffer = ET.tostring(self.xml, encoding='utf-8')
|
read_buffer = ET.tostring(self.xml, encoding='utf-8')
|
||||||
except AttributeError:
|
except (AttributeError, AssertionError):
|
||||||
|
# AssertionError on 2.6
|
||||||
read_buffer = ET.tostring(self.xml.getroot(), encoding='utf-8')
|
read_buffer = ET.tostring(self.xml.getroot(), encoding='utf-8')
|
||||||
|
|
||||||
fptr.write(struct.pack('>I', len(read_buffer) + 8))
|
fptr.write(struct.pack('>I', len(read_buffer) + 8))
|
||||||
|
|
@ -1667,7 +1683,7 @@ class XMLBox(Jp2kBox):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
xml = ET.fromstring(text)
|
xml = ET.fromstring(text)
|
||||||
except ET.ParseError as parse_error:
|
except ParseError as parse_error:
|
||||||
msg = 'A problem was encountered while parsing an XML box: "{0}"'
|
msg = 'A problem was encountered while parsing an XML box: "{0}"'
|
||||||
msg = msg.format(str(parse_error))
|
msg = msg.format(str(parse_error))
|
||||||
warnings.warn(msg, UserWarning)
|
warnings.warn(msg, UserWarning)
|
||||||
|
|
@ -1910,14 +1926,16 @@ class UUIDBox(Jp2kBox):
|
||||||
# XMP data. Parse as XML. Seems to be a difference between
|
# XMP data. Parse as XML. Seems to be a difference between
|
||||||
# ElementTree in version 2.7 and 3.3.
|
# ElementTree in version 2.7 and 3.3.
|
||||||
if sys.hexversion < 0x03000000:
|
if sys.hexversion < 0x03000000:
|
||||||
parser = ET.XMLParser(encoding='utf-8')
|
#parser = ET.XMLParser(encoding='utf-8')
|
||||||
self.data = ET.fromstringlist(raw_data, parser=parser)
|
#import pdb; pdb.set_trace()
|
||||||
|
#self.data = ET.fromstringlist(raw_data, parser=parser)
|
||||||
|
self.data = ET.fromstring(raw_data)
|
||||||
else:
|
else:
|
||||||
text = raw_data.decode('utf-8')
|
text = raw_data.decode('utf-8')
|
||||||
self.data = ET.fromstring(text)
|
self.data = ET.fromstring(text)
|
||||||
elif the_uuid.bytes == b'JpgTiffExif->JP2':
|
elif the_uuid.bytes == b'JpgTiffExif->JP2':
|
||||||
exif_obj = Exif(raw_data)
|
exif_obj = Exif(raw_data)
|
||||||
ifds = collections.OrderedDict()
|
ifds = OrderedDict()
|
||||||
ifds['Image'] = exif_obj.exif_image
|
ifds['Image'] = exif_obj.exif_image
|
||||||
ifds['Photo'] = exif_obj.exif_photo
|
ifds['Photo'] = exif_obj.exif_photo
|
||||||
ifds['GPSInfo'] = exif_obj.exif_gpsinfo
|
ifds['GPSInfo'] = exif_obj.exif_gpsinfo
|
||||||
|
|
@ -2067,7 +2085,7 @@ class _Ifd(object):
|
||||||
def __init__(self, endian, read_buffer, offset):
|
def __init__(self, endian, read_buffer, offset):
|
||||||
self.endian = endian
|
self.endian = endian
|
||||||
self.read_buffer = read_buffer
|
self.read_buffer = read_buffer
|
||||||
self.processed_ifd = collections.OrderedDict()
|
self.processed_ifd = OrderedDict()
|
||||||
|
|
||||||
self.num_tags, = struct.unpack(endian + 'H',
|
self.num_tags, = struct.unpack(endian + 'H',
|
||||||
read_buffer[offset:offset + 2])
|
read_buffer[offset:offset + 2])
|
||||||
|
|
@ -2075,7 +2093,7 @@ class _Ifd(object):
|
||||||
fmt = self.endian + 'HHII' * self.num_tags
|
fmt = self.endian + 'HHII' * self.num_tags
|
||||||
ifd_buffer = read_buffer[offset + 2:offset + 2 + self.num_tags * 12]
|
ifd_buffer = read_buffer[offset + 2:offset + 2 + self.num_tags * 12]
|
||||||
data = struct.unpack(fmt, ifd_buffer)
|
data = struct.unpack(fmt, ifd_buffer)
|
||||||
self.raw_ifd = collections.OrderedDict()
|
self.raw_ifd = OrderedDict()
|
||||||
for j, tag in enumerate(data[0::4]):
|
for j, tag in enumerate(data[0::4]):
|
||||||
# The offset to the tag offset/payload is the offset to the IFD
|
# The offset to the tag offset/payload is the offset to the IFD
|
||||||
# plus 2 bytes for the number of tags plus 12 bytes for each
|
# plus 2 bytes for the number of tags plus 12 bytes for each
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,13 @@ _INFO_CALLBACK = _CMPFUNC(_default_info_handler)
|
||||||
_WARNING_CALLBACK = _CMPFUNC(_default_warning_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):
|
class Jp2k(Jp2kBox):
|
||||||
"""JPEG 2000 file.
|
"""JPEG 2000 file.
|
||||||
|
|
||||||
|
|
@ -94,7 +101,6 @@ class Jp2k(Jp2kBox):
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
self.box = []
|
self.box = []
|
||||||
self._codec_format = None
|
self._codec_format = None
|
||||||
self._file_size = 0
|
|
||||||
|
|
||||||
# Parse the file for JP2/JPX contents only if we are reading it.
|
# Parse the file for JP2/JPX contents only if we are reading it.
|
||||||
if mode == 'rb':
|
if mode == 'rb':
|
||||||
|
|
@ -118,9 +124,7 @@ class Jp2k(Jp2kBox):
|
||||||
IOError
|
IOError
|
||||||
The file was not JPEG 2000.
|
The file was not JPEG 2000.
|
||||||
"""
|
"""
|
||||||
stat = os.stat(self.filename)
|
self.length = os.path.getsize(self.filename)
|
||||||
self.length = stat.st_size
|
|
||||||
self._file_size = stat.st_size
|
|
||||||
|
|
||||||
with open(self.filename, 'rb') as fptr:
|
with open(self.filename, 'rb') as fptr:
|
||||||
|
|
||||||
|
|
@ -226,7 +230,16 @@ class Jp2k(Jp2kBox):
|
||||||
>>> tfile = NamedTemporaryFile(suffix='.jp2', delete=False)
|
>>> tfile = NamedTemporaryFile(suffix='.jp2', delete=False)
|
||||||
>>> j = Jp2k(tfile.name, mode='wb')
|
>>> j = Jp2k(tfile.name, mode='wb')
|
||||||
>>> j.write(data.astype(np.uint8))
|
>>> j.write(data.astype(np.uint8))
|
||||||
|
|
||||||
|
Raises
|
||||||
|
------
|
||||||
|
glymur.LibraryNotFoundError
|
||||||
|
If glymur is unable to load the openjp2 library.
|
||||||
"""
|
"""
|
||||||
|
if _opj2.OPENJP2 is None:
|
||||||
|
raise LibraryNotFoundError("You must have the development version "
|
||||||
|
"of OpenJP2 installed before using "
|
||||||
|
"this functionality.")
|
||||||
|
|
||||||
cparams = _opj2.set_default_encoder_parameters()
|
cparams = _opj2.set_default_encoder_parameters()
|
||||||
|
|
||||||
|
|
@ -575,7 +588,7 @@ class Jp2k(Jp2kBox):
|
||||||
rlevel : int, optional
|
rlevel : int, optional
|
||||||
Factor by which to rlevel output resolution. Use -1 to get the
|
Factor by which to rlevel output resolution. Use -1 to get the
|
||||||
lowest resolution thumbnail. This is the only keyword option
|
lowest resolution thumbnail. This is the only keyword option
|
||||||
available to use when only OpenJPEG version 1.5.1 is present.
|
available to use when only the OpenJPEG version 1.5.1 is present.
|
||||||
layer : int, optional
|
layer : int, optional
|
||||||
Number of quality layer to decode.
|
Number of quality layer to decode.
|
||||||
area : tuple, optional
|
area : tuple, optional
|
||||||
|
|
@ -593,6 +606,9 @@ class Jp2k(Jp2kBox):
|
||||||
|
|
||||||
Raises
|
Raises
|
||||||
------
|
------
|
||||||
|
glymur.LibraryNotFoundError
|
||||||
|
If glymur is unable to load either the openjpeg or openjp2
|
||||||
|
libraries.
|
||||||
IOError
|
IOError
|
||||||
If the image has differing subsample factors.
|
If the image has differing subsample factors.
|
||||||
|
|
||||||
|
|
@ -613,8 +629,13 @@ class Jp2k(Jp2kBox):
|
||||||
"""
|
"""
|
||||||
if _opj2.OPENJP2 is not None:
|
if _opj2.OPENJP2 is not None:
|
||||||
img = self._read_openjp2(**kwargs)
|
img = self._read_openjp2(**kwargs)
|
||||||
else:
|
elif _opj.OPENJPEG is not None:
|
||||||
img = self._read_openjpeg(**kwargs)
|
img = self._read_openjpeg(**kwargs)
|
||||||
|
else:
|
||||||
|
raise LibraryNotFoundError("You must have either a recent version "
|
||||||
|
"of OpenJPEG or the development "
|
||||||
|
"version of OpenJP2 installed before "
|
||||||
|
"using this functionality.")
|
||||||
return img
|
return img
|
||||||
|
|
||||||
def _read_openjpeg(self, rlevel=0, verbose=False):
|
def _read_openjpeg(self, rlevel=0, verbose=False):
|
||||||
|
|
@ -958,12 +979,13 @@ class Jp2k(Jp2kBox):
|
||||||
|
|
||||||
Raises
|
Raises
|
||||||
------
|
------
|
||||||
NotImplementedError
|
glymur.LibraryNotFoundError
|
||||||
If the openjp2 library is not available.
|
If glymur is unable to load the openjp2 library.
|
||||||
"""
|
"""
|
||||||
if _opj2.OPENJP2 is None:
|
if _opj2.OPENJP2 is None:
|
||||||
msg = "Requires openjp2 library."
|
raise LibraryNotFoundError("You must have the development version "
|
||||||
raise NotImplementedError(msg)
|
"of OpenJP2 installed before using "
|
||||||
|
"this functionality.")
|
||||||
|
|
||||||
lst = self._read_common(rlevel=rlevel,
|
lst = self._read_common(rlevel=rlevel,
|
||||||
layer=layer,
|
layer=layer,
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,9 @@ def glymurrc_fname():
|
||||||
fname = os.path.join(confdir, 'glymurrc')
|
fname = os.path.join(confdir, 'glymurrc')
|
||||||
if os.path.exists(fname):
|
if os.path.exists(fname):
|
||||||
return fname
|
return fname
|
||||||
|
else:
|
||||||
|
msg = "Configuration directory '{0}' does not exist.".format(fname)
|
||||||
|
warnings.warn(msg)
|
||||||
|
|
||||||
# didn't find a configuration file.
|
# didn't find a configuration file.
|
||||||
return None
|
return None
|
||||||
|
|
@ -67,13 +70,6 @@ def load_openjpeg(libopenjpeg_path):
|
||||||
except OSError:
|
except OSError:
|
||||||
openjpeg_lib = None
|
openjpeg_lib = None
|
||||||
|
|
||||||
if openjpeg_lib is not None:
|
|
||||||
# Must be at least 1.5.0
|
|
||||||
openjpeg_lib.opj_version.restype = ctypes.c_char_p
|
|
||||||
version = openjpeg_lib.opj_version().decode('utf-8')
|
|
||||||
_, minor, _ = version.split('.')
|
|
||||||
if minor != '5':
|
|
||||||
openjpeg_lib = None
|
|
||||||
return openjpeg_lib
|
return openjpeg_lib
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -140,7 +136,6 @@ def get_configdir():
|
||||||
Default is $HOME/.config/glymur. You can override this with the
|
Default is $HOME/.config/glymur. You can override this with the
|
||||||
XDG_CONFIG_HOME environment variable.
|
XDG_CONFIG_HOME environment variable.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if 'XDG_CONFIG_HOME' in os.environ:
|
if 'XDG_CONFIG_HOME' in os.environ:
|
||||||
return os.path.join(os.environ['XDG_CONFIG_HOME'], 'glymur')
|
return os.path.join(os.environ['XDG_CONFIG_HOME'], 'glymur')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
# pylint: disable=R0903
|
# pylint: disable=R0903
|
||||||
|
|
||||||
import ctypes
|
import ctypes
|
||||||
|
import sys
|
||||||
|
|
||||||
from .config import glymur_config
|
from .config import glymur_config
|
||||||
_, OPENJPEG = glymur_config()
|
_, OPENJPEG = glymur_config()
|
||||||
|
|
@ -11,6 +12,20 @@ _, OPENJPEG = glymur_config()
|
||||||
PATH_LEN = 4096 # maximum allowed size for filenames
|
PATH_LEN = 4096 # maximum allowed size for filenames
|
||||||
|
|
||||||
|
|
||||||
|
def version():
|
||||||
|
"""Wrapper for opj_version library routine."""
|
||||||
|
OPENJPEG.opj_version.restype = ctypes.c_char_p
|
||||||
|
library_version = OPENJPEG.opj_version()
|
||||||
|
if sys.hexversion >= 0x03000000:
|
||||||
|
return library_version.decode('utf-8')
|
||||||
|
else:
|
||||||
|
return library_version
|
||||||
|
|
||||||
|
# Need to get the minor version, make sure we are at least at 1.4.x
|
||||||
|
#import pdb; pdb.set_trace()
|
||||||
|
_MINOR = version().split('.')[1]
|
||||||
|
|
||||||
|
|
||||||
class EventMgrType(ctypes.Structure):
|
class EventMgrType(ctypes.Structure):
|
||||||
"""Message handler object.
|
"""Message handler object.
|
||||||
|
|
||||||
|
|
@ -86,8 +101,10 @@ class DecompressionParametersType(ctypes.Structure):
|
||||||
("jpwl_max_tiles", ctypes.c_int),
|
("jpwl_max_tiles", ctypes.c_int),
|
||||||
# cp_limit_decoding: whether decoding should be done on the
|
# cp_limit_decoding: whether decoding should be done on the
|
||||||
# entire codestream or be limited to the main header
|
# entire codestream or be limited to the main header
|
||||||
("cp_limit_decoding", ctypes.c_int),
|
("cp_limit_decoding", ctypes.c_int)]
|
||||||
("flags", ctypes.c_uint)]
|
|
||||||
|
if _MINOR == '5':
|
||||||
|
_fields_.append(("flags", ctypes.c_uint))
|
||||||
|
|
||||||
|
|
||||||
class ImageCompType(ctypes.Structure):
|
class ImageCompType(ctypes.Structure):
|
||||||
|
|
@ -204,10 +221,3 @@ def setup_decoder(dinfo, dparams):
|
||||||
ctypes.POINTER(DecompressionParametersType)]
|
ctypes.POINTER(DecompressionParametersType)]
|
||||||
OPENJPEG.opj_setup_decoder.argtypes = argtypes
|
OPENJPEG.opj_setup_decoder.argtypes = argtypes
|
||||||
OPENJPEG.opj_setup_decoder(dinfo, dparams)
|
OPENJPEG.opj_setup_decoder(dinfo, dparams)
|
||||||
|
|
||||||
|
|
||||||
def version():
|
|
||||||
"""Wrapper for opj_version library routine."""
|
|
||||||
OPENJPEG.opj_version.restype = ctypes.c_char_p
|
|
||||||
library_version = OPENJPEG.opj_version()
|
|
||||||
return library_version.decode('utf-8')
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,11 @@ import shutil
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
|
||||||
|
if sys.hexversion < 0x02070000:
|
||||||
|
import unittest2 as unittest
|
||||||
|
else:
|
||||||
|
import unittest
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,12 @@
|
||||||
#pylint: disable-all
|
#pylint: disable-all
|
||||||
import ctypes
|
import ctypes
|
||||||
import unittest
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if sys.hexversion < 0x02070000:
|
||||||
|
import unittest2 as unittest
|
||||||
|
else:
|
||||||
|
import unittest
|
||||||
|
|
||||||
import glymur
|
import glymur
|
||||||
|
|
||||||
|
|
@ -16,13 +22,18 @@ class TestOpenJPEG(unittest.TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_version(self):
|
def test_version(self):
|
||||||
v = glymur.lib._openjpeg.version()
|
version = glymur.lib._openjpeg.version()
|
||||||
parts = v.split('.')
|
regex = re.compile('1.[345].[0-9]')
|
||||||
self.assertEqual(parts[0], '1')
|
if sys.hexversion <= 0x03020000:
|
||||||
self.assertEqual(parts[1], '5')
|
self.assertRegexpMatches(version, regex)
|
||||||
|
else:
|
||||||
|
self.assertRegex(version, regex)
|
||||||
|
|
||||||
def test_set_default_decoder_parameters(self):
|
def test_set_default_decoder_parameters(self):
|
||||||
# Verify that we properly set the default decode parameters.
|
# Verify that we properly set the default decode parameters.
|
||||||
|
version = glymur.lib._openjpeg.version()
|
||||||
|
minor = int(version.split('.')[1])
|
||||||
|
|
||||||
dp = glymur.lib._openjpeg.DecompressionParametersType()
|
dp = glymur.lib._openjpeg.DecompressionParametersType()
|
||||||
glymur.lib._openjpeg.set_default_decoder_parameters(ctypes.byref(dp))
|
glymur.lib._openjpeg.set_default_decoder_parameters(ctypes.byref(dp))
|
||||||
|
|
||||||
|
|
@ -36,4 +47,6 @@ class TestOpenJPEG(unittest.TestCase):
|
||||||
self.assertEqual(dp.jpwl_exp_comps, 0)
|
self.assertEqual(dp.jpwl_exp_comps, 0)
|
||||||
self.assertEqual(dp.jpwl_max_tiles, 0)
|
self.assertEqual(dp.jpwl_max_tiles, 0)
|
||||||
self.assertEqual(dp.cp_limit_decoding, 0)
|
self.assertEqual(dp.cp_limit_decoding, 0)
|
||||||
self.assertEqual(dp.flags, 0)
|
if minor > 4:
|
||||||
|
# Introduced in 1.5.x
|
||||||
|
self.assertEqual(dp.flags, 0)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import pkg_resources
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
if sys.hexversion < 0x03000000:
|
if sys.hexversion < 0x03000000:
|
||||||
|
|
@ -12,6 +11,11 @@ if sys.hexversion < 0x03000000:
|
||||||
else:
|
else:
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
|
||||||
|
if sys.hexversion < 0x02070000:
|
||||||
|
import unittest2 as unittest
|
||||||
|
else:
|
||||||
|
import unittest
|
||||||
|
|
||||||
import glymur
|
import glymur
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,11 @@ import os
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
|
||||||
|
if sys.hexversion < 0x02070000:
|
||||||
|
import unittest2 as unittest
|
||||||
|
else:
|
||||||
|
import unittest
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,12 @@ import imp
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
|
||||||
|
if sys.hexversion < 0x02070000:
|
||||||
|
import unittest2 as unittest
|
||||||
|
else:
|
||||||
|
import unittest
|
||||||
|
|
||||||
if sys.hexversion <= 0x03030000:
|
if sys.hexversion <= 0x03030000:
|
||||||
from mock import patch
|
from mock import patch
|
||||||
else:
|
else:
|
||||||
|
|
@ -21,32 +26,27 @@ from glymur import Jp2k
|
||||||
from glymur.lib import openjp2 as opj2
|
from glymur.lib import openjp2 as opj2
|
||||||
|
|
||||||
|
|
||||||
@unittest.skip("Cannot work when both OPENJPEG and OPENJP2 are both present.")
|
@unittest.skipIf(sys.hexversion < 0x03020000,
|
||||||
|
"TemporaryDirectory introduced in 3.2.")
|
||||||
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
|
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
|
||||||
"Needs openjp2 library first before these tests make sense.")
|
"Needs openjp2 library first before these tests make sense.")
|
||||||
@unittest.skipIf(sys.hexversion < 0x03020000,
|
|
||||||
"Uses features introduced in 3.2.")
|
|
||||||
class TestSuite(unittest.TestCase):
|
class TestSuite(unittest.TestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
# Monkey patch the package so as to ignore OPENJPEG if it exists.
|
imp.reload(glymur)
|
||||||
cls.openjpeg = glymur.lib.openjpeg._OPENJPEG
|
imp.reload(glymur.lib.openjp2)
|
||||||
glymur.lib.openjp2._OPENJPEG = None
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
# Restore OPENJPEG
|
|
||||||
glymur.lib.openjpeg._OPENJPEG = cls.openjpeg
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
imp.reload(glymur)
|
imp.reload(glymur)
|
||||||
imp.reload(glymur.lib.openjp2)
|
imp.reload(glymur.lib.openjp2)
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
self.jp2file = glymur.data.nemo()
|
self.jp2file = glymur.data.nemo()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
imp.reload(glymur)
|
pass
|
||||||
imp.reload(glymur.lib.openjp2)
|
|
||||||
|
|
||||||
def test_config_file_via_environ(self):
|
def test_config_file_via_environ(self):
|
||||||
"""Verify that we can read a configuration file set via environ var."""
|
"""Verify that we can read a configuration file set via environ var."""
|
||||||
|
|
@ -54,11 +54,11 @@ class TestSuite(unittest.TestCase):
|
||||||
configdir = os.path.join(tdir, 'glymur')
|
configdir = os.path.join(tdir, 'glymur')
|
||||||
os.mkdir(configdir)
|
os.mkdir(configdir)
|
||||||
filename = os.path.join(configdir, 'glymurrc')
|
filename = os.path.join(configdir, 'glymurrc')
|
||||||
with open(filename, 'wb') as tfile:
|
with open(filename, 'wt') as tfile:
|
||||||
tfile.write('[library]\n'.encode())
|
tfile.write('[library]\n')
|
||||||
libloc = glymur.lib.openjp2.OPENJP2._name
|
libloc = glymur.lib.openjp2.OPENJP2._name
|
||||||
line = 'openjp2: {0}\n'.format(libloc)
|
line = 'openjp2: {0}\n'.format(libloc)
|
||||||
tfile.write(line.encode())
|
tfile.write(line)
|
||||||
tfile.flush()
|
tfile.flush()
|
||||||
with patch.dict('os.environ', {'XDG_CONFIG_HOME': tdir}):
|
with patch.dict('os.environ', {'XDG_CONFIG_HOME': tdir}):
|
||||||
imp.reload(glymur.lib.openjp2)
|
imp.reload(glymur.lib.openjp2)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,12 @@ import os
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
|
||||||
|
if sys.hexversion < 0x02070000:
|
||||||
|
import unittest2 as unittest
|
||||||
|
else:
|
||||||
|
import unittest
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
from xml.etree import cElementTree as ET
|
from xml.etree import cElementTree as ET
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,14 @@
|
||||||
#pylint: disable-all
|
#pylint: disable-all
|
||||||
import doctest
|
import doctest
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import xml.etree.cElementTree as ET
|
import xml.etree.cElementTree as ET
|
||||||
import unittest
|
|
||||||
|
if sys.hexversion < 0x02070000:
|
||||||
|
import unittest2 as unittest
|
||||||
|
else:
|
||||||
|
import unittest
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
@ -11,6 +16,8 @@ import pkg_resources
|
||||||
import glymur
|
import glymur
|
||||||
from glymur import Jp2k
|
from glymur import Jp2k
|
||||||
from glymur.jp2box import *
|
from glymur.jp2box import *
|
||||||
|
from glymur.core import COLOR, OPACITY
|
||||||
|
from glymur.core import RED, GREEN, BLUE, GREY, WHOLE_IMAGE
|
||||||
|
|
||||||
|
|
||||||
# Doc tests should be run as well.
|
# Doc tests should be run as well.
|
||||||
|
|
@ -79,12 +86,19 @@ class TestChannelDefinition(unittest.TestCase):
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_rgb(self):
|
def test_cdef_no_inputs(self):
|
||||||
|
"""channel_type and association are required inputs."""
|
||||||
|
with self.assertRaises(IOError):
|
||||||
|
glymur.jp2box.ChannelDefinitionBox()
|
||||||
|
|
||||||
|
def test_rgb_with_index(self):
|
||||||
"""Just regular RGB."""
|
"""Just regular RGB."""
|
||||||
j2k = Jp2k(self.j2kfile)
|
j2k = Jp2k(self.j2kfile)
|
||||||
|
channel_type = [COLOR, COLOR, COLOR]
|
||||||
|
association = [RED, GREEN, BLUE]
|
||||||
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2],
|
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2],
|
||||||
channel_type=[0, 0, 0],
|
channel_type=channel_type,
|
||||||
association=[1, 2, 3])
|
association=association)
|
||||||
boxes = [self.ihdr, self.colr_rgb, cdef]
|
boxes = [self.ihdr, self.colr_rgb, cdef]
|
||||||
self.jp2h.box = boxes
|
self.jp2h.box = boxes
|
||||||
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c]
|
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c]
|
||||||
|
|
@ -96,15 +110,41 @@ class TestChannelDefinition(unittest.TestCase):
|
||||||
boxes = [box.box_id for box in jp2h.box]
|
boxes = [box.box_id for box in jp2h.box]
|
||||||
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
||||||
self.assertEqual(jp2h.box[2].index, (0, 1, 2))
|
self.assertEqual(jp2h.box[2].index, (0, 1, 2))
|
||||||
self.assertEqual(jp2h.box[2].channel_type, (0, 0, 0))
|
self.assertEqual(jp2h.box[2].channel_type,
|
||||||
self.assertEqual(jp2h.box[2].association, (1, 2, 3))
|
(COLOR, COLOR, COLOR))
|
||||||
|
self.assertEqual(jp2h.box[2].association,
|
||||||
|
(RED, GREEN, BLUE))
|
||||||
|
|
||||||
|
def test_rgb(self):
|
||||||
|
"""Just regular RGB, but don't supply the optional index."""
|
||||||
|
j2k = Jp2k(self.j2kfile)
|
||||||
|
channel_type = [COLOR, COLOR, COLOR]
|
||||||
|
association = [RED, GREEN, BLUE]
|
||||||
|
cdef = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
|
||||||
|
association=association)
|
||||||
|
boxes = [self.ihdr, self.colr_rgb, cdef]
|
||||||
|
self.jp2h.box = boxes
|
||||||
|
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c]
|
||||||
|
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
|
||||||
|
j2k.wrap(tfile.name, boxes=boxes)
|
||||||
|
|
||||||
|
jp2 = Jp2k(tfile.name)
|
||||||
|
jp2h = jp2.box[2]
|
||||||
|
boxes = [box.box_id for box in jp2h.box]
|
||||||
|
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
||||||
|
self.assertEqual(jp2h.box[2].index, (0, 1, 2))
|
||||||
|
self.assertEqual(jp2h.box[2].channel_type,
|
||||||
|
(COLOR, COLOR, COLOR))
|
||||||
|
self.assertEqual(jp2h.box[2].association,
|
||||||
|
(RED, GREEN, BLUE))
|
||||||
|
|
||||||
def test_rgba(self):
|
def test_rgba(self):
|
||||||
"""Just regular RGBA."""
|
"""Just regular RGBA."""
|
||||||
j2k = Jp2k(self.four_planes)
|
j2k = Jp2k(self.four_planes)
|
||||||
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2, 3],
|
channel_type = (COLOR, COLOR, COLOR, OPACITY)
|
||||||
channel_type=[0, 0, 0, 1],
|
association = (RED, GREEN, BLUE, WHOLE_IMAGE)
|
||||||
association=[1, 2, 3, 0])
|
cdef = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
|
||||||
|
association=association)
|
||||||
boxes = [self.ihdr, self.colr_rgb, cdef]
|
boxes = [self.ihdr, self.colr_rgb, cdef]
|
||||||
self.jp2h.box = boxes
|
self.jp2h.box = boxes
|
||||||
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c]
|
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c]
|
||||||
|
|
@ -116,15 +156,16 @@ class TestChannelDefinition(unittest.TestCase):
|
||||||
boxes = [box.box_id for box in jp2h.box]
|
boxes = [box.box_id for box in jp2h.box]
|
||||||
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
||||||
self.assertEqual(jp2h.box[2].index, (0, 1, 2, 3))
|
self.assertEqual(jp2h.box[2].index, (0, 1, 2, 3))
|
||||||
self.assertEqual(jp2h.box[2].channel_type, (0, 0, 0, 1))
|
self.assertEqual(jp2h.box[2].channel_type, channel_type)
|
||||||
self.assertEqual(jp2h.box[2].association, (1, 2, 3, 0))
|
self.assertEqual(jp2h.box[2].association, association)
|
||||||
|
|
||||||
def test_bad_rgba(self):
|
def test_bad_rgba(self):
|
||||||
"""R, G, and B must be specified."""
|
"""R, G, and B must be specified."""
|
||||||
j2k = Jp2k(self.four_planes)
|
j2k = Jp2k(self.four_planes)
|
||||||
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2, 3],
|
channel_type = (COLOR, COLOR, OPACITY, OPACITY)
|
||||||
channel_type=[0, 0, 1, 1],
|
association = (RED, GREEN, BLUE, WHOLE_IMAGE)
|
||||||
association=[1, 2, 3, 0])
|
cdef = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
|
||||||
|
association=association)
|
||||||
boxes = [self.ihdr, self.colr_rgb, cdef]
|
boxes = [self.ihdr, self.colr_rgb, cdef]
|
||||||
self.jp2h.box = boxes
|
self.jp2h.box = boxes
|
||||||
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c]
|
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c]
|
||||||
|
|
@ -135,9 +176,10 @@ class TestChannelDefinition(unittest.TestCase):
|
||||||
def test_grey(self):
|
def test_grey(self):
|
||||||
"""Just regular greyscale."""
|
"""Just regular greyscale."""
|
||||||
j2k = Jp2k(self.one_plane)
|
j2k = Jp2k(self.one_plane)
|
||||||
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0],
|
channel_type = (COLOR,)
|
||||||
channel_type=[0],
|
association = (GREY,)
|
||||||
association=[1])
|
cdef = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
|
||||||
|
association=association)
|
||||||
boxes = [self.ihdr, self.colr_gr, cdef]
|
boxes = [self.ihdr, self.colr_gr, cdef]
|
||||||
self.jp2h.box = boxes
|
self.jp2h.box = boxes
|
||||||
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c]
|
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c]
|
||||||
|
|
@ -149,15 +191,16 @@ class TestChannelDefinition(unittest.TestCase):
|
||||||
boxes = [box.box_id for box in jp2h.box]
|
boxes = [box.box_id for box in jp2h.box]
|
||||||
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
||||||
self.assertEqual(jp2h.box[2].index, (0,))
|
self.assertEqual(jp2h.box[2].index, (0,))
|
||||||
self.assertEqual(jp2h.box[2].channel_type, (0,))
|
self.assertEqual(jp2h.box[2].channel_type, channel_type)
|
||||||
self.assertEqual(jp2h.box[2].association, (1,))
|
self.assertEqual(jp2h.box[2].association, association)
|
||||||
|
|
||||||
def test_grey_alpha(self):
|
def test_grey_alpha(self):
|
||||||
"""Just regular greyscale plus alpha."""
|
"""Just regular greyscale plus alpha."""
|
||||||
j2k = Jp2k(self.two_planes)
|
j2k = Jp2k(self.two_planes)
|
||||||
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0, 1],
|
channel_type = (COLOR, OPACITY)
|
||||||
channel_type=[0, 1],
|
association = (GREY, WHOLE_IMAGE)
|
||||||
association=[1, 0])
|
cdef = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
|
||||||
|
association=association)
|
||||||
boxes = [self.ihdr, self.colr_gr, cdef]
|
boxes = [self.ihdr, self.colr_gr, cdef]
|
||||||
self.jp2h.box = boxes
|
self.jp2h.box = boxes
|
||||||
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c]
|
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c]
|
||||||
|
|
@ -169,17 +212,19 @@ class TestChannelDefinition(unittest.TestCase):
|
||||||
boxes = [box.box_id for box in jp2h.box]
|
boxes = [box.box_id for box in jp2h.box]
|
||||||
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
||||||
self.assertEqual(jp2h.box[2].index, (0, 1))
|
self.assertEqual(jp2h.box[2].index, (0, 1))
|
||||||
self.assertEqual(jp2h.box[2].channel_type, (0, 1))
|
self.assertEqual(jp2h.box[2].channel_type, channel_type)
|
||||||
self.assertEqual(jp2h.box[2].association, (1, 0))
|
self.assertEqual(jp2h.box[2].association, association)
|
||||||
|
|
||||||
def test_bad_grey_alpha(self):
|
def test_bad_grey_alpha(self):
|
||||||
"""A greyscale image with alpha layer must specify Y"""
|
"""A greyscale image with alpha layer must specify a color channel"""
|
||||||
j2k = Jp2k(self.two_planes)
|
j2k = Jp2k(self.two_planes)
|
||||||
|
|
||||||
|
channel_type = (OPACITY, OPACITY)
|
||||||
|
association = (GREY, WHOLE_IMAGE)
|
||||||
|
|
||||||
# This cdef box
|
# This cdef box
|
||||||
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0, 1],
|
cdef = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
|
||||||
channel_type=[1, 1],
|
association=association)
|
||||||
association=[0, 1])
|
|
||||||
boxes = [self.ihdr, self.colr_gr, cdef]
|
boxes = [self.ihdr, self.colr_gr, cdef]
|
||||||
self.jp2h.box = boxes
|
self.jp2h.box = boxes
|
||||||
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c]
|
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c]
|
||||||
|
|
@ -191,9 +236,10 @@ class TestChannelDefinition(unittest.TestCase):
|
||||||
"""There can only be one channel definition box in the jp2 header."""
|
"""There can only be one channel definition box in the jp2 header."""
|
||||||
j2k = Jp2k(self.j2kfile)
|
j2k = Jp2k(self.j2kfile)
|
||||||
|
|
||||||
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2],
|
channel_type = (COLOR, COLOR, COLOR)
|
||||||
channel_type=[0, 0, 0],
|
association = (RED, GREEN, BLUE)
|
||||||
association=[1, 2, 3])
|
cdef = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
|
||||||
|
association=association)
|
||||||
|
|
||||||
boxes = [self.ihdr, cdef, self.colr_rgb, cdef]
|
boxes = [self.ihdr, cdef, self.colr_rgb, cdef]
|
||||||
self.jp2h.box = boxes
|
self.jp2h.box = boxes
|
||||||
|
|
@ -209,9 +255,10 @@ class TestChannelDefinition(unittest.TestCase):
|
||||||
boxes = [self.ihdr, self.colr_rgb]
|
boxes = [self.ihdr, self.colr_rgb]
|
||||||
self.jp2h.box = boxes
|
self.jp2h.box = boxes
|
||||||
|
|
||||||
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2],
|
channel_type = (COLOR, COLOR, COLOR)
|
||||||
channel_type=[0, 0, 0],
|
association = (RED, GREEN, BLUE)
|
||||||
association=[1, 2, 3])
|
cdef = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
|
||||||
|
association=association)
|
||||||
|
|
||||||
boxes = [self.jP, self.ftyp, self.jp2h, cdef, self.jp2c]
|
boxes = [self.jP, self.ftyp, self.jp2h, cdef, self.jp2c]
|
||||||
|
|
||||||
|
|
@ -223,18 +270,20 @@ class TestChannelDefinition(unittest.TestCase):
|
||||||
# Channel types are limited to 0, 1, 2, 65535
|
# Channel types are limited to 0, 1, 2, 65535
|
||||||
# Should reject if not all of index, channel_type, association the
|
# Should reject if not all of index, channel_type, association the
|
||||||
# same length.
|
# same length.
|
||||||
|
channel_type = (COLOR, COLOR, 3)
|
||||||
|
association = (RED, GREEN, BLUE)
|
||||||
with self.assertRaises(IOError):
|
with self.assertRaises(IOError):
|
||||||
box = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2],
|
box = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
|
||||||
channel_type=[0, 0, 3],
|
association=association)
|
||||||
association=[1, 2, 3])
|
|
||||||
|
|
||||||
def test_wrong_lengths(self):
|
def test_wrong_lengths(self):
|
||||||
# Should reject if not all of index, channel_type, association the
|
# Should reject if not all of index, channel_type, association the
|
||||||
# same length.
|
# same length.
|
||||||
|
channel_type = (COLOR, COLOR)
|
||||||
|
association = (RED, GREEN, BLUE)
|
||||||
with self.assertRaises(IOError):
|
with self.assertRaises(IOError):
|
||||||
box = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2],
|
box = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
|
||||||
channel_type=[0, 0],
|
association=association)
|
||||||
association=[1, 2, 3])
|
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
|
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
|
||||||
|
|
@ -422,6 +471,7 @@ class TestJp2Boxes(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.j2kfile = glymur.data.goodstuff()
|
self.j2kfile = glymur.data.goodstuff()
|
||||||
|
self.jp2file = glymur.data.nemo()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
pass
|
pass
|
||||||
|
|
@ -517,7 +567,7 @@ class TestJp2Boxes(unittest.TestCase):
|
||||||
|
|
||||||
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
|
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
|
||||||
def test_wrap_jp2(self):
|
def test_wrap_jp2(self):
|
||||||
j2k = Jp2k(self.j2kfile)
|
j2k = Jp2k(self.jp2file)
|
||||||
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
|
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
|
||||||
jp2 = j2k.wrap(tfile.name)
|
jp2 = j2k.wrap(tfile.name)
|
||||||
boxes = [box.box_id for box in jp2.box]
|
boxes = [box.box_id for box in jp2.box]
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,12 @@ import struct
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import uuid
|
import uuid
|
||||||
import unittest
|
|
||||||
|
if sys.hexversion < 0x02070000:
|
||||||
|
import unittest2 as unittest
|
||||||
|
else:
|
||||||
|
import unittest
|
||||||
|
|
||||||
if sys.hexversion <= 0x03030000:
|
if sys.hexversion <= 0x03030000:
|
||||||
from mock import patch
|
from mock import patch
|
||||||
else:
|
else:
|
||||||
|
|
@ -34,11 +39,52 @@ def load_tests(loader, tests, ignore):
|
||||||
if os.name == "nt":
|
if os.name == "nt":
|
||||||
# Can't do it on windows, temporary file issue.
|
# Can't do it on windows, temporary file issue.
|
||||||
return tests
|
return tests
|
||||||
|
if sys.hexversion < 0x02070000:
|
||||||
|
# Don't bother with doctests on 2.6 for the time being.
|
||||||
|
return tests
|
||||||
if glymur.lib.openjp2.OPENJP2 is not None:
|
if glymur.lib.openjp2.OPENJP2 is not None:
|
||||||
tests.addTests(doctest.DocTestSuite('glymur.jp2k'))
|
tests.addTests(doctest.DocTestSuite('glymur.jp2k'))
|
||||||
return tests
|
return tests
|
||||||
|
|
||||||
|
|
||||||
|
class TestConfig(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.jp2file = glymur.data.nemo()
|
||||||
|
self.j2kfile = glymur.data.goodstuff()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_read_without_library_backing_us_up(self):
|
||||||
|
"""Don't have either openjp2 or openjpeg libraries? Must error out.
|
||||||
|
"""
|
||||||
|
with patch('glymur.lib.openjp2.OPENJP2', new=None):
|
||||||
|
with patch('glymur.lib.openjpeg.OPENJPEG', new=None):
|
||||||
|
with self.assertRaises(glymur.jp2k.LibraryNotFoundError):
|
||||||
|
d = glymur.Jp2k(self.jp2file).read()
|
||||||
|
|
||||||
|
def test_read_bands_without_library_backing_us_up(self):
|
||||||
|
"""Don't have openjp2 library? Must error out.
|
||||||
|
"""
|
||||||
|
with patch('glymur.lib.openjp2.OPENJP2', new=None):
|
||||||
|
with patch('glymur.lib.openjpeg.OPENJPEG', new=None):
|
||||||
|
with self.assertRaises(glymur.jp2k.LibraryNotFoundError):
|
||||||
|
d = glymur.Jp2k(self.jp2file).read_bands()
|
||||||
|
|
||||||
|
@unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows")
|
||||||
|
def test_write_without_library_backing_us_up(self):
|
||||||
|
"""Don't have openjp2 library? Must error out.
|
||||||
|
"""
|
||||||
|
data = glymur.Jp2k(self.j2kfile).read()
|
||||||
|
with patch('glymur.lib.openjp2.OPENJP2', new=None):
|
||||||
|
with patch('glymur.lib.openjpeg.OPENJPEG', new=None):
|
||||||
|
with self.assertRaises(glymur.jp2k.LibraryNotFoundError):
|
||||||
|
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
|
||||||
|
ofile = Jp2k(tfile.name, 'wb')
|
||||||
|
ofile.write(data)
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows")
|
@unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows")
|
||||||
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
|
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
|
||||||
"Missing openjp2 library.")
|
"Missing openjp2 library.")
|
||||||
|
|
@ -705,13 +751,6 @@ class TestJp2k15(unittest.TestCase):
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_bands(self):
|
|
||||||
"""Reading individual bands is an advanced maneuver.
|
|
||||||
"""
|
|
||||||
jp2k = Jp2k(self.j2kfile)
|
|
||||||
with self.assertRaises(NotImplementedError):
|
|
||||||
jp2k.read_bands()
|
|
||||||
|
|
||||||
def test_area(self):
|
def test_area(self):
|
||||||
"""Area option not allowed for 1.5.1.
|
"""Area option not allowed for 1.5.1.
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,12 @@ import platform
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
from xml.etree import cElementTree as ET
|
from xml.etree import cElementTree as ET
|
||||||
import unittest
|
|
||||||
|
if sys.hexversion < 0x02070000:
|
||||||
|
import unittest2 as unittest
|
||||||
|
else:
|
||||||
|
import unittest
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
if sys.hexversion <= 0x03030000:
|
if sys.hexversion <= 0x03030000:
|
||||||
|
|
@ -102,7 +107,6 @@ class TestSuite(unittest.TestCase):
|
||||||
self.assertTrue(peak_tolerance(jpdata[:, :, 2], pgxdata) < 33)
|
self.assertTrue(peak_tolerance(jpdata[:, :, 2], pgxdata) < 33)
|
||||||
self.assertTrue(mse(jpdata[:, :, 2], pgxdata) < 55.8)
|
self.assertTrue(mse(jpdata[:, :, 2], pgxdata) < 55.8)
|
||||||
|
|
||||||
@unittest.skip("Known failure in OPENJPEG test suite.")
|
|
||||||
def test_ETS_C0P0_p0_05_j2k(self):
|
def test_ETS_C0P0_p0_05_j2k(self):
|
||||||
jfile = os.path.join(data_root, 'input/conformance/p0_05.j2k')
|
jfile = os.path.join(data_root, 'input/conformance/p0_05.j2k')
|
||||||
jp2k = Jp2k(jfile)
|
jp2k = Jp2k(jfile)
|
||||||
|
|
@ -114,17 +118,19 @@ class TestSuite(unittest.TestCase):
|
||||||
self.assertTrue(peak_tolerance(jpdata[0], pgxdata) < 54)
|
self.assertTrue(peak_tolerance(jpdata[0], pgxdata) < 54)
|
||||||
self.assertTrue(mse(jpdata[0], pgxdata) < 68)
|
self.assertTrue(mse(jpdata[0], pgxdata) < 68)
|
||||||
|
|
||||||
@unittest.skip("Known failure in OPENJPEG test suite.")
|
@unittest.skip("8-bit pgx data vs 12-bit j2k data")
|
||||||
def test_ETS_C0P0_p0_06_j2k(self):
|
def test_ETS_C0P0_p0_06_j2k(self):
|
||||||
jfile = os.path.join(data_root, 'input/conformance/p0_06.j2k')
|
jfile = os.path.join(data_root, 'input/conformance/p0_06.j2k')
|
||||||
jp2k = Jp2k(jfile)
|
jp2k = Jp2k(jfile)
|
||||||
jpdata = jp2k.read(rlevel=3)
|
jpdata = jp2k.read_bands(rlevel=3)
|
||||||
|
|
||||||
pgxfile = os.path.join(data_root,
|
pgxfile = os.path.join(data_root,
|
||||||
'baseline/conformance/c0p0_06.pgx')
|
'baseline/conformance/c0p0_06.pgx')
|
||||||
pgxdata = read_pgx(pgxfile)
|
pgxdata = read_pgx(pgxfile)
|
||||||
self.assertTrue(peak_tolerance(jpdata[:, :, 0], pgxdata) < 109)
|
tol = peak_tolerance(jpdata[0], pgxdata)
|
||||||
self.assertTrue(mse(jpdata[:, :, 0], pgxdata) < 743)
|
self.assertTrue(tol < 109)
|
||||||
|
m = mse(jpdata[0], pgxdata)
|
||||||
|
self.assertTrue(m < 743)
|
||||||
|
|
||||||
@unittest.skip("Known failure in OPENJPEG test suite.")
|
@unittest.skip("Known failure in OPENJPEG test suite.")
|
||||||
def test_ETS_C0P0_p0_07_j2k(self):
|
def test_ETS_C0P0_p0_07_j2k(self):
|
||||||
|
|
@ -139,7 +145,7 @@ class TestSuite(unittest.TestCase):
|
||||||
self.assertTrue(peak_tolerance(jpdata[:, :, 0], pgxdata) < 10)
|
self.assertTrue(peak_tolerance(jpdata[:, :, 0], pgxdata) < 10)
|
||||||
self.assertTrue(mse(jpdata[:, :, 0], pgxdata) < 0.34)
|
self.assertTrue(mse(jpdata[:, :, 0], pgxdata) < 0.34)
|
||||||
|
|
||||||
@unittest.skip("Known failure in OPENJPEG test suite.")
|
@unittest.skip("8-bit pgx data vs 12-bit j2k data")
|
||||||
def test_ETS_C0P0_p0_08_j2k(self):
|
def test_ETS_C0P0_p0_08_j2k(self):
|
||||||
jfile = os.path.join(data_root, 'input/conformance/p0_08.j2k')
|
jfile = os.path.join(data_root, 'input/conformance/p0_08.j2k')
|
||||||
jp2k = Jp2k(jfile)
|
jp2k = Jp2k(jfile)
|
||||||
|
|
@ -210,7 +216,7 @@ class TestSuite(unittest.TestCase):
|
||||||
'baseline/conformance/c0p0_13.pgx')
|
'baseline/conformance/c0p0_13.pgx')
|
||||||
pgxdata = read_pgx(pgxfile)
|
pgxdata = read_pgx(pgxfile)
|
||||||
|
|
||||||
np.testing.assert_array_equal(jpdata, pgxdata)
|
np.testing.assert_array_equal(jpdata[:, :, 0], pgxdata)
|
||||||
|
|
||||||
@unittest.skip("Known failure in OPENJPEG test suite.")
|
@unittest.skip("Known failure in OPENJPEG test suite.")
|
||||||
def test_ETS_C0P0_p0_14_j2k(self):
|
def test_ETS_C0P0_p0_14_j2k(self):
|
||||||
|
|
@ -279,27 +285,20 @@ class TestSuite(unittest.TestCase):
|
||||||
'baseline/conformance/c0p1_02.pgx')
|
'baseline/conformance/c0p1_02.pgx')
|
||||||
pgxdata = read_pgx(pgxfile)
|
pgxdata = read_pgx(pgxfile)
|
||||||
|
|
||||||
print(peak_tolerance(jpdata[:, :, 0], pgxdata))
|
|
||||||
print(peak_tolerance(jpdata[:, :, 1], pgxdata))
|
|
||||||
print(peak_tolerance(jpdata[:, :, 2], pgxdata))
|
|
||||||
self.assertTrue(peak_tolerance(jpdata[:, :, 0], pgxdata) < 35)
|
self.assertTrue(peak_tolerance(jpdata[:, :, 0], pgxdata) < 35)
|
||||||
self.assertTrue(mse(jpdata[:, :, 0], pgxdata) < 74)
|
self.assertTrue(mse(jpdata[:, :, 0], pgxdata) < 74)
|
||||||
|
|
||||||
@unittest.skip("Known failure in OPENJPEG test suite operation.")
|
|
||||||
def test_ETS_C0P1_p1_03_j2k(self):
|
def test_ETS_C0P1_p1_03_j2k(self):
|
||||||
jfile = os.path.join(data_root, 'input/conformance/p1_03.j2k')
|
jfile = os.path.join(data_root, 'input/conformance/p1_03.j2k')
|
||||||
jp2k = Jp2k(jfile)
|
jp2k = Jp2k(jfile)
|
||||||
jpdata = jp2k.read(rlevel=3)
|
jpdata = jp2k.read_bands(rlevel=3)
|
||||||
|
|
||||||
pgxfile = os.path.join(data_root,
|
pgxfile = os.path.join(data_root,
|
||||||
'baseline/conformance/c0p1_03.pgx')
|
'baseline/conformance/c0p1_03.pgx')
|
||||||
pgxdata = read_pgx(pgxfile)
|
pgxdata = read_pgx(pgxfile)
|
||||||
|
|
||||||
print(peak_tolerance(jpdata[:, :, 0], pgxdata))
|
self.assertTrue(peak_tolerance(jpdata[0], pgxdata) < 28)
|
||||||
print(peak_tolerance(jpdata[:, :, 1], pgxdata))
|
self.assertTrue(mse(jpdata[0], pgxdata) < 18.8)
|
||||||
print(peak_tolerance(jpdata[:, :, 2], pgxdata))
|
|
||||||
self.assertTrue(peak_tolerance(jpdata[:, :, 0], pgxdata) < 28)
|
|
||||||
self.assertTrue(mse(jpdata[:, :, 0], pgxdata) < 18.8)
|
|
||||||
|
|
||||||
@unittest.skip("Known failure in OPENJPEG test suite operation.")
|
@unittest.skip("Known failure in OPENJPEG test suite operation.")
|
||||||
def test_ETS_C0P1_p1_04_j2k(self):
|
def test_ETS_C0P1_p1_04_j2k(self):
|
||||||
|
|
@ -359,20 +358,17 @@ class TestSuite(unittest.TestCase):
|
||||||
self.assertTrue(peak_tolerance(jpdata[:, :, 0], pgxdata) < 128)
|
self.assertTrue(peak_tolerance(jpdata[:, :, 0], pgxdata) < 128)
|
||||||
self.assertTrue(mse(jpdata[:, :, 0], pgxdata) < 16384)
|
self.assertTrue(mse(jpdata[:, :, 0], pgxdata) < 16384)
|
||||||
|
|
||||||
@unittest.skip("Known failure in OPENJPEG test suite operation.")
|
@unittest.skip("fprintf stderr output in r2345.")
|
||||||
def test_ETS_C0P1_p1_07_j2k(self):
|
def test_ETS_C0P1_p1_07_j2k(self):
|
||||||
jfile = os.path.join(data_root, 'input/conformance/p1_07.j2k')
|
jfile = os.path.join(data_root, 'input/conformance/p1_07.j2k')
|
||||||
jp2k = Jp2k(jfile)
|
jp2k = Jp2k(jfile)
|
||||||
jpdata = jp2k.read(rlevel=0)
|
jpdata = jp2k.read_bands(rlevel=0)
|
||||||
|
|
||||||
pgxfile = os.path.join(data_root,
|
pgxfile = os.path.join(data_root,
|
||||||
'baseline/conformance/c0p1_07.pgx')
|
'baseline/conformance/c0p1_07.pgx')
|
||||||
pgxdata = read_pgx(pgxfile)
|
pgxdata = read_pgx(pgxfile)
|
||||||
|
|
||||||
# This one works.
|
np.testing.assert_array_equal(jpdata[0], pgxdata)
|
||||||
np.testing.assert_array_equal(jpdata[:, :, 0], pgxdata)
|
|
||||||
# This one does not.
|
|
||||||
np.testing.assert_array_equal(jpdata[:, :, 1], pgxdata)
|
|
||||||
|
|
||||||
def test_ETS_C1P0_p0_01_j2k(self):
|
def test_ETS_C1P0_p0_01_j2k(self):
|
||||||
jfile = os.path.join(data_root, 'input/conformance/p0_01.j2k')
|
jfile = os.path.join(data_root, 'input/conformance/p0_01.j2k')
|
||||||
|
|
@ -7764,7 +7760,10 @@ class TestSuite15(unittest.TestCase):
|
||||||
jfile = os.path.join(data_root, 'input/conformance/file9.jp2')
|
jfile = os.path.join(data_root, 'input/conformance/file9.jp2')
|
||||||
jp2k = Jp2k(jfile)
|
jp2k = Jp2k(jfile)
|
||||||
jpdata = jp2k.read()
|
jpdata = jp2k.read()
|
||||||
self.assertEqual(jpdata.shape, (512, 768, 3))
|
if glymur.lib.openjpeg.version().startswith('1.3'):
|
||||||
|
self.assertEqual(jpdata.shape, (512, 768))
|
||||||
|
else:
|
||||||
|
self.assertEqual(jpdata.shape, (512, 768, 3))
|
||||||
|
|
||||||
def test_NR_DEC_Bretagne2_j2k_1_decode(self):
|
def test_NR_DEC_Bretagne2_j2k_1_decode(self):
|
||||||
jfile = os.path.join(data_root,
|
jfile = os.path.join(data_root,
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,12 @@ seem like logical negative tests to add.
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
|
||||||
|
if sys.hexversion < 0x02070000:
|
||||||
|
import unittest2 as unittest
|
||||||
|
else:
|
||||||
|
import unittest
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
@ -14,30 +19,15 @@ import pkg_resources
|
||||||
|
|
||||||
from glymur.lib import openjp2 as opj2
|
from glymur.lib import openjp2 as opj2
|
||||||
|
|
||||||
# Need some combination of matplotlib, PIL, or scikits-image for reading
|
msg = "Matplotlib with the PIL backend must be available in order to run the "
|
||||||
# other image formats.
|
|
||||||
no_read_backend = False
|
|
||||||
msg = "Either scikit-image with the freeimage backend or matplotlib "
|
|
||||||
msg += "with the PIL backend must be available in order to run the "
|
|
||||||
msg += "tests in this suite."
|
msg += "tests in this suite."
|
||||||
no_read_backend_msg = msg
|
no_read_backend_msg = msg
|
||||||
try:
|
try:
|
||||||
import skimage.io
|
from PIL import Image
|
||||||
try:
|
from matplotlib.pyplot import imread
|
||||||
skimage.io.use_plugin('freeimage')
|
no_read_backend = False
|
||||||
from skimage.io import imread
|
except:
|
||||||
except ImportError:
|
no_read_backend = True
|
||||||
try:
|
|
||||||
skimage.io.use_plugin('PIL')
|
|
||||||
from skimage.io import imread
|
|
||||||
except ImportError:
|
|
||||||
raise
|
|
||||||
except ImportError:
|
|
||||||
try:
|
|
||||||
from PIL import Image
|
|
||||||
from matplotlib.pyplot import imread
|
|
||||||
except ImportError:
|
|
||||||
no_read_backend = True
|
|
||||||
|
|
||||||
from glymur import Jp2k
|
from glymur import Jp2k
|
||||||
import glymur
|
import glymur
|
||||||
|
|
|
||||||
|
|
@ -7,37 +7,27 @@ import os
|
||||||
import platform
|
import platform
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
|
||||||
|
if sys.hexversion < 0x02070000:
|
||||||
|
import unittest2 as unittest
|
||||||
|
else:
|
||||||
|
import unittest
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from glymur.lib import openjp2 as opj2
|
from glymur.lib import openjp2 as opj2
|
||||||
|
|
||||||
# Need some combination of matplotlib, PIL, or scikits-image for reading
|
msg = "Matplotlib with the PIL backend must be available in order to run the "
|
||||||
# other image formats.
|
|
||||||
no_read_backend = False
|
|
||||||
msg = "Either scikit-image with the freeimage backend or matplotlib "
|
|
||||||
msg += "with the PIL backend must be available in order to run the "
|
|
||||||
msg += "tests in this suite."
|
msg += "tests in this suite."
|
||||||
no_read_backend_msg = msg
|
no_read_backend_msg = msg
|
||||||
try:
|
try:
|
||||||
import skimage.io
|
from PIL import Image
|
||||||
try:
|
from matplotlib.pyplot import imread
|
||||||
skimage.io.use_plugin('freeimage')
|
no_read_backend = False
|
||||||
from skimage.io import imread
|
except:
|
||||||
except ImportError:
|
no_read_backend = True
|
||||||
try:
|
|
||||||
skimage.io.use_plugin('PIL')
|
|
||||||
from skimage.io import imread
|
|
||||||
except ImportError:
|
|
||||||
raise
|
|
||||||
except ImportError:
|
|
||||||
try:
|
|
||||||
from PIL import Image
|
|
||||||
from matplotlib.pyplot import imread
|
|
||||||
except ImportError:
|
|
||||||
no_read_backend = True
|
|
||||||
|
|
||||||
from glymur import Jp2k
|
from glymur import Jp2k
|
||||||
import glymur
|
import glymur
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,22 @@ import pkg_resources
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
|
||||||
|
if sys.hexversion < 0x02070000:
|
||||||
|
import unittest2 as unittest
|
||||||
|
else:
|
||||||
|
import unittest
|
||||||
|
|
||||||
if sys.hexversion < 0x03000000:
|
if sys.hexversion < 0x03000000:
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
else:
|
else:
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
|
||||||
|
if sys.hexversion <= 0x03030000:
|
||||||
|
from mock import patch
|
||||||
|
else:
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
import glymur
|
import glymur
|
||||||
from glymur import Jp2k
|
from glymur import Jp2k
|
||||||
|
|
||||||
|
|
@ -48,10 +57,6 @@ class TestPrintingNeedsLib(unittest.TestCase):
|
||||||
self.jp2file = glymur.data.nemo()
|
self.jp2file = glymur.data.nemo()
|
||||||
self.j2kfile = glymur.data.goodstuff()
|
self.j2kfile = glymur.data.goodstuff()
|
||||||
|
|
||||||
# Save sys.stdout.
|
|
||||||
self.stdout = sys.stdout
|
|
||||||
sys.stdout = StringIO()
|
|
||||||
|
|
||||||
# Save the output of dumping nemo.jp2 for more than one test.
|
# Save the output of dumping nemo.jp2 for more than one test.
|
||||||
lines = ['JPEG 2000 Signature Box (jP ) @ (0, 12)',
|
lines = ['JPEG 2000 Signature Box (jP ) @ (0, 12)',
|
||||||
' Signature: 0d0a870a',
|
' Signature: 0d0a870a',
|
||||||
|
|
@ -118,8 +123,7 @@ class TestPrintingNeedsLib(unittest.TestCase):
|
||||||
self.expectedPlain = '\n'.join(lines)
|
self.expectedPlain = '\n'.join(lines)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
# Restore stdout.
|
pass
|
||||||
sys.stdout = self.stdout
|
|
||||||
|
|
||||||
def test_asoc_label_box(self):
|
def test_asoc_label_box(self):
|
||||||
# Construct a fake file with an asoc and a label box, as
|
# Construct a fake file with an asoc and a label box, as
|
||||||
|
|
@ -162,8 +166,9 @@ class TestPrintingNeedsLib(unittest.TestCase):
|
||||||
tfile2.flush()
|
tfile2.flush()
|
||||||
|
|
||||||
jasoc = glymur.Jp2k(tfile2.name)
|
jasoc = glymur.Jp2k(tfile2.name)
|
||||||
print(jasoc.box[3])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(jasoc.box[3])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
lines = ['Association Box (asoc) @ (77, 56)',
|
lines = ['Association Box (asoc) @ (77, 56)',
|
||||||
' Label Box (lbl ) @ (85, 13)',
|
' Label Box (lbl ) @ (85, 13)',
|
||||||
' Label: label',
|
' Label: label',
|
||||||
|
|
@ -173,20 +178,21 @@ class TestPrintingNeedsLib(unittest.TestCase):
|
||||||
self.assertEqual(actual, expected)
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
def test_jp2dump(self):
|
def test_jp2dump(self):
|
||||||
glymur.jp2dump(self._plain_nemo_file)
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
glymur.jp2dump(self._plain_nemo_file)
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
# Get rid of the filename line, as it is not set in stone.
|
# Get rid of the filename line, as it is not set in stone.
|
||||||
lst = actual.split('\n')
|
lst = actual.split('\n')
|
||||||
lst = lst[1:]
|
lst = lst[1:]
|
||||||
actual = '\n'.join(lst)
|
actual = '\n'.join(lst)
|
||||||
self.maxDiff = None
|
|
||||||
self.assertEqual(actual, self.expectedPlain)
|
self.assertEqual(actual, self.expectedPlain)
|
||||||
|
|
||||||
def test_entire_file(self):
|
def test_entire_file(self):
|
||||||
j = glymur.Jp2k(self._plain_nemo_file)
|
j = glymur.Jp2k(self._plain_nemo_file)
|
||||||
print(j)
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(j)
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
# Get rid of the filename line, as it is not set in stone.
|
# Get rid of the filename line, as it is not set in stone.
|
||||||
lst = actual.split('\n')
|
lst = actual.split('\n')
|
||||||
|
|
@ -200,20 +206,17 @@ class TestPrinting(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
# Save sys.stdout.
|
# Save sys.stdout.
|
||||||
self.stdout = sys.stdout
|
self.jp2file = glymur.data.nemo()
|
||||||
sys.stdout = StringIO()
|
|
||||||
self.jp2file = pkg_resources.resource_filename(glymur.__name__,
|
|
||||||
"data/nemo.jp2")
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
# Restore stdout.
|
pass
|
||||||
sys.stdout = self.stdout
|
|
||||||
|
|
||||||
def test_COC_segment(self):
|
def test_COC_segment(self):
|
||||||
j = glymur.Jp2k(self.jp2file)
|
j = glymur.Jp2k(self.jp2file)
|
||||||
codestream = j.get_codestream(header_only=False)
|
codestream = j.get_codestream(header_only=False)
|
||||||
print(codestream.segment[6])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[6])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
lines = ['COC marker segment @ (3260, 9)',
|
lines = ['COC marker segment @ (3260, 9)',
|
||||||
' Associated component: 1',
|
' Associated component: 1',
|
||||||
|
|
@ -233,14 +236,14 @@ class TestPrinting(unittest.TestCase):
|
||||||
' Segmentation symbols: False']
|
' Segmentation symbols: False']
|
||||||
|
|
||||||
expected = '\n'.join(lines)
|
expected = '\n'.join(lines)
|
||||||
self.maxDiff = None
|
|
||||||
self.assertEqual(actual, expected)
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
def test_COD_segment(self):
|
def test_COD_segment(self):
|
||||||
j = glymur.Jp2k(self.jp2file)
|
j = glymur.Jp2k(self.jp2file)
|
||||||
codestream = j.get_codestream()
|
codestream = j.get_codestream()
|
||||||
print(codestream.segment[2])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[2])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
lines = ['COD marker segment @ (3186, 12)',
|
lines = ['COD marker segment @ (3186, 12)',
|
||||||
' Coding style:',
|
' Coding style:',
|
||||||
|
|
@ -275,8 +278,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
def test_icc_profile(self):
|
def test_icc_profile(self):
|
||||||
filename = os.path.join(data_root, 'input/nonregression/text_GBR.jp2')
|
filename = os.path.join(data_root, 'input/nonregression/text_GBR.jp2')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
print(j.box[3].box[1])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(j.box[3].box[1])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
lin27 = ["Colour Specification Box (colr) @ (179, 1339)",
|
lin27 = ["Colour Specification Box (colr) @ (179, 1339)",
|
||||||
" Method: any ICC profile",
|
" Method: any ICC profile",
|
||||||
" Precedence: 2",
|
" Precedence: 2",
|
||||||
|
|
@ -340,8 +344,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
filename = os.path.join(data_root, 'input/conformance/p0_03.j2k')
|
filename = os.path.join(data_root, 'input/conformance/p0_03.j2k')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
codestream = j.get_codestream()
|
codestream = j.get_codestream()
|
||||||
print(codestream.segment[-5])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[-5])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
lines = ['CRG marker segment at (87, 6)',
|
lines = ['CRG marker segment at (87, 6)',
|
||||||
' Vertical, Horizontal offset: (0.50, 1.00)']
|
' Vertical, Horizontal offset: (0.50, 1.00)']
|
||||||
expected = '\n'.join(lines)
|
expected = '\n'.join(lines)
|
||||||
|
|
@ -353,8 +358,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
filename = os.path.join(data_root, 'input/conformance/p0_03.j2k')
|
filename = os.path.join(data_root, 'input/conformance/p0_03.j2k')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
codestream = j.get_codestream(header_only=False)
|
codestream = j.get_codestream(header_only=False)
|
||||||
print(codestream.segment[12])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[12])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
lines = ['RGN marker segment @ (310, 5)',
|
lines = ['RGN marker segment @ (310, 5)',
|
||||||
' Associated component: 0',
|
' Associated component: 0',
|
||||||
' ROI style: 0',
|
' ROI style: 0',
|
||||||
|
|
@ -368,8 +374,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
filename = os.path.join(data_root, 'input/conformance/p0_03.j2k')
|
filename = os.path.join(data_root, 'input/conformance/p0_03.j2k')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
codestream = j.get_codestream(header_only=False)
|
codestream = j.get_codestream(header_only=False)
|
||||||
print(codestream.segment[-2])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[-2])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
lines = ['SOP marker segment @ (12836, 4)',
|
lines = ['SOP marker segment @ (12836, 4)',
|
||||||
' Nsop: 15']
|
' Nsop: 15']
|
||||||
expected = '\n'.join(lines)
|
expected = '\n'.join(lines)
|
||||||
|
|
@ -383,8 +390,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
codestream = j.get_codestream()
|
codestream = j.get_codestream()
|
||||||
# 2nd to last segment in the main header
|
# 2nd to last segment in the main header
|
||||||
print(codestream.segment[-2])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[-2])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
lines = ['CME marker segment @ (85, 45)',
|
lines = ['CME marker segment @ (85, 45)',
|
||||||
' "Creator: AV-J2K (c) 2000,2001 Algo Vision"']
|
' "Creator: AV-J2K (c) 2000,2001 Algo Vision"']
|
||||||
expected = '\n'.join(lines)
|
expected = '\n'.join(lines)
|
||||||
|
|
@ -393,8 +401,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
def test_EOC_segment(self):
|
def test_EOC_segment(self):
|
||||||
j = glymur.Jp2k(self.jp2file)
|
j = glymur.Jp2k(self.jp2file)
|
||||||
codestream = j.get_codestream(header_only=False)
|
codestream = j.get_codestream(header_only=False)
|
||||||
print(codestream.segment[-1])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[-1])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
lines = ['EOC marker segment @ (1135421, 0)']
|
lines = ['EOC marker segment @ (1135421, 0)']
|
||||||
expected = '\n'.join(lines)
|
expected = '\n'.join(lines)
|
||||||
|
|
@ -406,8 +415,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
filename = os.path.join(data_root, 'input/conformance/p0_07.j2k')
|
filename = os.path.join(data_root, 'input/conformance/p0_07.j2k')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
codestream = j.get_codestream(header_only=False)
|
codestream = j.get_codestream(header_only=False)
|
||||||
print(codestream.segment[49935])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[49935])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
lines = ['PLT marker segment @ (7871146, 38)',
|
lines = ['PLT marker segment @ (7871146, 38)',
|
||||||
' Index: 0',
|
' Index: 0',
|
||||||
|
|
@ -423,8 +433,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
filename = os.path.join(data_root, 'input/conformance/p0_13.j2k')
|
filename = os.path.join(data_root, 'input/conformance/p0_13.j2k')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
codestream = j.get_codestream()
|
codestream = j.get_codestream()
|
||||||
print(codestream.segment[8])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[8])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
lines = ['POD marker segment @ (878, 20)',
|
lines = ['POD marker segment @ (878, 20)',
|
||||||
' Progression change 0:',
|
' Progression change 0:',
|
||||||
|
|
@ -451,8 +462,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
filename = os.path.join(data_root, 'input/conformance/p1_03.j2k')
|
filename = os.path.join(data_root, 'input/conformance/p1_03.j2k')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
codestream = j.get_codestream()
|
codestream = j.get_codestream()
|
||||||
print(codestream.segment[9])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[9])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
lines = ['PPM marker segment @ (213, 43712)',
|
lines = ['PPM marker segment @ (213, 43712)',
|
||||||
' Index: 0',
|
' Index: 0',
|
||||||
|
|
@ -467,8 +479,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
filename = os.path.join(data_root, 'input/conformance/p1_06.j2k')
|
filename = os.path.join(data_root, 'input/conformance/p1_06.j2k')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
codestream = j.get_codestream(header_only=False)
|
codestream = j.get_codestream(header_only=False)
|
||||||
print(codestream.segment[6])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[6])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
lines = ['PPT marker segment @ (155, 109)',
|
lines = ['PPT marker segment @ (155, 109)',
|
||||||
' Index: 0',
|
' Index: 0',
|
||||||
|
|
@ -480,8 +493,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
def test_QCC_segment(self):
|
def test_QCC_segment(self):
|
||||||
j = glymur.Jp2k(self.jp2file)
|
j = glymur.Jp2k(self.jp2file)
|
||||||
codestream = j.get_codestream(header_only=False)
|
codestream = j.get_codestream(header_only=False)
|
||||||
print(codestream.segment[7])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[7])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
lines = ['QCC marker segment @ (3271, 8)',
|
lines = ['QCC marker segment @ (3271, 8)',
|
||||||
' Associated Component: 1',
|
' Associated Component: 1',
|
||||||
|
|
@ -494,8 +508,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
def test_QCD_segment_5x3_transform(self):
|
def test_QCD_segment_5x3_transform(self):
|
||||||
j = glymur.Jp2k(self.jp2file)
|
j = glymur.Jp2k(self.jp2file)
|
||||||
codestream = j.get_codestream()
|
codestream = j.get_codestream()
|
||||||
print(codestream.segment[3])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[3])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
lines = ['QCD marker segment @ (3200, 7)',
|
lines = ['QCD marker segment @ (3200, 7)',
|
||||||
' Quantization style: no quantization, 2 guard bits',
|
' Quantization style: no quantization, 2 guard bits',
|
||||||
|
|
@ -507,8 +522,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
def test_SIZ_segment(self):
|
def test_SIZ_segment(self):
|
||||||
j = glymur.Jp2k(self.jp2file)
|
j = glymur.Jp2k(self.jp2file)
|
||||||
codestream = j.get_codestream()
|
codestream = j.get_codestream()
|
||||||
print(codestream.segment[1])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[1])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
lines = ['SIZ marker segment @ (3137, 47)',
|
lines = ['SIZ marker segment @ (3137, 47)',
|
||||||
' Profile: 2',
|
' Profile: 2',
|
||||||
|
|
@ -527,8 +543,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
def test_SOC_segment(self):
|
def test_SOC_segment(self):
|
||||||
j = glymur.Jp2k(self.jp2file)
|
j = glymur.Jp2k(self.jp2file)
|
||||||
codestream = j.get_codestream()
|
codestream = j.get_codestream()
|
||||||
print(codestream.segment[0])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[0])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
lines = ['SOC marker segment @ (3135, 0)']
|
lines = ['SOC marker segment @ (3135, 0)']
|
||||||
expected = '\n'.join(lines)
|
expected = '\n'.join(lines)
|
||||||
|
|
@ -537,8 +554,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
def test_SOD_segment(self):
|
def test_SOD_segment(self):
|
||||||
j = glymur.Jp2k(self.jp2file)
|
j = glymur.Jp2k(self.jp2file)
|
||||||
codestream = j.get_codestream(header_only=False)
|
codestream = j.get_codestream(header_only=False)
|
||||||
print(codestream.segment[10])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[10])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
lines = ['SOD marker segment @ (3302, 0)']
|
lines = ['SOD marker segment @ (3302, 0)']
|
||||||
expected = '\n'.join(lines)
|
expected = '\n'.join(lines)
|
||||||
|
|
@ -547,8 +565,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
def test_SOT_segment(self):
|
def test_SOT_segment(self):
|
||||||
j = glymur.Jp2k(self.jp2file)
|
j = glymur.Jp2k(self.jp2file)
|
||||||
codestream = j.get_codestream(header_only=False)
|
codestream = j.get_codestream(header_only=False)
|
||||||
print(codestream.segment[5])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[5])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
lines = ['SOT marker segment @ (3248, 10)',
|
lines = ['SOT marker segment @ (3248, 10)',
|
||||||
' Tile part index: 0',
|
' Tile part index: 0',
|
||||||
|
|
@ -566,8 +585,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
filename = os.path.join(data_root, 'input/conformance/p0_15.j2k')
|
filename = os.path.join(data_root, 'input/conformance/p0_15.j2k')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
codestream = j.get_codestream()
|
codestream = j.get_codestream()
|
||||||
print(codestream.segment[10])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[10])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
lines = ['TLM marker segment @ (268, 28)',
|
lines = ['TLM marker segment @ (268, 28)',
|
||||||
' Index: 0',
|
' Index: 0',
|
||||||
|
|
@ -577,11 +597,15 @@ class TestPrinting(unittest.TestCase):
|
||||||
expected = '\n'.join(lines)
|
expected = '\n'.join(lines)
|
||||||
self.assertEqual(actual, expected)
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
@unittest.skipIf(sys.hexversion < 0x02070000,
|
||||||
|
"Differences in XML printing between 2.6 and 2.7")
|
||||||
def test_xmp(self):
|
def test_xmp(self):
|
||||||
# Verify the printing of a UUID/XMP box.
|
# Verify the printing of a UUID/XMP box.
|
||||||
j = glymur.Jp2k(self.jp2file)
|
j = glymur.Jp2k(self.jp2file)
|
||||||
print(j.box[4])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(j.box[4])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
lst = ['UUID Box (uuid) @ (715, 2412)',
|
lst = ['UUID Box (uuid) @ (715, 2412)',
|
||||||
' UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)',
|
' UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)',
|
||||||
' UUID Data: ',
|
' UUID Data: ',
|
||||||
|
|
@ -599,8 +623,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
|
|
||||||
def test_codestream(self):
|
def test_codestream(self):
|
||||||
j = glymur.Jp2k(self.jp2file)
|
j = glymur.Jp2k(self.jp2file)
|
||||||
print(j.get_codestream())
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(j.get_codestream())
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
lst = ['Codestream:',
|
lst = ['Codestream:',
|
||||||
' SOC marker segment @ (3135, 0)',
|
' SOC marker segment @ (3135, 0)',
|
||||||
' SIZ marker segment @ (3137, 47)',
|
' SIZ marker segment @ (3137, 47)',
|
||||||
|
|
@ -645,13 +670,16 @@ class TestPrinting(unittest.TestCase):
|
||||||
self.maxDiff = None
|
self.maxDiff = None
|
||||||
self.assertEqual(actual, expected)
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
@unittest.skipIf(sys.hexversion < 0x02070000,
|
||||||
|
"Differences in XML printing between 2.6 and 2.7")
|
||||||
@unittest.skipIf(data_root is None,
|
@unittest.skipIf(data_root is None,
|
||||||
"OPJ_DATA_ROOT environment variable not set")
|
"OPJ_DATA_ROOT environment variable not set")
|
||||||
def test_xml(self):
|
def test_xml(self):
|
||||||
filename = os.path.join(data_root, 'input/conformance/file1.jp2')
|
filename = os.path.join(data_root, 'input/conformance/file1.jp2')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
print(j.box[2])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(j.box[2])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
lines = ['XML Box (xml ) @ (36, 439)',
|
lines = ['XML Box (xml ) @ (36, 439)',
|
||||||
' <ns0:IMAGE_CREATION '
|
' <ns0:IMAGE_CREATION '
|
||||||
|
|
@ -679,8 +707,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
def test_channel_definition(self):
|
def test_channel_definition(self):
|
||||||
filename = os.path.join(data_root, 'input/conformance/file2.jp2')
|
filename = os.path.join(data_root, 'input/conformance/file2.jp2')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
print(j.box[2].box[2])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(j.box[2].box[2])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
lines = ['Channel Definition Box (cdef) @ (81, 28)',
|
lines = ['Channel Definition Box (cdef) @ (81, 28)',
|
||||||
' Channel 0 (color) ==> (3)',
|
' Channel 0 (color) ==> (3)',
|
||||||
' Channel 1 (color) ==> (2)',
|
' Channel 1 (color) ==> (2)',
|
||||||
|
|
@ -693,8 +722,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
def test_component_mapping(self):
|
def test_component_mapping(self):
|
||||||
filename = os.path.join(data_root, 'input/conformance/file9.jp2')
|
filename = os.path.join(data_root, 'input/conformance/file9.jp2')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
print(j.box[2].box[2])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(j.box[2].box[2])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
lines = ['Component Mapping Box (cmap) @ (848, 20)',
|
lines = ['Component Mapping Box (cmap) @ (848, 20)',
|
||||||
' Component 0 ==> palette column 0',
|
' Component 0 ==> palette column 0',
|
||||||
' Component 0 ==> palette column 1',
|
' Component 0 ==> palette column 1',
|
||||||
|
|
@ -707,8 +737,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
def test_palette(self):
|
def test_palette(self):
|
||||||
filename = os.path.join(data_root, 'input/conformance/file9.jp2')
|
filename = os.path.join(data_root, 'input/conformance/file9.jp2')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
print(j.box[2].box[1])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(j.box[2].box[1])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
lines = ['Palette Box (pclr) @ (66, 782)',
|
lines = ['Palette Box (pclr) @ (66, 782)',
|
||||||
' Size: (256 x 3)']
|
' Size: (256 x 3)']
|
||||||
expected = '\n'.join(lines)
|
expected = '\n'.join(lines)
|
||||||
|
|
@ -719,8 +750,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
def test_palette(self):
|
def test_palette(self):
|
||||||
filename = os.path.join(data_root, 'input/conformance/file7.jp2')
|
filename = os.path.join(data_root, 'input/conformance/file7.jp2')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
print(j.box[2])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(j.box[2])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
lines = ['Reader Requirements Box (rreq) @ (44, 24)',
|
lines = ['Reader Requirements Box (rreq) @ (44, 24)',
|
||||||
' Standard Features:',
|
' Standard Features:',
|
||||||
' Feature 005: '
|
' Feature 005: '
|
||||||
|
|
@ -742,8 +774,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
filename = os.path.join(data_root, 'input/conformance/p0_03.j2k')
|
filename = os.path.join(data_root, 'input/conformance/p0_03.j2k')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
codestream = j.get_codestream()
|
codestream = j.get_codestream()
|
||||||
print(codestream.segment[6])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[6])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
lines = ['CRG marker segment @ (87, 6)',
|
lines = ['CRG marker segment @ (87, 6)',
|
||||||
' Vertical, Horizontal offset: (0.50, 1.00)']
|
' Vertical, Horizontal offset: (0.50, 1.00)']
|
||||||
expected = '\n'.join(lines)
|
expected = '\n'.join(lines)
|
||||||
|
|
@ -756,8 +789,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
filename = os.path.join(data_root, 'input/conformance/p0_05.j2k')
|
filename = os.path.join(data_root, 'input/conformance/p0_05.j2k')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
codestream = j.get_codestream()
|
codestream = j.get_codestream()
|
||||||
print(codestream.segment[1])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(codestream.segment[1])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
lines = ['SIZ marker segment @ (2, 50)',
|
lines = ['SIZ marker segment @ (2, 50)',
|
||||||
' Profile: 0',
|
' Profile: 0',
|
||||||
' Reference Grid Height, Width: (1024 x 1024)',
|
' Reference Grid Height, Width: (1024 x 1024)',
|
||||||
|
|
@ -777,8 +811,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
# Verify that palette (pclr) boxes are printed without error.
|
# Verify that palette (pclr) boxes are printed without error.
|
||||||
filename = os.path.join(data_root, 'input/conformance/file9.jp2')
|
filename = os.path.join(data_root, 'input/conformance/file9.jp2')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
print(j.box[2].box[1])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(j.box[2].box[1])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
lines = ['Palette Box (pclr) @ (66, 782)',
|
lines = ['Palette Box (pclr) @ (66, 782)',
|
||||||
' Size: (256 x 3)']
|
' Size: (256 x 3)']
|
||||||
expected = '\n'.join(lines)
|
expected = '\n'.join(lines)
|
||||||
|
|
@ -837,9 +872,10 @@ class TestPrinting(unittest.TestCase):
|
||||||
tfile.flush()
|
tfile.flush()
|
||||||
|
|
||||||
jp2k = glymur.Jp2k(tfile.name)
|
jp2k = glymur.Jp2k(tfile.name)
|
||||||
print(jp2k.box[3])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
print(jp2k.box[4])
|
print(jp2k.box[3])
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(jp2k.box[4])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
lines = ['UUIDInfo Box (uinf) @ (77, 50)',
|
lines = ['UUIDInfo Box (uinf) @ (77, 50)',
|
||||||
' UUID List Box (ulst) @ (85, 26)',
|
' UUID List Box (ulst) @ (85, 26)',
|
||||||
' UUID[0]: 00000000-0000-0000-0000-000000000000',
|
' UUID[0]: 00000000-0000-0000-0000-000000000000',
|
||||||
|
|
@ -868,8 +904,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
filename = os.path.join(data_root, 'input/nonregression/text_GBR.jp2')
|
filename = os.path.join(data_root, 'input/nonregression/text_GBR.jp2')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
|
|
||||||
print(j.box[3].box[1])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(j.box[3].box[1])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
lines = ["Colour Specification Box (colr) @ (179, 1339)",
|
lines = ["Colour Specification Box (colr) @ (179, 1339)",
|
||||||
" Method: any ICC profile",
|
" Method: any ICC profile",
|
||||||
" Precedence: 2",
|
" Precedence: 2",
|
||||||
|
|
@ -907,8 +944,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
filename = os.path.join(data_root, 'input/nonregression/text_GBR.jp2')
|
filename = os.path.join(data_root, 'input/nonregression/text_GBR.jp2')
|
||||||
j = glymur.Jp2k(filename)
|
j = glymur.Jp2k(filename)
|
||||||
|
|
||||||
print(j.box[4])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(j.box[4])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
lines = ['UUID Box (uuid) @ (1544, 25)',
|
lines = ['UUID Box (uuid) @ (1544, 25)',
|
||||||
' UUID: 3a0d0218-0ae9-4115-b376-4bca41ce0e71',
|
' UUID: 3a0d0218-0ae9-4115-b376-4bca41ce0e71',
|
||||||
' UUID Data: 1 bytes']
|
' UUID Data: 1 bytes']
|
||||||
|
|
@ -921,8 +959,9 @@ class TestPrinting(unittest.TestCase):
|
||||||
def test_exif_uuid(self):
|
def test_exif_uuid(self):
|
||||||
j = glymur.Jp2k(self.jp2file)
|
j = glymur.Jp2k(self.jp2file)
|
||||||
|
|
||||||
print(j.box[3])
|
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||||
actual = sys.stdout.getvalue().strip()
|
print(j.box[3])
|
||||||
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
lines = ["UUID Box (uuid) @ (77, 638)",
|
lines = ["UUID Box (uuid) @ (77, 638)",
|
||||||
" UUID: 4a706754-6966-6645-7869-662d3e4a5032 (Exif)",
|
" UUID: 4a706754-6966-6645-7869-662d3e4a5032 (Exif)",
|
||||||
|
|
|
||||||
63
release.txt
63
release.txt
|
|
@ -1,30 +1,39 @@
|
||||||
| OS | Python 2.7 | Python 3.3 | Notes |
|
| OS | Python | Python | Python | Notes |
|
||||||
+------------+------------+------------+--------------------------------------+
|
| | 2.6 | 2.7 | 3.3 | |
|
||||||
| 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. 285 of 448 tests |
|
||||||
| Windows | X | | Python(xy) with OpenJPEG 1.5.1 and |
|
| | | | | pass. |
|
||||||
| | | | OpenJPEG svn. At least 282 of 444 |
|
+-----------+--------+--------+--------+--------------------------------------+
|
||||||
| | | | tests should pass. |
|
| Mac | X | | | MacPorts with both OpenJPEG 1.5.1 |
|
||||||
+------------+------------+------------+--------------------------------------+
|
| 10.6.8 | | | | and OpenJPEG svn. 353 of 449 tests |
|
||||||
| Mac | X | | MacPorts with both OpenJPEG 1.5.1 |
|
| | | | | should pass. |
|
||||||
| | | | and OpenJPEG svn. 370 of 450 tests |
|
+-----------+--------+--------+--------+--------------------------------------+
|
||||||
| | | | should pass. |
|
| Mac | | X | | MacPorts with both OpenJPEG 1.5.1 |
|
||||||
+------------+------------+------------+--------------------------------------+
|
| 10.6.8 | | | | and OpenJPEG svn. 376 of 454 tests |
|
||||||
| Mac | | X | MacPorts with both OpenJPEG 1.5.1 |
|
| | | | | should pass. |
|
||||||
| | | | and OpenJPEG svn. 390 of 450 |
|
+-----------+--------+--------+--------+--------------------------------------+
|
||||||
| | | | tests should pass. |
|
| Mac | | | X | MacPorts with both OpenJPEG 1.5.1 |
|
||||||
+------------+------------+------------+--------------------------------------+
|
| 10.6.8 | | | | and OpenJPEG svn. 401 of 454 |
|
||||||
| Fedora 19 | | X | Ships with 1.5.1. 390 of 450 tests |
|
| | | | | tests should pass. |
|
||||||
| | | | should pass. |
|
+-----------+--------+--------+-----------------------------------------------+
|
||||||
+------------+------------+------------+--------------------------------------+
|
| Fedora 19 | | | X | Ships with 1.5.1, openjp2 built too. |
|
||||||
| Fedora 18 | | X | Ships with 1.5.1. 167 of 445 tests |
|
| | | | | 401 of 454 tests should pass. |
|
||||||
| | | | should pass. |
|
+-----------+--------+--------+--------+--------------------------------------+
|
||||||
+------------+------------+------------+--------------------------------------+
|
| Fedora 18 | | | X | Ships with 1.5.1. 169 of 449 tests |
|
||||||
| Fedora 17 | X | | Ships with 1.4. Should error out |
|
| | | | | should pass. |
|
||||||
| | | | gracefully. |
|
+-----------+--------+--------+--------+--------------------------------------+
|
||||||
+------------+------------+------------+--------------------------------------+
|
| Fedora 17 | | X | | Ships with 1.4.0. 169 of 449 tests |
|
||||||
|
| | | | | should pass. |
|
||||||
|
+-----------+--------+--------+--------+--------------------------------------+
|
||||||
|
| CentOS | X | | | Ships with 1.3.0. 167 of 449 tests |
|
||||||
|
| 6.3 | | | | should pass. |
|
||||||
|
+-----------+--------+--------+--------+--------------------------------------+
|
||||||
|
| Raspberry | | X | | Ships with 1.3.0. 169 of 449 tests |
|
||||||
|
| Pi | | | | should pass. |
|
||||||
|
| Debian 7 | | | | |
|
||||||
|
+-----------+--------+--------+--------+--------------------------------------+
|
||||||
|
|
||||||
Pylint on entire package should be at least 0.95.
|
Pylint on entire package should exceed 0.95.
|
||||||
pep8 should be pass cleanly.
|
pep8 should be pass cleanly.
|
||||||
Coverage should exceed 95%.
|
Coverage should exceed 95%.
|
||||||
|
|
|
||||||
11
setup.py
11
setup.py
|
|
@ -2,26 +2,31 @@ from setuptools import setup, find_packages
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
kwargs = {'name': 'Glymur',
|
kwargs = {'name': 'Glymur',
|
||||||
'version': '0.2.2',
|
'version': '0.2.3',
|
||||||
'description': 'Tools for accessing JPEG2000 files',
|
'description': 'Tools for accessing JPEG2000 files',
|
||||||
'long_description': open('README.md').read(),
|
'long_description': open('README.md').read(),
|
||||||
'author': 'John Evans',
|
'author': 'John Evans',
|
||||||
'author_email': 'johnevans938 at gmail dot com',
|
'author_email': 'john.g.evans.ne at gmail dot com',
|
||||||
'url': 'https://github.com/quintusdias/glymur',
|
'url': 'https://github.com/quintusdias/glymur',
|
||||||
'packages': ['glymur', 'glymur.data', 'glymur.test', 'glymur.lib',
|
'packages': ['glymur', 'glymur.data', 'glymur.test', 'glymur.lib',
|
||||||
'glymur.lib.test'],
|
'glymur.lib.test'],
|
||||||
'package_data': {'glymur': ['data/*.jp2', 'data/*.j2k']},
|
'package_data': {'glymur': ['data/*.jp2', 'data/*.j2k']},
|
||||||
'scripts': ['bin/jp2dump'],
|
'scripts': ['bin/jp2dump'],
|
||||||
'license': 'LICENSE.txt',
|
'license': 'LICENSE.txt',
|
||||||
|
'test_suite': 'glymur.test',
|
||||||
'platforms': ['darwin']}
|
'platforms': ['darwin']}
|
||||||
|
|
||||||
instllrqrs = ['numpy>1.6.2']
|
instllrqrs = ['numpy>=1.4.1']
|
||||||
if sys.hexversion < 0x03030000:
|
if sys.hexversion < 0x03030000:
|
||||||
instllrqrs.append('contextlib2>=0.4')
|
instllrqrs.append('contextlib2>=0.4')
|
||||||
instllrqrs.append('mock>=1.0.1')
|
instllrqrs.append('mock>=1.0.1')
|
||||||
|
if sys.hexversion < 0x02070000:
|
||||||
|
instllrqrs.append('ordereddict>=1.1')
|
||||||
|
instllrqrs.append('unittest2>=0.5.1')
|
||||||
kwargs['install_requires'] = instllrqrs
|
kwargs['install_requires'] = instllrqrs
|
||||||
|
|
||||||
clssfrs = ["Programming Language :: Python",
|
clssfrs = ["Programming Language :: Python",
|
||||||
|
"Programming Language :: Python :: 2.6",
|
||||||
"Programming Language :: Python :: 2.7",
|
"Programming Language :: Python :: 2.7",
|
||||||
"Programming Language :: Python :: 3.3",
|
"Programming Language :: Python :: 3.3",
|
||||||
"Programming Language :: Python :: Implementation :: CPython",
|
"Programming Language :: Python :: Implementation :: CPython",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue