diff --git a/glymur/data/nemo.jp2 b/glymur/data/nemo.jp2
index 55d199c..838583d 100644
Binary files a/glymur/data/nemo.jp2 and b/glymur/data/nemo.jp2 differ
diff --git a/glymur/jp2box.py b/glymur/jp2box.py
index 6f628df..066a9fa 100644
--- a/glymur/jp2box.py
+++ b/glymur/jp2box.py
@@ -2136,12 +2136,6 @@ class UUIDBox(Jp2kBox):
self.data = raw_data
self._type = 'unknown'
- if length == 0:
- # Need to compute the length.
- # The length is 8 (L and T fields) + 16 (length of UUID identifier)
- # + length of uuid data.
- length = 24 + len(self.data)
-
self.length = length
self.offset = offset
@@ -2179,9 +2173,15 @@ class UUIDBox(Jp2kBox):
if self._type != 'XMP':
msg = "Only XMP UUID boxes can currently be written."
raise NotImplementedError(msg)
- read_buffer = struct.pack('>I4s', self.length, 'uuid')
+ serialized_buffer = b''
+ serialized_buffer += ET.tostring(self.data.getroot(), encoding='utf-8')
+ serialized_buffer += b''
+ if self.length == 0:
+ self.length = 24 + len(serialized_buffer)
+ read_buffer = struct.pack('>I4s', self.length, b'uuid')
fptr.write(read_buffer)
- fptr.write(self.data)
+ fptr.write(self.uuid.bytes)
+ fptr.write(serialized_buffer)
@staticmethod
def parse(fptr, offset, length):
diff --git a/glymur/jp2k.py b/glymur/jp2k.py
index 45eaf39..42eaab5 100644
--- a/glymur/jp2k.py
+++ b/glymur/jp2k.py
@@ -1013,7 +1013,7 @@ class Jp2k(Jp2kBox):
>>> jp2 = glymur.Jp2k(jfile)
>>> codestream = jp2.get_codestream()
>>> print(codestream.segment[1])
- SIZ marker segment @ (3137, 47)
+ SIZ marker segment @ (3233, 47)
Profile: 2
Reference Grid Height, Width: (1456 x 2592)
Vertical, Horizontal Reference Grid Offset: (0 x 0)
diff --git a/glymur/test/fixtures.py b/glymur/test/fixtures.py
index b872f1d..68c0706 100644
--- a/glymur/test/fixtures.py
+++ b/glymur/test/fixtures.py
@@ -167,3 +167,90 @@ def read_pgx_header(pgx_file):
header = header.rstrip()
return header, pos
+
+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
+
+
+
+
+ """
diff --git a/glymur/test/test_jp2box.py b/glymur/test/test_jp2box.py
index ff61bc5..2f6241c 100644
--- a/glymur/test/test_jp2box.py
+++ b/glymur/test/test_jp2box.py
@@ -419,7 +419,7 @@ class TestAppend(unittest.TestCase):
# The sequence of box IDs should be the same as before, but with an
# xml box at the end.
box_ids = [box.box_id for box in jp2.box]
- expected = ['jP ', 'ftyp', 'jp2h', 'uuid', 'uuid', 'jp2c', 'xml ']
+ expected = ['jP ', 'ftyp', 'jp2h', 'uuid', 'jp2c', 'xml ']
self.assertEqual(box_ids, expected)
self.assertEqual(ET.tostring(jp2.box[-1].xml.getroot()),
b'0')
@@ -468,7 +468,7 @@ class TestAppend(unittest.TestCase):
# The sequence of box IDs should be the same as before, but with an
# xml box at the end.
box_ids = [box.box_id for box in jp2.box]
- expected = ['jP ', 'ftyp', 'jp2h', 'uuid', 'uuid', 'jp2c', 'xml ']
+ expected = ['jP ', 'ftyp', 'jp2h', 'uuid', 'jp2c', 'xml ']
self.assertEqual(box_ids, expected)
self.assertEqual(ET.tostring(jp2.box[-1].xml.getroot()),
b'0')
diff --git a/glymur/test/test_jp2k.py b/glymur/test/test_jp2k.py
index 636ea9a..c9e750a 100644
--- a/glymur/test/test_jp2k.py
+++ b/glymur/test/test_jp2k.py
@@ -100,7 +100,7 @@ class TestJp2k(unittest.TestCase):
jp2k = Jp2k(self.jp2file)
# top-level boxes
- self.assertEqual(len(jp2k.box), 6)
+ self.assertEqual(len(jp2k.box), 5)
self.assertEqual(jp2k.box[0].box_id, 'jP ')
self.assertEqual(jp2k.box[0].offset, 0)
@@ -119,15 +119,11 @@ class TestJp2k(unittest.TestCase):
self.assertEqual(jp2k.box[3].box_id, 'uuid')
self.assertEqual(jp2k.box[3].offset, 77)
- self.assertEqual(jp2k.box[3].length, 638)
+ self.assertEqual(jp2k.box[3].length, 3146)
- self.assertEqual(jp2k.box[4].box_id, 'uuid')
- self.assertEqual(jp2k.box[4].offset, 715)
- self.assertEqual(jp2k.box[4].length, 2412)
-
- self.assertEqual(jp2k.box[5].box_id, 'jp2c')
- self.assertEqual(jp2k.box[5].offset, 3127)
- self.assertEqual(jp2k.box[5].length, 1132296)
+ self.assertEqual(jp2k.box[4].box_id, 'jp2c')
+ self.assertEqual(jp2k.box[4].offset, 3223)
+ self.assertEqual(jp2k.box[4].length, 1132296)
# jp2h super box
self.assertEqual(len(jp2k.box[2].box), 2)
@@ -169,7 +165,7 @@ class TestJp2k(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
with open(self.jp2file, 'rb') as ifile:
# Everything up until the jp2c box.
- write_buffer = ifile.read(3127)
+ write_buffer = ifile.read(3223)
tfile.write(write_buffer)
# The L field must be 1 in order to signal the presence of the
@@ -190,9 +186,9 @@ class TestJp2k(unittest.TestCase):
jp2k = Jp2k(tfile.name)
- self.assertEqual(jp2k.box[5].box_id, 'jp2c')
- self.assertEqual(jp2k.box[5].offset, 3127)
- self.assertEqual(jp2k.box[5].length, 1133427 + 8)
+ self.assertEqual(jp2k.box[4].box_id, 'jp2c')
+ self.assertEqual(jp2k.box[4].offset, 3223)
+ self.assertEqual(jp2k.box[4].length, 1133427 + 8)
@unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows")
def test_length_field_is_zero(self):
@@ -357,45 +353,12 @@ class TestJp2k(unittest.TestCase):
def test_xmp_attribute(self):
"""Verify the XMP packet in the shipping example file can be read."""
j = Jp2k(self.jp2file)
- xmp = j.box[4].data
+ xmp = j.box[3].data
ns0 = '{http://www.w3.org/1999/02/22-rdf-syntax-ns#}'
- ns1 = '{http://ns.adobe.com/xap/1.0/}'
- name = '{0}RDF/{0}Description'.format(ns0)
+ ns2 = '{http://ns.adobe.com/xap/1.0/}'
+ name = '{0}RDF/{0}Description/{1}CreatorTool'.format(ns0, ns2)
elt = xmp.find(name)
- attr_value = elt.attrib['{0}CreatorTool'.format(ns1)]
- self.assertEqual(attr_value, 'glymur')
-
- @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows")
- def test_unrecognized_exif_tag(self):
- """An unrecognized exif tag should be handled gracefully."""
- with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
- shutil.copyfile(self.jp2file, tfile.name)
-
- # The Exif UUID starts at byte 77. There are 8 bytes for the L and
- # T fields, then 16 bytes for the UUID identifier, then 6 exif
- # header bytes, then 8 bytes for the TIFF header, then 2 bytes
- # the the Image IFD number of tags, where we finally find the first
- # tag, "Make" (271). We'll corrupt it by changing it into 171,
- # which does not correspond to any known Exif Image tag.
- with open(tfile.name, 'r+b') as fptr:
- fptr.seek(117)
- write_buffer = struct.pack('',
- ' ',
- ' ',
- ' ',
- ' ']
- expected = '\n'.join(lst)
+ expected = nemo_xmp_box
self.assertEqual(actual, expected)
def test_codestream(self):
@@ -657,8 +645,8 @@ class TestPrinting(unittest.TestCase):
print(j.get_codestream())
actual = fake_out.getvalue().strip()
lst = ['Codestream:',
- ' SOC marker segment @ (3135, 0)',
- ' SIZ marker segment @ (3137, 47)',
+ ' SOC marker segment @ (3231, 0)',
+ ' SIZ marker segment @ (3233, 47)',
' Profile: 2',
' Reference Grid Height, Width: (1456 x 2592)',
' Vertical, Horizontal Reference Grid Offset: (0 x 0)',
@@ -668,7 +656,7 @@ class TestPrinting(unittest.TestCase):
' Signed: (False, False, False)',
' Vertical, Horizontal Subsampling: '
+ '((1, 1), (1, 1), (1, 1))',
- ' COD marker segment @ (3186, 12)',
+ ' COD marker segment @ (3282, 12)',
' Coding style:',
' Entropy coder, without partitions',
' SOP marker segments: False',
@@ -690,11 +678,11 @@ class TestPrinting(unittest.TestCase):
' Vertically stripe causal context: False',
' Predictable termination: False',
' Segmentation symbols: False',
- ' QCD marker segment @ (3200, 7)',
+ ' QCD marker segment @ (3296, 7)',
' Quantization style: no quantization, '
+ '2 guard bits',
' Step size: [(0, 8), (0, 9), (0, 9), (0, 10)]',
- ' CME marker segment @ (3209, 37)',
+ ' CME marker segment @ (3305, 37)',
' "Created by OpenJPEG version 2.0.0"']
expected = '\n'.join(lst)
self.assertEqual(actual, expected)
@@ -1046,59 +1034,42 @@ class TestPrinting(unittest.TestCase):
"Ordered dicts not printing well in 2.7")
def test_exif_uuid(self):
"""Verify printing of exif information"""
- j = glymur.Jp2k(self.jp2file)
+ with tempfile.NamedTemporaryFile(suffix='.jp2', mode='wb') as tfile:
- with patch('sys.stdout', new=StringIO()) as fake_out:
- print(j.box[3])
- actual = fake_out.getvalue().strip()
+ with open(self.jp2file, 'rb') as ifptr:
+ tfile.write(ifptr.read())
- lines = ["UUID Box (uuid) @ (77, 638)",
+ # Write L, T, UUID identifier.
+ tfile.write(struct.pack('>I4s', 76, b'uuid'))
+ tfile.write(b'JpgTiffExif->JP2')
+
+ tfile.write(b'Exif\x00\x00')
+ xbuffer = struct.pack('