Merge branch 'release-0.2.5'

This commit is contained in:
jevans 2013-07-22 18:07:45 -04:00
commit 729f42b5c9
9 changed files with 32 additions and 52 deletions

View file

@ -1,3 +1,6 @@
Jul 23, 2013 - v0.2.5 Fixed inconsistency in XML handling, now all instances
are always ElementTree objects (issue82).
Jul 21, 2013 - v0.2.4 Fixed markdown bug for Fedora 17 information, fixed
out-of-date windows information (issue79). Fixed incorrect
interpretation of Psot parameter (issue78).

View file

@ -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.4'
release = '0.2.5'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View file

@ -185,9 +185,8 @@ Work with XMP UUIDs?
====================
The example JP2 file shipped with glymur has an XMP UUID. ::
>>> from glymur import Jp2k
>>> file = glymur.data.nemo()
>>> j = Jp2k(file)
>>> import glymur
>>> j = glymur.Jp2k(glymur.data.nemo())
>>> print(j.box[4])
UUID Box (uuid) @ (715, 2412)
UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
@ -198,7 +197,7 @@ The example JP2 file shipped with glymur has an XMP UUID. ::
</rdf:RDF>
</ns0:xmpmeta>
Since the UUID data in this case is returned as an ElementTree Element, one can
Since the UUID data in this case is returned as an ElementTree instance, one can
use ElementTree to access the data. For example, to extract the
**CreatorTool** attribute value, the following would work::

View file

@ -6,7 +6,6 @@ Here's an incomplete list of what I'd like to focus on in the near future.
* continue to monitor upstream changes in the openjp2 library
* investigate using CFFI or cython instead of ctypes to wrap openjp2
* investigate swapping out ElementTree for LXML
* eventually expose the openjp2 API
* investigate JPIP

View file

@ -42,16 +42,6 @@ for _marker in range(0xff90, 0xff94):
_VALID_MARKERS.append(_marker)
class InconsistentStartOfTileError(IOError):
"""To be raised if bad SOT segment encountered.
SOT segment offsets are recorded as encountered. The offsets should all be
different.
"""
def __init__(self, msg):
IOError.__init__(self, msg)
class Codestream(object):
"""Container for codestream information.
@ -115,8 +105,8 @@ class Codestream(object):
marker_id, = struct.unpack('>H', read_buffer)
if marker_id == 0xff90 and header_only:
# start-of-tile (SOT) means we are out of the main header.
# No need to go any further.
# Start-of-tile (SOT) means that we are out of the main header
# and there is no need to go further.
break
try:
@ -135,7 +125,7 @@ class Codestream(object):
if marker_id == 0xff93:
# If SOD, then we need to seek past the tile part bit stream.
if self._parse_tpart_flag:
if self._parse_tpart_flag and not header_only:
# But first parse the tile part bit stream for SOP and
# EPH segments.
self._parse_tile_part_bit_stream(fptr, segment,
@ -143,6 +133,7 @@ class Codestream(object):
fptr.seek(self._tile_offset[-1] + self._tile_length[-1])
def _process_marker_segment(self, fptr, marker_id):
"""Process and return a segment from the codestream.
"""
@ -207,19 +198,12 @@ class Codestream(object):
# we encounter start-of-data marker segments.
segment = _parse_sot_segment(fptr)
if segment.offset not in self._tile_offset:
self._tile_offset.append(segment.offset)
if segment.psot == 0:
tile_part_length = self.offset + self.length - segment.offset - 2
else:
tile_part_length = segment.psot
self._tile_length.append(tile_part_length)
self._tile_offset.append(segment.offset)
if segment.psot == 0:
tile_part_length = self.offset + self.length - segment.offset - 2
else:
msg = "Inconsistent start-of-tile (SOT) marker segment "
msg += "encountered in tile with index {0}. "
msg += "Codestream parsing terminated."
msg = msg.format(segment.isot)
raise InconsistentStartOfTileError(msg)
tile_part_length = segment.psot
self._tile_length.append(tile_part_length)
elif marker_id == 0xff93:
# start of data. Need to seek past the current tile part.

View file

@ -1608,7 +1608,7 @@ class XMLBox(Jp2kBox):
offset of the box from the start of the file.
longname : str
more verbose description of the box.
xml : ElementTree.Element
xml : ElementTree object
XML section.
"""
def __init__(self, xml=None, filename=None, length=0, offset=-1):
@ -1636,10 +1636,7 @@ class XMLBox(Jp2kBox):
msg = Jp2kBox.__str__(self)
xml = self.xml
if self.xml is not None:
try:
msg += _pretty_print_xml(self.xml)
except TypeError:
msg += _pretty_print_xml(self.xml.getroot())
msg += _pretty_print_xml(self.xml)
else:
msg += '\n {0}'.format(xml)
return msg
@ -1682,7 +1679,8 @@ class XMLBox(Jp2kBox):
text = text.rstrip('\0')
try:
xml = ET.fromstring(text)
elt = ET.fromstring(text)
xml = ET.ElementTree(elt)
except ParseError as parse_error:
msg = 'A problem was encountered while parsing an XML box: "{0}"'
msg = msg.format(str(parse_error))
@ -1926,13 +1924,11 @@ class UUIDBox(Jp2kBox):
# XMP data. Parse as XML. Seems to be a difference between
# ElementTree in version 2.7 and 3.3.
if sys.hexversion < 0x03000000:
#parser = ET.XMLParser(encoding='utf-8')
#import pdb; pdb.set_trace()
#self.data = ET.fromstringlist(raw_data, parser=parser)
self.data = ET.fromstring(raw_data)
elt = ET.fromstring(raw_data)
else:
text = raw_data.decode('utf-8')
self.data = ET.fromstring(text)
elt = ET.fromstring(text)
self.data = ET.ElementTree(elt)
elif the_uuid.bytes == b'JpgTiffExif->JP2':
exif_obj = Exif(raw_data)
ifds = OrderedDict()
@ -2555,8 +2551,8 @@ def _pretty_print_xml(xml, level=0):
"""Pretty print XML data.
"""
xml = copy.deepcopy(xml)
_indent(xml, level=level)
xmltext = ET.tostring(xml).decode('utf-8')
_indent(xml.getroot(), level=level)
xmltext = ET.tostring(xml.getroot()).decode('utf-8')
# Indent it a bit.
lst = [(' ' + x) for x in xmltext.split('\n')]

