Merge branch 'master' into devel
This commit is contained in:
commit
f016bf69cb
13 changed files with 242 additions and 130 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.0 Support for Python 2.7 on windows, OpenJPEG 1.5.1.
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ copyright = u'2013, John Evans'
|
|||
# The short X.Y version.
|
||||
version = '0.1'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.2.2'
|
||||
release = '0.2.3'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ Glymur Configuration
|
|||
''''''''''''''''''''''
|
||||
|
||||
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
|
||||
of more of glymur's features, you should compile OpenJPEG as a shared
|
||||
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
|
||||
because ctypes access libraries in a platform-dependent manner, it is
|
||||
recommended that you create a configuration file to help Glymur properly find
|
||||
the openjp2 library. You may create the configuration file as follows::
|
||||
the openjp2 library. The configuration format is the same as used by Python's
|
||||
configparser module, i.e. ::
|
||||
|
||||
$ mkdir -p ~/.config/glymur
|
||||
$ cd ~/.config/glymur
|
||||
$ cat > glymurrc << EOF
|
||||
> [library]
|
||||
> openjp2: /opt/openjp2-svn/lib/libopenjp2.so
|
||||
> EOF
|
||||
[library]
|
||||
openjp2: /opt/openjp2-svn/lib/libopenjp2.so
|
||||
|
||||
This assumes, of course, that you've installed OpenJPEG into
|
||||
/opt/openjp2-svn on a linux system. You may also substitute
|
||||
**$XDG_CONFIG_HOME** for **$HOME/.config**.
|
||||
|
||||
You may also include a line for the version 1.5.1 library if you have it installed
|
||||
in a non-standard place, i.e. ::
|
||||
You may also include a line for the version 1.x openjpeg library if you have it
|
||||
installed in a non-standard place, i.e. ::
|
||||
|
||||
[library]
|
||||
openjp2: /opt/openjp2-svn/lib/libopenjp2.so
|
||||
|
|
@ -91,11 +88,14 @@ meet the minimal set of requirements for running glymur.
|
|||
* python3
|
||||
* python3-numpy
|
||||
* 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)
|
||||
|
||||
Pillow is also needed in order to run the maximum number of tests, so
|
||||
go ahead and install Pillow via pip since Pillow is not yet available
|
||||
go ahead and install Pillow via pip since Pillow is not available
|
||||
in Fedora 18 default repositories::
|
||||
|
||||
$ yum install python3-devel # pip needs this in order to compile Pillow
|
||||
|
|
@ -105,29 +105,20 @@ in Fedora 18 default repositories::
|
|||
|
||||
Fedora 17
|
||||
'''''''''
|
||||
Fedora 17 ships with Python 2.7 and OpenJPEG 1.4.
|
||||
|
||||
Required RPMs include::
|
||||
Fedora 17 ships with Python 2.7 and OpenJPEG 1.4. You should have the
|
||||
following RPMs installed.
|
||||
|
||||
* python
|
||||
* python-mock
|
||||
* python-pip
|
||||
* python-setuptools
|
||||
* numpy
|
||||
* matplotlib (optional)
|
||||
|
||||
In addition, you must install contextlib2 via pip.
|
||||
|
||||
A few tests still will not run, however, unless one of the following
|
||||
combinations of RPMs / Python packages is installed.
|
||||
|
||||
* 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::
|
||||
In addition, you must install contextlib2 and Pillow via pip.
|
||||
|
||||
$ yum install python-devel # pip needs this in order to compile Pillow
|
||||
$ pip-python3 install Pillow --user
|
||||
$ pip-python install Pillow --user
|
||||
$ pip-python install contextlib2 --user
|
||||
$ 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
|
||||
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
|
||||
no box argument: ::
|
||||
codestream provided by `goodstuff.j2k` (a file consisting of a raw codestream),
|
||||
you can use the **wrap** method with no box argument: ::
|
||||
|
||||
>>> import glymur
|
||||
>>> jfile = glymur.data.goodstuff()
|
||||
|
|
@ -119,6 +119,68 @@ and add it after the JP2 header box, but before the codestream box ::
|
|||
. (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?
|
||||
====================
|
||||
The example JP2 file shipped with glymur has an XMP UUID. ::
|
||||
|
|
|
|||
|
|
@ -18,17 +18,19 @@ Glymur works on Python 2.6, 2.7, and 3.3. Python 3.3 is strongly recommended.
|
|||
|
||||
OpenJPEG Installation
|
||||
=====================
|
||||
The OpenJPEG library version should be 1.4, 1.5, or the trunk/development
|
||||
OpenJPEG should be version 1.4, 1.5, or the trunk/development
|
||||
version of OpenJPEG. The official 2.0.0 release or versions earlier than 1.3.0
|
||||
are not supported. Furthermore, the 1.4 and 1.5 versions of OpenJPEG are
|
||||
currently only utilized for read-only purposes. For more information
|
||||
are not supported. Furthermore, the 1.X versions of OpenJPEG are
|
||||
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.
|
||||
|
||||
If you use MacPorts on the mac or if you have a sufficiently recent version of
|
||||
Linux, your package manager should already provide you with a version
|
||||
of OpenJPEG with which glymur can already use. If your platform is
|
||||
windows, I suggest using the 1.5.1 windows installer provided to you by
|
||||
the OpenJPEG folks at https://code.google.com/p/openjpeg/downloads/list .
|
||||
If you use MacPorts on the mac or if you have a sufficiently recent
|
||||
version of Linux, your package manager should already provide you
|
||||
with a version of OpenJPEG 1.X with which glymur can already use
|
||||
for read-only purposes. If your platform is windows, I suggest
|
||||
using the 1.5.1 windows installer provided to you by the OpenJPEG
|
||||
folks at https://code.google.com/p/openjpeg/downloads/list .
|
||||
|
||||
Glymur Installation
|
||||
===================
|
||||
|
|
|
|||
|
|
@ -43,14 +43,14 @@ _COLORSPACE_MAP_DISPLAY = {
|
|||
ROMM_RGB: 'ROMM-RGB'}
|
||||
|
||||
# enumerated color channel types
|
||||
_COLOR = 0
|
||||
_OPACITY = 1
|
||||
_PRE_MULTIPLIED_OPACITY = 2
|
||||
COLOR = 0
|
||||
OPACITY = 1
|
||||
PRE_MULTIPLIED_OPACITY = 2
|
||||
_UNSPECIFIED = 65535
|
||||
_COLOR_TYPE_MAP_DISPLAY = {
|
||||
_COLOR: 'color',
|
||||
_OPACITY: 'opacity',
|
||||
_PRE_MULTIPLIED_OPACITY: 'pre-multiplied opacity',
|
||||
COLOR: 'color',
|
||||
OPACITY: 'opacity',
|
||||
PRE_MULTIPLIED_OPACITY: 'pre-multiplied opacity',
|
||||
_UNSPECIFIED: 'unspecified'}
|
||||
|
||||
# color channel definitions.
|
||||
|
|
@ -58,6 +58,7 @@ RED = 1
|
|||
GREEN = 2
|
||||
BLUE = 3
|
||||
GREY = 1
|
||||
WHOLE_IMAGE = 0
|
||||
|
||||
# enumerated color channel associations
|
||||
_COLORSPACE = {SRGB: {"R": 1, "G": 2, "B": 3},
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ References
|
|||
import copy
|
||||
import datetime
|
||||
import math
|
||||
import os
|
||||
import pprint
|
||||
import struct
|
||||
import sys
|
||||
|
|
@ -73,9 +74,6 @@ class Jp2kBox(object):
|
|||
self.offset = offset
|
||||
self.longname = longname
|
||||
|
||||
# should never be used except maybe for last box in file.
|
||||
self._file_size = -1
|
||||
|
||||
def __str__(self):
|
||||
msg = "{0} Box ({1})".format(self.longname, self.box_id)
|
||||
msg += " @ ({0}, {1})".format(self.offset, self.length)
|
||||
|
|
@ -118,7 +116,7 @@ class Jp2kBox(object):
|
|||
if box_length == 0:
|
||||
# The length of the box is presumed to last until the end of
|
||||
# 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:
|
||||
# The length of the box is in the XL field, a 64-bit value.
|
||||
|
|
@ -428,14 +426,24 @@ class ChannelDefinitionBox(Jp2kBox):
|
|||
longname : str
|
||||
more verbose description of the box.
|
||||
index : int
|
||||
number of the channel
|
||||
number of the channel. Defaults to monotonically increasing sequence,
|
||||
i.e. [0, 1, 2, ...]
|
||||
channel_type : int
|
||||
type of the channel
|
||||
association : int
|
||||
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')
|
||||
|
||||
# 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):
|
||||
msg = "Length of channel definition box inputs must be the same."
|
||||
raise IOError(msg)
|
||||
|
|
@ -506,8 +514,9 @@ class ChannelDefinitionBox(Jp2kBox):
|
|||
channel_type = data[1:num_components * 6:3]
|
||||
association = data[2:num_components * 6:3]
|
||||
|
||||
box = ChannelDefinitionBox(index, channel_type, association,
|
||||
length=length, offset=offset)
|
||||
box = ChannelDefinitionBox(index=index, channel_type=channel_type,
|
||||
association=association, length=length,
|
||||
offset=offset)
|
||||
return box
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,6 @@ class Jp2k(Jp2kBox):
|
|||
self.mode = mode
|
||||
self.box = []
|
||||
self._codec_format = None
|
||||
self._file_size = 0
|
||||
|
||||
# Parse the file for JP2/JPX contents only if we are reading it.
|
||||
if mode == 'rb':
|
||||
|
|
@ -126,7 +125,6 @@ class Jp2k(Jp2kBox):
|
|||
The file was not JPEG 2000.
|
||||
"""
|
||||
self.length = os.path.getsize(self.filename)
|
||||
self._file_size = os.path.getsize(self.filename)
|
||||
|
||||
with open(self.filename, 'rb') as fptr:
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ def 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]
|
||||
_MINOR = version().split('.')[1]
|
||||
|
||||
|
||||
class EventMgrType(ctypes.Structure):
|
||||
|
|
@ -103,7 +103,7 @@ class DecompressionParametersType(ctypes.Structure):
|
|||
# entire codestream or be limited to the main header
|
||||
("cp_limit_decoding", ctypes.c_int)]
|
||||
|
||||
if _minor != '4':
|
||||
if _MINOR == '5':
|
||||
_fields_.append(("flags", ctypes.c_uint))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ import pkg_resources
|
|||
import glymur
|
||||
from glymur import Jp2k
|
||||
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.
|
||||
|
|
@ -84,12 +86,19 @@ class TestChannelDefinition(unittest.TestCase):
|
|||
def tearDown(self):
|
||||
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."""
|
||||
j2k = Jp2k(self.j2kfile)
|
||||
channel_type = [COLOR, COLOR, COLOR]
|
||||
association = [RED, GREEN, BLUE]
|
||||
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2],
|
||||
channel_type=[0, 0, 0],
|
||||
association=[1, 2, 3])
|
||||
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]
|
||||
|
|
@ -101,15 +110,41 @@ class TestChannelDefinition(unittest.TestCase):
|
|||
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, (0, 0, 0))
|
||||
self.assertEqual(jp2h.box[2].association, (1, 2, 3))
|
||||
self.assertEqual(jp2h.box[2].channel_type,
|
||||
(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):
|
||||
"""Just regular RGBA."""
|
||||
j2k = Jp2k(self.four_planes)
|
||||
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2, 3],
|
||||
channel_type=[0, 0, 0, 1],
|
||||
association=[1, 2, 3, 0])
|
||||
channel_type = (COLOR, COLOR, COLOR, OPACITY)
|
||||
association = (RED, GREEN, BLUE, WHOLE_IMAGE)
|
||||
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]
|
||||
|
|
@ -121,15 +156,16 @@ class TestChannelDefinition(unittest.TestCase):
|
|||
boxes = [box.box_id for box in jp2h.box]
|
||||
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
||||
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].association, (1, 2, 3, 0))
|
||||
self.assertEqual(jp2h.box[2].channel_type, channel_type)
|
||||
self.assertEqual(jp2h.box[2].association, association)
|
||||
|
||||
def test_bad_rgba(self):
|
||||
"""R, G, and B must be specified."""
|
||||
j2k = Jp2k(self.four_planes)
|
||||
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2, 3],
|
||||
channel_type=[0, 0, 1, 1],
|
||||
association=[1, 2, 3, 0])
|
||||
channel_type = (COLOR, COLOR, OPACITY, OPACITY)
|
||||
association = (RED, GREEN, BLUE, WHOLE_IMAGE)
|
||||
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]
|
||||
|
|
@ -140,9 +176,10 @@ class TestChannelDefinition(unittest.TestCase):
|
|||
def test_grey(self):
|
||||
"""Just regular greyscale."""
|
||||
j2k = Jp2k(self.one_plane)
|
||||
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0],
|
||||
channel_type=[0],
|
||||
association=[1])
|
||||
channel_type = (COLOR,)
|
||||
association = (GREY,)
|
||||
cdef = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
|
||||
association=association)
|
||||
boxes = [self.ihdr, self.colr_gr, cdef]
|
||||
self.jp2h.box = boxes
|
||||
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c]
|
||||
|
|
@ -154,15 +191,16 @@ class TestChannelDefinition(unittest.TestCase):
|
|||
boxes = [box.box_id for box in jp2h.box]
|
||||
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
||||
self.assertEqual(jp2h.box[2].index, (0,))
|
||||
self.assertEqual(jp2h.box[2].channel_type, (0,))
|
||||
self.assertEqual(jp2h.box[2].association, (1,))
|
||||
self.assertEqual(jp2h.box[2].channel_type, channel_type)
|
||||
self.assertEqual(jp2h.box[2].association, association)
|
||||
|
||||
def test_grey_alpha(self):
|
||||
"""Just regular greyscale plus alpha."""
|
||||
j2k = Jp2k(self.two_planes)
|
||||
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0, 1],
|
||||
channel_type=[0, 1],
|
||||
association=[1, 0])
|
||||
channel_type = (COLOR, OPACITY)
|
||||
association = (GREY, WHOLE_IMAGE)
|
||||
cdef = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
|
||||
association=association)
|
||||
boxes = [self.ihdr, self.colr_gr, cdef]
|
||||
self.jp2h.box = boxes
|
||||
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c]
|
||||
|
|
@ -174,17 +212,19 @@ class TestChannelDefinition(unittest.TestCase):
|
|||
boxes = [box.box_id for box in jp2h.box]
|
||||
self.assertEqual(boxes, ['ihdr', 'colr', 'cdef'])
|
||||
self.assertEqual(jp2h.box[2].index, (0, 1))
|
||||
self.assertEqual(jp2h.box[2].channel_type, (0, 1))
|
||||
self.assertEqual(jp2h.box[2].association, (1, 0))
|
||||
self.assertEqual(jp2h.box[2].channel_type, channel_type)
|
||||
self.assertEqual(jp2h.box[2].association, association)
|
||||
|
||||
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)
|
||||
|
||||
channel_type = (OPACITY, OPACITY)
|
||||
association = (GREY, WHOLE_IMAGE)
|
||||
|
||||
# This cdef box
|
||||
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0, 1],
|
||||
channel_type=[1, 1],
|
||||
association=[0, 1])
|
||||
cdef = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
|
||||
association=association)
|
||||
boxes = [self.ihdr, self.colr_gr, cdef]
|
||||
self.jp2h.box = boxes
|
||||
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c]
|
||||
|
|
@ -196,9 +236,10 @@ class TestChannelDefinition(unittest.TestCase):
|
|||
"""There can only be one channel definition box in the jp2 header."""
|
||||
j2k = Jp2k(self.j2kfile)
|
||||
|
||||
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2],
|
||||
channel_type=[0, 0, 0],
|
||||
association=[1, 2, 3])
|
||||
channel_type = (COLOR, COLOR, COLOR)
|
||||
association = (RED, GREEN, BLUE)
|
||||
cdef = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
|
||||
association=association)
|
||||
|
||||
boxes = [self.ihdr, cdef, self.colr_rgb, cdef]
|
||||
self.jp2h.box = boxes
|
||||
|
|
@ -214,9 +255,10 @@ class TestChannelDefinition(unittest.TestCase):
|
|||
boxes = [self.ihdr, self.colr_rgb]
|
||||
self.jp2h.box = boxes
|
||||
|
||||
cdef = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2],
|
||||
channel_type=[0, 0, 0],
|
||||
association=[1, 2, 3])
|
||||
channel_type = (COLOR, COLOR, COLOR)
|
||||
association = (RED, GREEN, BLUE)
|
||||
cdef = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
|
||||
association=association)
|
||||
|
||||
boxes = [self.jP, self.ftyp, self.jp2h, cdef, self.jp2c]
|
||||
|
||||
|
|
@ -228,18 +270,20 @@ class TestChannelDefinition(unittest.TestCase):
|
|||
# Channel types are limited to 0, 1, 2, 65535
|
||||
# Should reject if not all of index, channel_type, association the
|
||||
# same length.
|
||||
channel_type = (COLOR, COLOR, 3)
|
||||
association = (RED, GREEN, BLUE)
|
||||
with self.assertRaises(IOError):
|
||||
box = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2],
|
||||
channel_type=[0, 0, 3],
|
||||
association=[1, 2, 3])
|
||||
box = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
|
||||
association=association)
|
||||
|
||||
def test_wrong_lengths(self):
|
||||
# Should reject if not all of index, channel_type, association the
|
||||
# same length.
|
||||
channel_type = (COLOR, COLOR)
|
||||
association = (RED, GREEN, BLUE)
|
||||
with self.assertRaises(IOError):
|
||||
box = glymur.jp2box.ChannelDefinitionBox(index=[0, 1, 2],
|
||||
channel_type=[0, 0],
|
||||
association=[1, 2, 3])
|
||||
box = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
|
||||
association=association)
|
||||
|
||||
|
||||
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
|
||||
|
|
@ -427,6 +471,7 @@ class TestJp2Boxes(unittest.TestCase):
|
|||
|
||||
def setUp(self):
|
||||
self.j2kfile = glymur.data.goodstuff()
|
||||
self.jp2file = glymur.data.nemo()
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
|
@ -522,7 +567,7 @@ class TestJp2Boxes(unittest.TestCase):
|
|||
|
||||
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
|
||||
def test_wrap_jp2(self):
|
||||
j2k = Jp2k(self.j2kfile)
|
||||
j2k = Jp2k(self.jp2file)
|
||||
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
|
||||
jp2 = j2k.wrap(tfile.name)
|
||||
boxes = [box.box_id for box in jp2.box]
|
||||
|
|
|
|||
69
release.txt
69
release.txt
|
|
@ -1,37 +1,38 @@
|
|||
| 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. At least 282 of 444 |
|
||||
| | | | | tests should pass. |
|
||||
+---------+--------+--------+--------+---------------------------------------+
|
||||
| Mac | X | | | MacPorts with both OpenJPEG 1.5.1 |
|
||||
| | | | | and OpenJPEG svn. 342 of 451 tests |
|
||||
| | | | | should pass. |
|
||||
+---------+--------+--------+--------+---------------------------------------+
|
||||
| Mac | | X | | MacPorts with both OpenJPEG 1.5.1 |
|
||||
| | | | | and OpenJPEG svn. 373 of 451 tests |
|
||||
| | | | | should pass. |
|
||||
+---------+--------+--------+--------+---------------------------------------+
|
||||
| Mac | | | X | MacPorts with both OpenJPEG 1.5.1 |
|
||||
| | | | | and OpenJPEG svn. 398 of 451 |
|
||||
| | | | | tests should pass. |
|
||||
+---------+--------+--------+------------------------------------------------+
|
||||
| Fedora | | | X | Ships with 1.5.1. 390 of 450 tests |
|
||||
| 19 | | | | should pass. |
|
||||
+---------+--------+--------+--------+---------------------------------------+
|
||||
| Fedora | | | X | Ships with 1.5.1. 167 of 445 tests |
|
||||
| 18 | | | | should pass. |
|
||||
+---------+--------+--------+--------+---------------------------------------+
|
||||
| Fedora | | X | | Ships with 1.4.0. 167 of 445 tests |
|
||||
| 17 | | | | should pass. |
|
||||
+---------+--------+--------+--------+---------------------------------------+
|
||||
| CentOS | X | | | Ships with 1.3.0. 165 of 445 tests |
|
||||
| 6.3 | | | | should pass. |
|
||||
+---------+--------+--------+--------+---------------------------------------+
|
||||
| OS | Python | Python | Python | Notes |
|
||||
| | 2.6 | 2.7 | 3.3 | |
|
||||
+-----------+--------+--------+--------+--------------------------------------+
|
||||
| Windows | | X | | Python(xy) with OpenJPEG 1.5.1 and |
|
||||
| | | | | OpenJPEG svn. 285 of 448 tests |
|
||||
| | | | | pass. |
|
||||
+-----------+--------+--------+--------+--------------------------------------+
|
||||
| Mac | X | | | MacPorts with both OpenJPEG 1.5.1 |
|
||||
| 10.6.8 | | | | and OpenJPEG svn. 353 of 449 tests |
|
||||
| | | | | should pass. |
|
||||
+-----------+--------+--------+--------+--------------------------------------+
|
||||
| Mac | | X | | MacPorts with both OpenJPEG 1.5.1 |
|
||||
| 10.6.8 | | | | and OpenJPEG svn. 376 of 454 tests |
|
||||
| | | | | should pass. |
|
||||
+-----------+--------+--------+--------+--------------------------------------+
|
||||
| Mac | | | X | MacPorts with both OpenJPEG 1.5.1 |
|
||||
| 10.6.8 | | | | and OpenJPEG svn. 401 of 454 |
|
||||
| | | | | tests should pass. |
|
||||
+-----------+--------+--------+-----------------------------------------------+
|
||||
| Fedora 19 | | | X | Ships with 1.5.1, openjp2 built too. |
|
||||
| | | | | 401 of 454 tests should pass. |
|
||||
+-----------+--------+--------+--------+--------------------------------------+
|
||||
| Fedora 18 | | | X | Ships with 1.5.1. 169 of 449 tests |
|
||||
| | | | | should pass. |
|
||||
+-----------+--------+--------+--------+--------------------------------------+
|
||||
| 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 exceed 0.95.
|
||||
pep8 should be pass cleanly.
|
||||
|
|
|
|||
2
setup.py
2
setup.py
|
|
@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|||
import sys
|
||||
|
||||
kwargs = {'name': 'Glymur',
|
||||
'version': '0.2.2',
|
||||
'version': '0.2.3',
|
||||
'description': 'Tools for accessing JPEG2000 files',
|
||||
'long_description': open('README.md').read(),
|
||||
'author': 'John Evans',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue