diff --git a/glymur/_uuid_io/Exif.py b/glymur/_uuid_io/Exif.py
index 967468d..b07cd42 100644
--- a/glymur/_uuid_io/Exif.py
+++ b/glymur/_uuid_io/Exif.py
@@ -3,6 +3,7 @@
Handlers for Exif UUIDs. Be nice if we would find a standard for this.
"""
import pprint
+import re
import struct
import sys
import warnings
diff --git a/glymur/codestream.py b/glymur/codestream.py
index d01795f..67b2d56 100644
--- a/glymur/codestream.py
+++ b/glymur/codestream.py
@@ -663,7 +663,7 @@ class Codestream(object):
bitdepth = tuple(((x & 0x7f) + 1) for x in data[0::3])
signed = tuple(((x & 0xb0) > 0) for x in data[0::3])
-
+
xrsiz = data[1::3]
yrsiz = data[2::3]
@@ -1529,7 +1529,7 @@ class SIZsegment(Segment):
signed=self.signed,
xyrsiz=(self.xrsiz, self.yrsiz))
return msg
-
+
def __str__(self):
msg = Segment.__str__(self)
msg += '\n '
diff --git a/glymur/jp2box.py b/glymur/jp2box.py
index da8e1c9..b3fcf89 100644
--- a/glymur/jp2box.py
+++ b/glymur/jp2box.py
@@ -19,7 +19,6 @@ import os
import pprint
import struct
import sys
-import traceback
import uuid
import warnings
import xml.etree.cElementTree as ET
@@ -563,11 +562,11 @@ class CodestreamHeaderBox(Jp2kBox):
box : list
List of boxes contained in this superbox.
"""
- def __init__(self, box=[], length=0, offset=-1):
+ def __init__(self, box=None, length=0, offset=-1):
Jp2kBox.__init__(self, box_id='jpch', longname='Codestream Header')
self.length = length
self.offset = offset
- self.box = box
+ self.box = box if box is not None else []
def __repr__(self):
msg = "glymur.jp2box.CodestreamHeaderBox(box={0})".format(self.box)
@@ -625,12 +624,12 @@ class CompositingLayerHeaderBox(Jp2kBox):
box : list
List of boxes contained in this superbox.
"""
- def __init__(self, box=[], length=0, offset=-1):
+ def __init__(self, box=None, length=0, offset=-1):
Jp2kBox.__init__(self, box_id='jplh',
longname='Compositing Layer Header')
self.length = length
self.offset = offset
- self.box = []
+ self.box = box if box is not None else []
def __repr__(self):
msg = "glymur.jp2box.CompositingLayerHeaderBox(box={0})"
@@ -1073,11 +1072,11 @@ class AssociationBox(Jp2kBox):
box : list
List of boxes contained in this superbox.
"""
- def __init__(self, box=[], length=0, offset=-1):
+ def __init__(self, box=None, length=0, offset=-1):
Jp2kBox.__init__(self, box_id='asoc', longname='Association')
self.length = length
self.offset = offset
- self.box = box
+ self.box = box if box is not None else []
def __repr__(self):
msg = "glymur.jp2box.AssociationBox(box={0})".format(self.box)
@@ -1135,11 +1134,11 @@ class JP2HeaderBox(Jp2kBox):
box : list
List of boxes contained in this superbox.
"""
- def __init__(self, box=[], length=0, offset=-1):
+ def __init__(self, box=None, length=0, offset=-1):
Jp2kBox.__init__(self, box_id='jp2h', longname='JP2 Header')
self.length = length
self.offset = offset
- self.box = box
+ self.box = box if box is not None else []
def __repr__(self):
msg = "glymur.jp2box.JP2HeaderBox(box={0})".format(self.box)
@@ -1621,11 +1620,11 @@ class ResolutionBox(Jp2kBox):
box : list
List of boxes contained in this superbox.
"""
- def __init__(self, box=[], length=0, offset=-1):
+ def __init__(self, box=None, length=0, offset=-1):
Jp2kBox.__init__(self, box_id='res ', longname='Resolution')
self.length = length
self.offset = offset
- self.box = box
+ self.box = box if box is not None else []
def __repr__(self):
msg = "glymur.jp2box.ResolutionBox(box={0})"
@@ -2040,11 +2039,11 @@ class UUIDInfoBox(Jp2kBox):
box : list
List of boxes contained in this superbox.
"""
- def __init__(self, box=[], length=0, offset=-1):
+ def __init__(self, box=None, length=0, offset=-1):
Jp2kBox.__init__(self, box_id='uinf', longname='UUIDInfo')
self.length = length
self.offset = offset
- self.box = box
+ self.box = box if box is not None else []
def __repr__(self):
msg = "glymur.jp2box.UUIDInfoBox(box={0})".format(self.box)
diff --git a/glymur/jp2k.py b/glymur/jp2k.py
index a337ae7..4eb8b2a 100644
--- a/glymur/jp2k.py
+++ b/glymur/jp2k.py
@@ -484,17 +484,17 @@ class Jp2k(Jp2kBox):
stack.callback(opj2.image_destroy, image)
_populate_image_struct(cparams, image, img_array)
-
+
codec = opj2.create_compress(cparams.codec_fmt)
stack.callback(opj2.destroy_codec, codec)
-
+
info_handler = _INFO_CALLBACK if verbose else None
opj2.set_info_handler(codec, info_handler)
opj2.set_warning_handler(codec, _WARNING_CALLBACK)
opj2.set_error_handler(codec, _ERROR_CALLBACK)
-
+
opj2.setup_encoder(codec, cparams, image)
-
+
if _OPENJP2_IS_OFFICIAL_V2:
fptr = libc.fopen(self.filename, 'wb')
strm = opj2.stream_create_default_file_stream(fptr, False)
@@ -505,11 +505,11 @@ class Jp2k(Jp2kBox):
strm = opj2.stream_create_default_file_stream_v3(self.filename,
False)
stack.callback(opj2.stream_destroy_v3, strm)
-
+
opj2.start_compress(codec, image, strm)
opj2.encode(codec, strm)
opj2.end_compress(codec, strm)
-
+
# Refresh the metadata.
self.parse()
diff --git a/glymur/lib/openjpeg.py b/glymur/lib/openjpeg.py
index 5b1183f..418e9df 100644
--- a/glymur/lib/openjpeg.py
+++ b/glymur/lib/openjpeg.py
@@ -11,8 +11,8 @@ import numpy as np
from .config import glymur_config
_, OPENJPEG = glymur_config()
-# Maximum number of tile parts expected by JPWL: increase at your will
-JPWL_MAX_NO_TILESPECS = 16
+# Maximum number of tile parts expected by JPWL: increase at your will
+JPWL_MAX_NO_TILESPECS = 16
J2K_MAXRLVLS = 33 # Number of maximum resolution level authorized
PATH_LEN = 4096 # maximum allowed size for filenames
@@ -58,7 +58,7 @@ class CommonStructType(ctypes.Structure):
("mj2_handle", ctypes.c_void_p)]
-STREAM_READ = 0x0001 # The stream was opened for reading.
+STREAM_READ = 0x0001 # The stream was opened for reading.
STREAM_WRITE = 0x0002 # The stream was opened for writing.
class CioType(ctypes.Structure):
"""Byte input-output stream (CIO)
@@ -81,7 +81,7 @@ class CioType(ctypes.Structure):
class CompressionInfoType(CommonStructType):
- """Common fields between JPEG-2000 compression and decompression contexts.
+ """Common fields between JPEG-2000 compression and decompression contexts.
This is for compression contexts. Corresponds to common_struct_t.
"""
pass
@@ -91,68 +91,68 @@ class PocType(ctypes.Structure):
"""Progression order changes."""
_fields_ = [("resno", ctypes.c_int),
# Resolution num start, Component num start, given by POC
- ("compno0", ctypes.c_int),
+ ("compno0", ctypes.c_int),
# Layer num end,Resolution num end, Component num end, given by POC
- ("layno1", ctypes.c_int),
- ("resno1", ctypes.c_int),
- ("compno1", ctypes.c_int),
+ ("layno1", ctypes.c_int),
+ ("resno1", ctypes.c_int),
+ ("compno1", ctypes.c_int),
- # Layer num start,Precinct num start, Precinct num end
- ("layno0", ctypes.c_int),
- ("precno0", ctypes.c_int),
- ("precno1", ctypes.c_int),
+ # Layer num start,Precinct num start, Precinct num end
+ ("layno0", ctypes.c_int),
+ ("precno0", ctypes.c_int),
+ ("precno1", ctypes.c_int),
# Progression order enum
# OPJ_PROG_ORDER prg1,prg;
- ("prg1", ctypes.c_int),
- ("prg", ctypes.c_int),
+ ("prg1", ctypes.c_int),
+ ("prg", ctypes.c_int),
- # Progression order string
+ # Progression order string
# char progorder[5];
("progorder", ctypes.c_char * 5),
- # Tile number
+ # Tile number
# int tile;
- ("tile", ctypes.c_int),
+ ("tile", ctypes.c_int),
# /** Start and end values for Tile width and height*/
# int tx0,tx1,ty0,ty1;
- ("tx0", ctypes.c_int),
- ("tx1", ctypes.c_int),
- ("ty0", ctypes.c_int),
- ("ty1", ctypes.c_int),
+ ("tx0", ctypes.c_int),
+ ("tx1", ctypes.c_int),
+ ("ty0", ctypes.c_int),
+ ("ty1", ctypes.c_int),
# /** Start value, initialised in pi_initialise_encode*/
# int layS, resS, compS, prcS;
- ("layS", ctypes.c_int),
- ("resS", ctypes.c_int),
- ("compS", ctypes.c_int),
+ ("layS", ctypes.c_int),
+ ("resS", ctypes.c_int),
+ ("compS", ctypes.c_int),
("prcS", ctypes.c_int),
# /** End value, initialised in pi_initialise_encode */
# int layE, resE, compE, prcE;
- ("layE", ctypes.c_int),
- ("resE", ctypes.c_int),
- ("compE", ctypes.c_int),
- ("prcE", ctypes.c_int),
+ ("layE", ctypes.c_int),
+ ("resE", ctypes.c_int),
+ ("compE", ctypes.c_int),
+ ("prcE", ctypes.c_int),
# Start and end values of Tile width and height, initialised in
# pi_initialise_encode int txS,txE,tyS,tyE,dx,dy;
- ("txS", ctypes.c_int),
- ("txE", ctypes.c_int),
- ("tyS", ctypes.c_int),
- ("tyE", ctypes.c_int),
- ("dx", ctypes.c_int),
- ("dy", ctypes.c_int),
+ ("txS", ctypes.c_int),
+ ("txE", ctypes.c_int),
+ ("tyS", ctypes.c_int),
+ ("tyE", ctypes.c_int),
+ ("dx", ctypes.c_int),
+ ("dy", ctypes.c_int),
- # Temporary values for Tile parts, initialised in pi_create_encode
+ # Temporary values for Tile parts, initialised in pi_create_encode
# int lay_t, res_t, comp_t, prc_t,tx0_t,ty0_t;
- ("lay_t", ctypes.c_int),
- ("res_t", ctypes.c_int),
- ("comp_t", ctypes.c_int),
- ("prc_t", ctypes.c_int),
- ("tx0_t", ctypes.c_int),
+ ("lay_t", ctypes.c_int),
+ ("res_t", ctypes.c_int),
+ ("comp_t", ctypes.c_int),
+ ("prc_t", ctypes.c_int),
+ ("tx0_t", ctypes.c_int),
("ty0_t", ctypes.c_int)]
@@ -374,23 +374,23 @@ class DecompressionParametersType(ctypes.Structure):
class ImageComptParmType(ctypes.Structure):
"""Component parameters structure used by the opj_image_create function.
"""
- _fields_ = [
- # XRsiz: horizontal separation of a sample of ith component with
- # respect to the reference grid
- ("dx", ctypes.c_int),
+ _fields_ = [
+ # XRsiz: horizontal separation of a sample of ith component with
+ # respect to the reference grid
+ ("dx", ctypes.c_int),
- # YRsiz: vertical separation of a sample of ith component with
+ # YRsiz: vertical separation of a sample of ith component with
# respect to the reference grid */
- ("dy", ctypes.c_int),
-
- # data width, height
- ("w", ctypes.c_int),
- ("h", ctypes.c_int),
+ ("dy", ctypes.c_int),
- # x component offset compared to the whole image
- # y component offset compared to the whole image
- ("x0", ctypes.c_int),
- ("y0", ctypes.c_int),
+ # data width, height
+ ("w", ctypes.c_int),
+ ("h", ctypes.c_int),
+
+ # x component offset compared to the whole image
+ # y component offset compared to the whole image
+ ("x0", ctypes.c_int),
+ ("y0", ctypes.c_int),
# precision
('prec', ctypes.c_int),
@@ -398,7 +398,7 @@ class ImageComptParmType(ctypes.Structure):
# image depth in bits
('bpp', ctypes.c_int),
- # signed (1) / unsigned (0)
+ # signed (1) / unsigned (0)
('sgnd', ctypes.c_int)]
@@ -511,7 +511,7 @@ def destroy_compress(cinfo):
def encode(cinfo, cio, image):
"""Wrapper for openjpeg library function opj_encode.
- Encodes an image into a JPEG-2000 codestream.
+ Encodes an image into a JPEG-2000 codestream.
Parameters
----------
@@ -540,7 +540,7 @@ def destroy_decompress(dinfo):
def image_cmptparm_t_from_np(np_image):
"""Return appropriate image_cmptparm_t based on given numpy array.
"""
- try:
+ try:
num_comps = np_image.shape[2]
except IndexError:
num_comps = 1
@@ -557,17 +557,17 @@ def image_cmptparm_t_from_np(np_image):
bpp = 8
sgnd = 1
elif np_image.dtype == np.uint16:
- prec = 16
- bpp = 16
+ prec = 16
+ bpp = 16
sgnd = 0
elif np_image.dtype == np.int16:
- prec = 16
- bpp = 16
+ prec = 16
+ bpp = 16
sgnd = 1
else:
raise(TypeError("unhandled"))
- for j in range(0, num_comps):
+ for j in range(0, num_comps):
tarr[j].dx = 1
tarr[j].dy = 1
tarr[j].w = np_image.shape[1]
diff --git a/glymur/lib/test/test_openjp2.py b/glymur/lib/test/test_openjp2.py
index 54d8254..8694507 100644
--- a/glymur/lib/test/test_openjp2.py
+++ b/glymur/lib/test/test_openjp2.py
@@ -1,5 +1,5 @@
"""
-Tests for libopenjp2 wrapping functions.
+Tests for libopenjp2 wrapping functions.
"""
# R0904: Seems like pylint is fooled in this situation
# W0142: using kwargs is ok in this context
@@ -212,7 +212,7 @@ class TestOpenJP2(unittest.TestCase):
"""Runs test designated tte3 in OpenJPEG test suite."""
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
xtx3_setup(tfile.name)
- self.assertTrue(True)
+ self.assertTrue(True)
def test_rta3(self):
"""Runs test designated rta3 in OpenJPEG test suite."""
@@ -221,13 +221,13 @@ class TestOpenJP2(unittest.TestCase):
codec_format = openjp2.CODEC_J2K
self.j2k_random_tile_access(tfile.name, codec_format)
- self.assertTrue(True)
+ self.assertTrue(True)
def test_tte4(self):
"""Runs test designated tte4 in OpenJPEG test suite."""
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
xtx4_setup(tfile.name)
- self.assertTrue(True)
+ self.assertTrue(True)
def test_rta4(self):
"""Runs test designated rta4 in OpenJPEG test suite."""
@@ -241,7 +241,7 @@ class TestOpenJP2(unittest.TestCase):
"""Runs test designated tte5 in OpenJPEG test suite."""
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
xtx5_setup(tfile.name)
- self.assertTrue(True)
+ self.assertTrue(True)
def test_rta5(self):
"""Runs test designated rta5 in OpenJPEG test suite."""
@@ -332,8 +332,8 @@ def tile_encoder(**kwargs):
def tile_decoder(**kwargs):
"""Fixture called with various configurations by many tests.
-
- Reads a tile. That's all it does.
+
+ Reads a tile. That's all it does.
"""
stream = openjp2.stream_create_default_file_stream_v3(kwargs['filename'],
True)
@@ -355,7 +355,7 @@ def tile_decoder(**kwargs):
openjp2.setup_decoder(codec, dparam)
image = openjp2.read_header(stream, codec)
- openjp2.set_decode_area(codec, image,
+ openjp2.set_decode_area(codec, image,
kwargs['x0'], kwargs['y0'],
kwargs['x1'], kwargs['y1'])
diff --git a/glymur/test/fixtures.py b/glymur/test/fixtures.py
index 9c543bf..6626075 100644
--- a/glymur/test/fixtures.py
+++ b/glymur/test/fixtures.py
@@ -11,6 +11,19 @@ import numpy as np
import glymur
+# The Python XMP Toolkit may be used for XMP UUIDs, but only if available and
+# if the version is at least 2.0.0.
+try:
+ import libxmp
+ if hasattr(libxmp, 'version') and re.match(r'''[2-9].\d*.\d*''',
+ libxmp.version.VERSION):
+ from libxmp import XMPMeta
+ HAS_PYTHON_XMP_TOOLKIT = True
+ else:
+ HAS_PYTHON_XMP_TOOLKIT = False
+except ImportError:
+ HAS_PYTHON_XMP_TOOLKIT = False
+
# Need to know of the libopenjp2 version is the official 2.0.0 release and NOT
# the 2.0+ development version.
OPENJP2_IS_V2_OFFICIAL = False
@@ -170,90 +183,96 @@ def read_pgx_header(pgx_file):
nemo_xmp_box = """UUID Box (uuid) @ (77, 3146)
UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
- UUID Data:
-
-
-
- Google
- 2013-02-09T14:47:53
-
-
- 1
- 72/1
- 72/1
- 2
- HTC
- HTC Glacier
- 2592
- 1456
-
-
- 8
- 8
- 8
-
-
- 2
- 3
-
-
- 1343036288/4294967295
- 1413044224/4294967295
-
-
-
-
- 2748779008/4294967295
- 1417339264/4294967295
- 1288490240/4294967295
- 2576980480/4294967295
- 644245120/4294967295
- 257698032/4294967295
-
-
-
-
- 1
- 2528
- 1424
- 353/100
- 0
- 0/1
- WGS-84
- 2013-02-09T14:47:53
-
-
- 76
-
-
- 0220
- 0100
-
-
- 1
- 2
- 3
- 0
-
-
- 42,20.56N
- 71,5.29W
- 2013-02-09T19:47:53Z
- NETWORK
-
-
- 2013-02-09T14:47:53
-
-
-
-
- Glymur
- Python XMP Toolkit
-
-
-
-
- """
+ UUID Data:
+
+
+
+ Google
+ 2013-02-09T14:47:53
+
+
+ 1
+ 72/1
+ 72/1
+ 2
+ HTC
+ HTC Glacier
+ 2592
+ 1456
+
+
+ 8
+ 8
+ 8
+
+
+ 2
+ 3
+
+
+ 1343036288/4294967295
+ 1413044224/4294967295
+
+
+
+
+ 2748779008/4294967295
+ 1417339264/4294967295
+ 1288490240/4294967295
+ 2576980480/4294967295
+ 644245120/4294967295
+ 257698032/4294967295
+
+
+
+
+ 1
+ 2528
+ 1424
+ 353/100
+ 0
+ 0/1
+ WGS-84
+ 2013-02-09T14:47:53
+
+
+ 76
+
+
+ 0220
+ 0100
+
+
+ 1
+ 2
+ 3
+ 0
+
+
+ 42,20.56N
+ 71,5.29W
+ 2013-02-09T19:47:53Z
+ NETWORK
+
+
+ 2013-02-09T14:47:53
+
+
+
+
+ Glymur
+ Python XMP Toolkit
+
+
+
+
+
+"""
SimpleRDF = """
\)"
+ regexp = r"""glymur.jp2box.XMLBox"""
+ regexp += r"""\(xml=<(xml.etree.ElementTree.){0,1}ElementTree object """
+ regexp += """at 0x([a-f0-9]*)>\)"""
if sys.hexversion < 0x03000000:
self.assertRegexpMatches(repr(box), regexp)
@@ -927,9 +927,9 @@ class TestRepr(unittest.TestCase):
# Since the raw_data parameter is a sequence of bytes which could be
# quite long, don't bother trying to make it conform to eval(repr()).
- regexp = "glymur.jp2box.UUIDBox\("
- regexp += "the_uuid=UUID\('00000000-0000-0000-0000-000000000000'\),\s"
- regexp += "raw_data=\)"
+ regexp = r"""glymur.jp2box.UUIDBox\("""
+ regexp += """the_uuid=UUID\('00000000-0000-0000-0000-000000000000'\),\s"""
+ regexp += """raw_data=\)"""
if sys.hexversion < 0x03000000:
self.assertRegexpMatches(repr(box), regexp)
diff --git a/glymur/test/test_jp2box_uuid.py b/glymur/test/test_jp2box_uuid.py
index 0d3684a..82dc253 100644
--- a/glymur/test/test_jp2box_uuid.py
+++ b/glymur/test/test_jp2box_uuid.py
@@ -35,7 +35,9 @@ if sys.hexversion <= 0x03030000:
else:
from unittest.mock import patch
-from libxmp import XMPMeta
+from .fixtures import HAS_PYTHON_XMP_TOOLKIT, OPJ_DATA_ROOT
+if HAS_PYTHON_XMP_TOOLKIT:
+ from libxmp import XMPMeta
import glymur
from glymur import Jp2k
diff --git a/glymur/test/test_jp2k.py b/glymur/test/test_jp2k.py
index aeb0e41..852312f 100644
--- a/glymur/test/test_jp2k.py
+++ b/glymur/test/test_jp2k.py
@@ -30,13 +30,14 @@ import warnings
import numpy as np
import pkg_resources
-import libxmp
-from libxmp import XMPMeta
-
import glymur
from glymur import Jp2k
-from .fixtures import OPENJP2_IS_V2_OFFICIAL
+from .fixtures import HAS_PYTHON_XMP_TOOLKIT, OPENJP2_IS_V2_OFFICIAL
+if HAS_PYTHON_XMP_TOOLKIT:
+ import libxmp
+ from libxmp import XMPMeta
+
from .fixtures import OPJ_DATA_ROOT, opj_data_file
@@ -362,6 +363,8 @@ class TestJp2k(unittest.TestCase):
self.assertEqual(ET.tostring(jp2k.box[3].xml.getroot()),
b'this is a test')
+ @unittest.skipIf(not HAS_PYTHON_XMP_TOOLKIT,
+ "Requires Python XMP Toolkit >= 2.0")
def test_xmp_attribute(self):
"""Verify the XMP packet in the shipping example file can be read."""
j = Jp2k(self.jp2file)
diff --git a/glymur/version.py b/glymur/version.py
index af7523e..260f880 100644
--- a/glymur/version.py
+++ b/glymur/version.py
@@ -1,10 +1,12 @@
-# This file is part of glymur, a Python interface for accessing JPEG 2000.
-#
-# http://glymur.readthedocs.org
-#
-# Copyright 2013 John Evans
-#
-# License: MIT
+"""
+This file is part of glymur, a Python interface for accessing JPEG 2000.
+
+http://glymur.readthedocs.org
+
+Copyright 2013 John Evans
+
+License: MIT
+"""
import sys
import numpy as np