View file

@ -365,7 +365,7 @@ class TestXML(unittest.TestCase):
j2k.wrap(tfile.name, boxes=boxes)
jp2 = Jp2k(tfile.name)
self.assertEqual(jp2.box[3].box_id, 'xml ')
self.assertEqual(ET.tostring(jp2.box[3].xml),
self.assertEqual(ET.tostring(jp2.box[3].xml.getroot()),
b'<data>0</data>')
@unittest.skipIf(os.name == "nt",

View file

@ -4021,7 +4021,7 @@ class TestSuiteDump(unittest.TestCase):
self.assertEqual(jp2.box[1].compatibility_list[1], 'jp2 ')
# XML box
tags = [x.tag for x in jp2.box[2].xml]
tags = [x.tag for x in jp2.box[2].xml.getroot()]
self.assertEqual(tags,
['{http://www.jpeg.org/jpx/1.0/xml}'
+ 'GENERAL_CREATION_INFO'])
@ -4046,7 +4046,7 @@ class TestSuiteDump(unittest.TestCase):
self.assertEqual(jp2.box[3].box[1].colorspace, glymur.core.SRGB)
# XML box
tags = [x.tag for x in jp2.box[4].xml]
tags = [x.tag for x in jp2.box[4].xml.getroot()]
self.assertEqual(tags, ['{http://www.jpeg.org/jpx/1.0/xml}CAPTION',
'{http://www.jpeg.org/jpx/1.0/xml}LOCATION',
'{http://www.jpeg.org/jpx/1.0/xml}EVENT'])
@ -4376,13 +4376,13 @@ class TestSuiteDump(unittest.TestCase):
self.assertIsNone(jp2.box[2].box[1].colorspace)
# XML box
tags = [x.tag for x in jp2.box[3].xml]
tags = [x.tag for x in jp2.box[3].xml.getroot()]
self.assertEqual(tags,
['{http://www.jpeg.org/jpx/1.0/xml}'
+ 'GENERAL_CREATION_INFO'])
# XML box
tags = [x.tag for x in jp2.box[5].xml]
tags = [x.tag for x in jp2.box[5].xml.getroot()]
self.assertEqual(tags,
['{http://www.jpeg.org/jpx/1.0/xml}CAPTION',
'{http://www.jpeg.org/jpx/1.0/xml}LOCATION',
@ -6954,8 +6954,7 @@ class TestSuiteDump(unittest.TestCase):
self.assertEqual(c.segment[3]._exponent, [4] + [5, 5, 6] * 5)
def test_NR_merged_dump(self):
jfile = os.path.join(data_root,
'input/nonregression/merged.jp2')
jfile = os.path.join(data_root, 'input/nonregression/merged.jp2')
jp2 = Jp2k(jfile)
ids = [box.box_id for box in jp2.box]

View file

@ -2,7 +2,7 @@ from setuptools import setup, find_packages
import sys
kwargs = {'name': 'Glymur',
'version': '0.2.4',
'version': '0.2.5',
'description': 'Tools for accessing JPEG2000 files',
'long_description': open('README.md').read(),
'author': 'John Evans',