Some differences noted in XML printing. Some extra requirements. Closes #75.

A couple of XML printing tests were commented out because of differences
between the ways that 2.6 and 2.6+ versions of ElementTree print XML.

A 2.6 installation will require one to install ordereddict and
unittest2.
This commit is contained in:
John Evans 2013-07-13 13:11:22 -04:00
commit 5ecff26614
7 changed files with 37 additions and 15 deletions

View file

@ -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/

View file

@ -14,7 +14,7 @@ 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
===================== =====================
@ -27,8 +27,8 @@ 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 version of
Linux, your package manager should already provide you with at least version Linux, your package manager should already provide you with at least version
1.5.1 of OpenJPEG, which means that glymur can be installed ready to read JPEG 1.5.1 of OpenJPEG, which means that glymur can be installed ready to read JPEG
2000 images. If you use windows, I suggest using the 1.5.1 windows installer 2000 images. If your platform is windows, I suggest using the 1.5.1 windows
provided to you by the OpenJPEG folks at installer provided to you by the OpenJPEG folks at
https://code.google.com/p/openjpeg/downloads/list . https://code.google.com/p/openjpeg/downloads/list .
Glymur Installation Glymur Installation

View file

@ -13,7 +13,6 @@ 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
@ -23,6 +22,12 @@ 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
@ -342,7 +347,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]
@ -1012,8 +1017,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 +1640,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 +1674,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 +1917,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 +2076,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 +2084,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

View file

@ -1,5 +1,6 @@
#pylint: disable-all #pylint: disable-all
import ctypes import ctypes
import sys
if sys.hexversion < 0x02070000: if sys.hexversion < 0x02070000:
import unittest2 as unittest import unittest2 as unittest

View file

@ -39,6 +39,9 @@ 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

View file

@ -581,6 +581,8 @@ 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)
@ -649,6 +651,8 @@ 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):

View file

@ -19,9 +19,13 @@ instllrqrs = ['numpy>1.6.2']
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",