Merge branch 'issue176' into devel

This commit is contained in:
John Evans 2014-03-01 12:31:44 -05:00
commit 692cee0345
14 changed files with 152 additions and 344 deletions

View file

@ -11,8 +11,8 @@ before_install:
# command to install dependencies # command to install dependencies
install: install:
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then pip install --use-mirrors contextlib2 mock; fi - if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then pip install --use-mirrors lxml contextlib2 mock; fi
- if [[ $TRAVIS_PYTHON_VERSION == '3.3' ]]; then pip install --use-mirrors numpy; fi - if [[ $TRAVIS_PYTHON_VERSION == '3.3' ]]; then pip install --use-mirrors lxml numpy; fi
# command to run tests # command to run tests
script: script:

View file

@ -5,6 +5,7 @@ ChangeLog
0.6.0 (pending) 0.6.0 (pending)
=============== ===============
* Added lxml requirement.
* added set_printoptions, get_printoptions function * added set_printoptions, get_printoptions function
* dropped support for Python 2.6, added support for Python 3.4 * dropped support for Python 2.6, added support for Python 3.4
* dropped windows support * dropped windows support

View file

@ -68,8 +68,8 @@ For python 3.3, you should install the following set of ports:
* python33 * python33
* py33-numpy * py33-numpy
* py33-lxml
* py33-distribute * py33-distribute
* py33-matplotlib (optional, for running certain tests)
* py33-Pillow (optional, for running certain tests) * py33-Pillow (optional, for running certain tests)
MacPorts supplies both OpenJPEG 1.5.0 and OpenJPEG 2.0.0. MacPorts supplies both OpenJPEG 1.5.0 and OpenJPEG 2.0.0.
@ -85,6 +85,7 @@ packages may also need to be installed. Consult your package manager
documentation or use pip. documentation or use pip.
* setuptools * setuptools
* python-lxml
* matplotlib * matplotlib
* pillow * pillow
* contextlib2 (2.7 only) * contextlib2 (2.7 only)

View file

@ -131,7 +131,6 @@ From within Python, it is as simple as printing the Jp2k object, i.e. ::
</rdf:Description> </rdf:Description>
</rdf:RDF> </rdf:RDF>
</ns0:xmpmeta> </ns0:xmpmeta>
Contiguous Codestream Box (jp2c) @ (3223, 1132296) Contiguous Codestream Box (jp2c) @ (3223, 1132296)
Main header: Main header:
SOC marker segment @ (3231, 0) SOC marker segment @ (3231, 0)
@ -228,7 +227,6 @@ The :py:meth:`append` method can add an XML box as shown below::
>>> import shutil >>> import shutil
>>> import glymur >>> import glymur
>>> shutil.copyfile(glymur.data.nemo(), 'myfile.jp2') >>> shutil.copyfile(glymur.data.nemo(), 'myfile.jp2')
>>> from xml.etree import cElementTree as ET
>>> jp2 = glymur.Jp2k('myfile.jp2') >>> jp2 = glymur.Jp2k('myfile.jp2')
>>> xmlbox = glymur.jp2box.XMLBox(filename='data.xml') >>> xmlbox = glymur.jp2box.XMLBox(filename='data.xml')
>>> jp2.append(xmlbox) >>> jp2.append(xmlbox)
@ -408,12 +406,12 @@ The example JP2 file shipped with glymur has an XMP UUID. ::
. .
</ns0:xmpmeta> </ns0:xmpmeta>
Since the UUID data in this case is returned as an ElementTree instance, Since the UUID data in this case is returned as an lxml ElementTree
one can use ElementTree from the standard library to access the data. instance, one can use lxml to access the data. For example, to
For example, to extract the **CreatorTool** attribute value, one could do the extract the **CreatorTool** attribute value, one could do the
following following
>>> xmp = j.box[3].data.packet >>> xmp = j.box[3].data
>>> rdf = '{http://www.w3.org/1999/02/22-rdf-syntax-ns#}' >>> rdf = '{http://www.w3.org/1999/02/22-rdf-syntax-ns#}'
>>> ns2 = '{http://ns.adobe.com/xap/1.0/}' >>> ns2 = '{http://ns.adobe.com/xap/1.0/}'
>>> name = '{0}RDF/{0}Description/{1}CreatorTool'.format(rdf, ns2) >>> name = '{0}RDF/{0}Description/{1}CreatorTool'.format(rdf, ns2)

View file

@ -7,7 +7,8 @@ import re
import struct import struct
import sys import sys
import warnings import warnings
import xml.etree.cElementTree as ET
import lxml.etree as ET
if sys.hexversion < 0x02070000: if sys.hexversion < 0x02070000:
# pylint: disable=F0401,E0611 # pylint: disable=F0401,E0611

View file

@ -1,7 +1,7 @@
"""Core definitions to be shared amongst the modules. """Core definitions to be shared amongst the modules.
""" """
import copy import copy
import xml.etree.cElementTree as ET import lxml.etree as ET
# Progression order # Progression order
LRCP = 0 LRCP = 0
@ -76,45 +76,3 @@ _CAPABILITIES_DISPLAY = {
1: '0', 1: '0',
2: '1', 2: '1',
3: '3'} 3: '3'}
def _pretty_print_xml(xml, level=0):
"""Pretty print XML data.
"""
xml = copy.deepcopy(xml)
_indent(xml.getroot(), level=level)
xmltext = ET.tostring(xml.getroot(), encoding='utf-8').decode('utf-8')
# Indent it a bit.
lst = [(' ' + x) for x in xmltext.split('\n')]
try:
xml = '\n'.join(lst)
return '\n{0}'.format(xml)
except UnicodeEncodeError:
# This can happen on python 2.x if the character set contains certain
# non-ascii characters. Just print out the corresponding xml char
# entities instead.
xml = u'\n'.join(lst)
text = u'\n{0}'.format(xml)
text = text.encode('ascii', 'xmlcharrefreplace')
return text
def _indent(elem, level=0):
"""Recipe for pretty printing XML. Please see
http://effbot.org/zone/element-lib.htm#prettyprint
"""
i = "\n" + level * " "
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = i + " "
if not elem.tail or not elem.tail.strip():
elem.tail = i
for elem in elem:
_indent(elem, level + 1)
if not elem.tail or not elem.tail.strip():
elem.tail = i
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i

View file

@ -20,10 +20,11 @@ import os
import pprint import pprint
import struct import struct
import sys import sys
import textwrap
import uuid import uuid
import warnings import warnings
import xml.etree.cElementTree as ET
import lxml.etree as ET
import numpy as np import numpy as np
from .codestream import Codestream from .codestream import Codestream
@ -32,7 +33,6 @@ from .core import _COLOR_TYPE_MAP_DISPLAY
from .core import SRGB, GREYSCALE, YCC from .core import SRGB, GREYSCALE, YCC
from .core import ENUMERATED_COLORSPACE, RESTRICTED_ICC_PROFILE from .core import ENUMERATED_COLORSPACE, RESTRICTED_ICC_PROFILE
from .core import ANY_ICC_PROFILE, VENDOR_COLOR_METHOD from .core import ANY_ICC_PROFILE, VENDOR_COLOR_METHOD
from .core import _pretty_print_xml
from . import _uuid_io from . import _uuid_io
@ -97,10 +97,8 @@ class Jp2kBox(object):
msg = Jp2kBox.__str__(self) msg = Jp2kBox.__str__(self)
for box in self.box: for box in self.box:
boxstr = str(box) boxstr = str(box)
# Indent the child boxes to make the association clear.
# Add indentation. msg += '\n' + textwrap.indent(boxstr, ' ')
strs = [('\n ' + x) for x in boxstr.split('\n')]
msg += ''.join(strs)
return msg return msg
@ -890,10 +888,7 @@ class ContiguousCodestreamBox(Jp2kBox):
msg += '\n Main header:' msg += '\n Main header:'
for segment in self.main_header.segment: for segment in self.main_header.segment:
segstr = str(segment) msg += '\n' + textwrap.indent(str(segment), ' ')
# Add indentation.
strs = [('\n ' + x) for x in segstr.split('\n')]
msg += ''.join(strs)
return msg return msg
@ -2563,11 +2558,14 @@ class XMLBox(Jp2kBox):
if _printoptions['xml'] == False: if _printoptions['xml'] == False:
return msg return msg
xml = self.xml msg += '\n'
if self.xml is not None: if self.xml is not None:
msg += _pretty_print_xml(self.xml) xmlstring = ET.tostring(self.xml,
encoding='utf-8',
pretty_print=True).decode('utf-8')
else: else:
msg += '\n {0}'.format(xml) xmlstring = 'None'
msg += textwrap.indent(xmlstring, ' ')
return msg return msg
def write(self, fptr): def write(self, fptr):
@ -2971,9 +2969,12 @@ class UUIDBox(Jp2kBox):
return msg return msg
if self.uuid == uuid.UUID('be7acfcb-97a9-42e8-9c71-999491e3afac'): if self.uuid == uuid.UUID('be7acfcb-97a9-42e8-9c71-999491e3afac'):
line = '\n UUID Data: {0}' line = '\n UUID Data:\n{0}'
xmlstring = _pretty_print_xml(self.data) xmlstring = ET.tostring(self.data,
xmlstring = xmlstring.rstrip() encoding='utf-8',
pretty_print=True).decode('utf-8')
# indent it a bit
xmlstring = textwrap.indent(xmlstring.rstrip(), ' ')
msg += line.format(xmlstring) msg += line.format(xmlstring)
elif self.uuid.bytes == b'JpgTiffExif->JP2': elif self.uuid.bytes == b'JpgTiffExif->JP2':
msg += '\n UUID Data: {0}'.format(str(self.data)) msg += '\n UUID Data: {0}'.format(str(self.data))

View file

@ -4,6 +4,7 @@ Test fixtures common to more than one test point.
import os import os
import re import re
import sys import sys
import textwrap
import warnings import warnings
import numpy as np import numpy as np
@ -181,92 +182,100 @@ def read_pgx_header(pgx_file):
header = header.rstrip() header = header.rstrip()
return header, pos return header, pos
nemo_xmp = """<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<ns0:xmpmeta xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ns0="adobe:ns:meta/" xmlns:ns2="http://ns.adobe.com/xap/1.0/" xmlns:ns3="http://ns.adobe.com/tiff/1.0/" xmlns:ns4="http://ns.adobe.com/exif/1.0/" xmlns:ns5="http://ns.adobe.com/photoshop/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ns0:xmptk="Exempi + XMP Core 5.1.2">
<rdf:RDF>
<rdf:Description rdf:about="">
<ns2:CreatorTool>Google</ns2:CreatorTool>
<ns2:CreateDate>2013-02-09T14:47:53</ns2:CreateDate>
</rdf:Description>
<rdf:Description rdf:about="">
<ns3:YCbCrPositioning>1</ns3:YCbCrPositioning>
<ns3:XResolution>72/1</ns3:XResolution>
<ns3:YResolution>72/1</ns3:YResolution>
<ns3:ResolutionUnit>2</ns3:ResolutionUnit>
<ns3:Make>HTC</ns3:Make>
<ns3:Model>HTC Glacier</ns3:Model>
<ns3:ImageWidth>2592</ns3:ImageWidth>
<ns3:ImageLength>1456</ns3:ImageLength>
<ns3:BitsPerSample>
<rdf:Seq>
<rdf:li>8</rdf:li>
<rdf:li>8</rdf:li>
<rdf:li>8</rdf:li>
</rdf:Seq>
</ns3:BitsPerSample>
<ns3:PhotometricInterpretation>2</ns3:PhotometricInterpretation>
<ns3:SamplesPerPixel>3</ns3:SamplesPerPixel>
<ns3:WhitePoint>
<rdf:Seq>
<rdf:li>1343036288/4294967295</rdf:li>
<rdf:li>1413044224/4294967295</rdf:li>
</rdf:Seq>
</ns3:WhitePoint>
<ns3:PrimaryChromaticities>
<rdf:Seq>
<rdf:li>2748779008/4294967295</rdf:li>
<rdf:li>1417339264/4294967295</rdf:li>
<rdf:li>1288490240/4294967295</rdf:li>
<rdf:li>2576980480/4294967295</rdf:li>
<rdf:li>644245120/4294967295</rdf:li>
<rdf:li>257698032/4294967295</rdf:li>
</rdf:Seq>
</ns3:PrimaryChromaticities>
</rdf:Description>
<rdf:Description rdf:about="">
<ns4:ColorSpace>1</ns4:ColorSpace>
<ns4:PixelXDimension>2528</ns4:PixelXDimension>
<ns4:PixelYDimension>1424</ns4:PixelYDimension>
<ns4:FocalLength>353/100</ns4:FocalLength>
<ns4:GPSAltitudeRef>0</ns4:GPSAltitudeRef>
<ns4:GPSAltitude>0/1</ns4:GPSAltitude>
<ns4:GPSMapDatum>WGS-84</ns4:GPSMapDatum>
<ns4:DateTimeOriginal>2013-02-09T14:47:53</ns4:DateTimeOriginal>
<ns4:ISOSpeedRatings>
<rdf:Seq>
<rdf:li>76</rdf:li>
</rdf:Seq>
</ns4:ISOSpeedRatings>
<ns4:ExifVersion>0220</ns4:ExifVersion>
<ns4:FlashpixVersion>0100</ns4:FlashpixVersion>
<ns4:ComponentsConfiguration>
<rdf:Seq>
<rdf:li>1</rdf:li>
<rdf:li>2</rdf:li>
<rdf:li>3</rdf:li>
<rdf:li>0</rdf:li>
</rdf:Seq>
</ns4:ComponentsConfiguration>
<ns4:GPSLatitude>42,20.56N</ns4:GPSLatitude>
<ns4:GPSLongitude>71,5.29W</ns4:GPSLongitude>
<ns4:GPSTimeStamp>2013-02-09T19:47:53Z</ns4:GPSTimeStamp>
<ns4:GPSProcessingMethod>NETWORK</ns4:GPSProcessingMethod>
</rdf:Description>
<rdf:Description rdf:about="">
<ns5:DateCreated>2013-02-09T14:47:53</ns5:DateCreated>
</rdf:Description>
<rdf:Description rdf:about="">
<dc:Creator>
<rdf:Seq>
<rdf:li>Glymur</rdf:li>
<rdf:li>Python XMP Toolkit</rdf:li>
</rdf:Seq>
</dc:Creator>
</rdf:Description>
</rdf:RDF>
</ns0:xmpmeta>
<?xpacket end="w"?>"""
nemo_xmp_box = """UUID Box (uuid) @ (77, 3146) nemo_xmp_box = """UUID Box (uuid) @ (77, 3146)
UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP) UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
UUID Data: UUID Data:
<ns0:xmpmeta xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ns0="adobe:ns:meta/" xmlns:ns2="http://ns.adobe.com/xap/1.0/" xmlns:ns3="http://ns.adobe.com/tiff/1.0/" xmlns:ns4="http://ns.adobe.com/exif/1.0/" xmlns:ns5="http://ns.adobe.com/photoshop/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ns0:xmptk="Exempi + XMP Core 5.1.2"> {0}""".format(textwrap.indent(nemo_xmp, ' '))
<rdf:RDF>
<rdf:Description rdf:about=""> nemo_xmp_box = """UUID Box (uuid) @ (77, 3146)
<ns2:CreatorTool>Google</ns2:CreatorTool> UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
<ns2:CreateDate>2013-02-09T14:47:53</ns2:CreateDate> UUID Data:
</rdf:Description> {0}""".format(textwrap.indent(nemo_xmp, ' '))
<rdf:Description rdf:about="">
<ns3:YCbCrPositioning>1</ns3:YCbCrPositioning>
<ns3:XResolution>72/1</ns3:XResolution>
<ns3:YResolution>72/1</ns3:YResolution>
<ns3:ResolutionUnit>2</ns3:ResolutionUnit>
<ns3:Make>HTC</ns3:Make>
<ns3:Model>HTC Glacier</ns3:Model>
<ns3:ImageWidth>2592</ns3:ImageWidth>
<ns3:ImageLength>1456</ns3:ImageLength>
<ns3:BitsPerSample>
<rdf:Seq>
<rdf:li>8</rdf:li>
<rdf:li>8</rdf:li>
<rdf:li>8</rdf:li>
</rdf:Seq>
</ns3:BitsPerSample>
<ns3:PhotometricInterpretation>2</ns3:PhotometricInterpretation>
<ns3:SamplesPerPixel>3</ns3:SamplesPerPixel>
<ns3:WhitePoint>
<rdf:Seq>
<rdf:li>1343036288/4294967295</rdf:li>
<rdf:li>1413044224/4294967295</rdf:li>
</rdf:Seq>
</ns3:WhitePoint>
<ns3:PrimaryChromaticities>
<rdf:Seq>
<rdf:li>2748779008/4294967295</rdf:li>
<rdf:li>1417339264/4294967295</rdf:li>
<rdf:li>1288490240/4294967295</rdf:li>
<rdf:li>2576980480/4294967295</rdf:li>
<rdf:li>644245120/4294967295</rdf:li>
<rdf:li>257698032/4294967295</rdf:li>
</rdf:Seq>
</ns3:PrimaryChromaticities>
</rdf:Description>
<rdf:Description rdf:about="">
<ns4:ColorSpace>1</ns4:ColorSpace>
<ns4:PixelXDimension>2528</ns4:PixelXDimension>
<ns4:PixelYDimension>1424</ns4:PixelYDimension>
<ns4:FocalLength>353/100</ns4:FocalLength>
<ns4:GPSAltitudeRef>0</ns4:GPSAltitudeRef>
<ns4:GPSAltitude>0/1</ns4:GPSAltitude>
<ns4:GPSMapDatum>WGS-84</ns4:GPSMapDatum>
<ns4:DateTimeOriginal>2013-02-09T14:47:53</ns4:DateTimeOriginal>
<ns4:ISOSpeedRatings>
<rdf:Seq>
<rdf:li>76</rdf:li>
</rdf:Seq>
</ns4:ISOSpeedRatings>
<ns4:ExifVersion>0220</ns4:ExifVersion>
<ns4:FlashpixVersion>0100</ns4:FlashpixVersion>
<ns4:ComponentsConfiguration>
<rdf:Seq>
<rdf:li>1</rdf:li>
<rdf:li>2</rdf:li>
<rdf:li>3</rdf:li>
<rdf:li>0</rdf:li>
</rdf:Seq>
</ns4:ComponentsConfiguration>
<ns4:GPSLatitude>42,20.56N</ns4:GPSLatitude>
<ns4:GPSLongitude>71,5.29W</ns4:GPSLongitude>
<ns4:GPSTimeStamp>2013-02-09T19:47:53Z</ns4:GPSTimeStamp>
<ns4:GPSProcessingMethod>NETWORK</ns4:GPSProcessingMethod>
</rdf:Description>
<rdf:Description rdf:about="">
<ns5:DateCreated>2013-02-09T14:47:53</ns5:DateCreated>
</rdf:Description>
<rdf:Description rdf:about="">
<dc:Creator>
<rdf:Seq>
<rdf:li>Glymur</rdf:li>
<rdf:li>Python XMP Toolkit</rdf:li>
</rdf:Seq>
</dc:Creator>
</rdf:Description>
</rdf:RDF>
</ns0:xmpmeta>"""
SimpleRDF = """<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'> SimpleRDF = """<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<rdf:Description rdf:about='Test:XMPCoreCoverage/kSimpleRDF' <rdf:Description rdf:about='Test:XMPCoreCoverage/kSimpleRDF'
@ -353,7 +362,7 @@ text_gbr_34 = """Colour Specification Box (colr) @ (179, 1339)
# Metadata dump of nemo. # Metadata dump of nemo.
nemo_dump_full = r'''JPEG 2000 Signature Box (jP ) @ (0, 12) dump = r'''JPEG 2000 Signature Box (jP ) @ (0, 12)
Signature: 0d0a870a Signature: 0d0a870a
File Type Box (ftyp) @ (12, 20) File Type Box (ftyp) @ (12, 20)
Brand: jp2 Brand: jp2
@ -371,90 +380,8 @@ JP2 Header Box (jp2h) @ (32, 45)
Colorspace: sRGB Colorspace: sRGB
UUID Box (uuid) @ (77, 3146) UUID Box (uuid) @ (77, 3146)
UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP) UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
UUID Data: UUID Data:
<ns0:xmpmeta xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ns0="adobe:ns:meta/" xmlns:ns2="http://ns.adobe.com/xap/1.0/" xmlns:ns3="http://ns.adobe.com/tiff/1.0/" xmlns:ns4="http://ns.adobe.com/exif/1.0/" xmlns:ns5="http://ns.adobe.com/photoshop/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ns0:xmptk="Exempi + XMP Core 5.1.2"> {0}
<rdf:RDF>
<rdf:Description rdf:about="">
<ns2:CreatorTool>Google</ns2:CreatorTool>
<ns2:CreateDate>2013-02-09T14:47:53</ns2:CreateDate>
</rdf:Description>
<rdf:Description rdf:about="">
<ns3:YCbCrPositioning>1</ns3:YCbCrPositioning>
<ns3:XResolution>72/1</ns3:XResolution>
<ns3:YResolution>72/1</ns3:YResolution>
<ns3:ResolutionUnit>2</ns3:ResolutionUnit>
<ns3:Make>HTC</ns3:Make>
<ns3:Model>HTC Glacier</ns3:Model>
<ns3:ImageWidth>2592</ns3:ImageWidth>
<ns3:ImageLength>1456</ns3:ImageLength>
<ns3:BitsPerSample>
<rdf:Seq>
<rdf:li>8</rdf:li>
<rdf:li>8</rdf:li>
<rdf:li>8</rdf:li>
</rdf:Seq>
</ns3:BitsPerSample>
<ns3:PhotometricInterpretation>2</ns3:PhotometricInterpretation>
<ns3:SamplesPerPixel>3</ns3:SamplesPerPixel>
<ns3:WhitePoint>
<rdf:Seq>
<rdf:li>1343036288/4294967295</rdf:li>
<rdf:li>1413044224/4294967295</rdf:li>
</rdf:Seq>
</ns3:WhitePoint>
<ns3:PrimaryChromaticities>
<rdf:Seq>
<rdf:li>2748779008/4294967295</rdf:li>
<rdf:li>1417339264/4294967295</rdf:li>
<rdf:li>1288490240/4294967295</rdf:li>
<rdf:li>2576980480/4294967295</rdf:li>
<rdf:li>644245120/4294967295</rdf:li>
<rdf:li>257698032/4294967295</rdf:li>
</rdf:Seq>
</ns3:PrimaryChromaticities>
</rdf:Description>
<rdf:Description rdf:about="">
<ns4:ColorSpace>1</ns4:ColorSpace>
<ns4:PixelXDimension>2528</ns4:PixelXDimension>
<ns4:PixelYDimension>1424</ns4:PixelYDimension>
<ns4:FocalLength>353/100</ns4:FocalLength>
<ns4:GPSAltitudeRef>0</ns4:GPSAltitudeRef>
<ns4:GPSAltitude>0/1</ns4:GPSAltitude>
<ns4:GPSMapDatum>WGS-84</ns4:GPSMapDatum>
<ns4:DateTimeOriginal>2013-02-09T14:47:53</ns4:DateTimeOriginal>
<ns4:ISOSpeedRatings>
<rdf:Seq>
<rdf:li>76</rdf:li>
</rdf:Seq>
</ns4:ISOSpeedRatings>
<ns4:ExifVersion>0220</ns4:ExifVersion>
<ns4:FlashpixVersion>0100</ns4:FlashpixVersion>
<ns4:ComponentsConfiguration>
<rdf:Seq>
<rdf:li>1</rdf:li>
<rdf:li>2</rdf:li>
<rdf:li>3</rdf:li>
<rdf:li>0</rdf:li>
</rdf:Seq>
</ns4:ComponentsConfiguration>
<ns4:GPSLatitude>42,20.56N</ns4:GPSLatitude>
<ns4:GPSLongitude>71,5.29W</ns4:GPSLongitude>
<ns4:GPSTimeStamp>2013-02-09T19:47:53Z</ns4:GPSTimeStamp>
<ns4:GPSProcessingMethod>NETWORK</ns4:GPSProcessingMethod>
</rdf:Description>
<rdf:Description rdf:about="">
<ns5:DateCreated>2013-02-09T14:47:53</ns5:DateCreated>
</rdf:Description>
<rdf:Description rdf:about="">
<dc:Creator>
<rdf:Seq>
<rdf:li>Glymur</rdf:li>
<rdf:li>Python XMP Toolkit</rdf:li>
</rdf:Seq>
</dc:Creator>
</rdf:Description>
</rdf:RDF>
</ns0:xmpmeta>
Contiguous Codestream Box (jp2c) @ (3223, 1132296) Contiguous Codestream Box (jp2c) @ (3223, 1132296)
Main header: Main header:
SOC marker segment @ (3231, 0) SOC marker segment @ (3231, 0)
@ -492,6 +419,7 @@ Contiguous Codestream Box (jp2c) @ (3223, 1132296)
Step size: [(0, 8), (0, 9), (0, 9), (0, 10)] Step size: [(0, 8), (0, 9), (0, 9), (0, 10)]
CME marker segment @ (3305, 37) CME marker segment @ (3305, 37)
"Created by OpenJPEG version 2.0.0"''' "Created by OpenJPEG version 2.0.0"'''
nemo_dump_full = dump.format(textwrap.indent(nemo_xmp, ' '))
nemo_dump_short = r"""JPEG 2000 Signature Box (jP ) @ (0, 12) nemo_dump_short = r"""JPEG 2000 Signature Box (jP ) @ (0, 12)
File Type Box (ftyp) @ (12, 20) File Type Box (ftyp) @ (12, 20)
@ -557,7 +485,7 @@ Contiguous Codestream Box (jp2c) @ (3223, 1132296)
CME marker segment @ (3305, 37) CME marker segment @ (3305, 37)
"Created by OpenJPEG version 2.0.0"''' "Created by OpenJPEG version 2.0.0"'''
nemo_dump_no_codestream = r"""JPEG 2000 Signature Box (jP ) @ (0, 12) dump = r"""JPEG 2000 Signature Box (jP ) @ (0, 12)
Signature: 0d0a870a Signature: 0d0a870a
File Type Box (ftyp) @ (12, 20) File Type Box (ftyp) @ (12, 20)
Brand: jp2 Brand: jp2
@ -575,91 +503,10 @@ JP2 Header Box (jp2h) @ (32, 45)
Colorspace: sRGB Colorspace: sRGB
UUID Box (uuid) @ (77, 3146) UUID Box (uuid) @ (77, 3146)
UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP) UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
UUID Data: UUID Data:
<ns0:xmpmeta xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ns0="adobe:ns:meta/" xmlns:ns2="http://ns.adobe.com/xap/1.0/" xmlns:ns3="http://ns.adobe.com/tiff/1.0/" xmlns:ns4="http://ns.adobe.com/exif/1.0/" xmlns:ns5="http://ns.adobe.com/photoshop/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ns0:xmptk="Exempi + XMP Core 5.1.2"> {0}
<rdf:RDF>
<rdf:Description rdf:about="">
<ns2:CreatorTool>Google</ns2:CreatorTool>
<ns2:CreateDate>2013-02-09T14:47:53</ns2:CreateDate>
</rdf:Description>
<rdf:Description rdf:about="">
<ns3:YCbCrPositioning>1</ns3:YCbCrPositioning>
<ns3:XResolution>72/1</ns3:XResolution>
<ns3:YResolution>72/1</ns3:YResolution>
<ns3:ResolutionUnit>2</ns3:ResolutionUnit>
<ns3:Make>HTC</ns3:Make>
<ns3:Model>HTC Glacier</ns3:Model>
<ns3:ImageWidth>2592</ns3:ImageWidth>
<ns3:ImageLength>1456</ns3:ImageLength>
<ns3:BitsPerSample>
<rdf:Seq>
<rdf:li>8</rdf:li>
<rdf:li>8</rdf:li>
<rdf:li>8</rdf:li>
</rdf:Seq>
</ns3:BitsPerSample>
<ns3:PhotometricInterpretation>2</ns3:PhotometricInterpretation>
<ns3:SamplesPerPixel>3</ns3:SamplesPerPixel>
<ns3:WhitePoint>
<rdf:Seq>
<rdf:li>1343036288/4294967295</rdf:li>
<rdf:li>1413044224/4294967295</rdf:li>
</rdf:Seq>
</ns3:WhitePoint>
<ns3:PrimaryChromaticities>
<rdf:Seq>
<rdf:li>2748779008/4294967295</rdf:li>
<rdf:li>1417339264/4294967295</rdf:li>
<rdf:li>1288490240/4294967295</rdf:li>
<rdf:li>2576980480/4294967295</rdf:li>
<rdf:li>644245120/4294967295</rdf:li>
<rdf:li>257698032/4294967295</rdf:li>
</rdf:Seq>
</ns3:PrimaryChromaticities>
</rdf:Description>
<rdf:Description rdf:about="">
<ns4:ColorSpace>1</ns4:ColorSpace>
<ns4:PixelXDimension>2528</ns4:PixelXDimension>
<ns4:PixelYDimension>1424</ns4:PixelYDimension>
<ns4:FocalLength>353/100</ns4:FocalLength>
<ns4:GPSAltitudeRef>0</ns4:GPSAltitudeRef>
<ns4:GPSAltitude>0/1</ns4:GPSAltitude>
<ns4:GPSMapDatum>WGS-84</ns4:GPSMapDatum>
<ns4:DateTimeOriginal>2013-02-09T14:47:53</ns4:DateTimeOriginal>
<ns4:ISOSpeedRatings>
<rdf:Seq>
<rdf:li>76</rdf:li>
</rdf:Seq>
</ns4:ISOSpeedRatings>
<ns4:ExifVersion>0220</ns4:ExifVersion>
<ns4:FlashpixVersion>0100</ns4:FlashpixVersion>
<ns4:ComponentsConfiguration>
<rdf:Seq>
<rdf:li>1</rdf:li>
<rdf:li>2</rdf:li>
<rdf:li>3</rdf:li>
<rdf:li>0</rdf:li>
</rdf:Seq>
</ns4:ComponentsConfiguration>
<ns4:GPSLatitude>42,20.56N</ns4:GPSLatitude>
<ns4:GPSLongitude>71,5.29W</ns4:GPSLongitude>
<ns4:GPSTimeStamp>2013-02-09T19:47:53Z</ns4:GPSTimeStamp>
<ns4:GPSProcessingMethod>NETWORK</ns4:GPSProcessingMethod>
</rdf:Description>
<rdf:Description rdf:about="">
<ns5:DateCreated>2013-02-09T14:47:53</ns5:DateCreated>
</rdf:Description>
<rdf:Description rdf:about="">
<dc:Creator>
<rdf:Seq>
<rdf:li>Glymur</rdf:li>
<rdf:li>Python XMP Toolkit</rdf:li>
</rdf:Seq>
</dc:Creator>
</rdf:Description>
</rdf:RDF>
</ns0:xmpmeta>
Contiguous Codestream Box (jp2c) @ (3223, 1132296)""" Contiguous Codestream Box (jp2c) @ (3223, 1132296)"""
nemo_dump_no_codestream = dump.format(textwrap.indent(nemo_xmp, ' '))
nemo_dump_no_codestream_no_xml = r"""JPEG 2000 Signature Box (jP ) @ (0, 12) nemo_dump_no_codestream_no_xml = r"""JPEG 2000 Signature Box (jP ) @ (0, 12)
Signature: 0d0a870a Signature: 0d0a870a
@ -691,10 +538,10 @@ file7_rreq = r"""Reader Requirements Box (rreq) @ (44, 24)
Feature 043: 0x40 Deprecated - compositing layer uses restricted ICC profile Feature 043: 0x40 Deprecated - compositing layer uses restricted ICC profile
Vendor Features:""" Vendor Features:"""
file1_xml = r"""XML Box (xml ) @ (36, 439) file1_xml = """XML Box (xml ) @ (36, 439)
<ns0:IMAGE_CREATION xmlns:ns0="http://www.jpeg.org/jpx/1.0/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.jpeg.org/jpx/1.0/xml http://www.jpeg.org/metadata/15444-2.xsd"> <IMAGE_CREATION xmlns="http://www.jpeg.org/jpx/1.0/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.jpeg.org/jpx/1.0/xml http://www.jpeg.org/metadata/15444-2.xsd">
<ns0:GENERAL_CREATION_INFO> \t<GENERAL_CREATION_INFO>
<ns0:CREATION_TIME>2001-11-01T13:45:00.000-06:00</ns0:CREATION_TIME> \t\t<CREATION_TIME>2001-11-01T13:45:00.000-06:00</CREATION_TIME>
<ns0:IMAGE_SOURCE>Professional 120 Image</ns0:IMAGE_SOURCE> \t\t<IMAGE_SOURCE>Professional 120 Image</IMAGE_SOURCE>
</ns0:GENERAL_CREATION_INFO> \t</GENERAL_CREATION_INFO>
</ns0:IMAGE_CREATION>""" </IMAGE_CREATION>"""

View file

@ -22,10 +22,10 @@ import sys
import tempfile import tempfile
import uuid import uuid
from uuid import UUID from uuid import UUID
import xml.etree.cElementTree as ET
import unittest import unittest
import warnings import warnings
import lxml.etree as ET
import numpy as np import numpy as np
import glymur import glymur
@ -1056,7 +1056,7 @@ class TestRepr(unittest.TestCase):
box = glymur.jp2box.XMLBox(xml=tree) box = glymur.jp2box.XMLBox(xml=tree)
regexp = r"""glymur.jp2box.XMLBox""" regexp = r"""glymur.jp2box.XMLBox"""
regexp += r"""\(xml=<(xml.etree.ElementTree.){0,1}ElementTree object """ regexp += r"""\(xml=<lxml.etree._ElementTree object """
regexp += """at 0x([a-f0-9]*)>\)""" regexp += """at 0x([a-f0-9]*)>\)"""
if sys.hexversion < 0x03000000: if sys.hexversion < 0x03000000:

View file

@ -8,7 +8,7 @@ import struct
import sys import sys
import tempfile import tempfile
import unittest import unittest
import xml.etree.cElementTree as ET import lxml.etree as ET
import glymur import glymur
from glymur import Jp2k from glymur import Jp2k

View file

@ -18,7 +18,6 @@ import sys
import tempfile import tempfile
import uuid import uuid
import warnings import warnings
import xml.etree
if sys.hexversion < 0x02070000: if sys.hexversion < 0x02070000:
import unittest2 as unittest import unittest2 as unittest
@ -35,6 +34,8 @@ if sys.hexversion <= 0x03030000:
else: else:
from unittest.mock import patch from unittest.mock import patch
import lxml.etree
from .fixtures import HAS_PYTHON_XMP_TOOLKIT, OPJ_DATA_ROOT from .fixtures import HAS_PYTHON_XMP_TOOLKIT, OPJ_DATA_ROOT
if HAS_PYTHON_XMP_TOOLKIT: if HAS_PYTHON_XMP_TOOLKIT:
from libxmp import XMPMeta from libxmp import XMPMeta
@ -71,7 +72,7 @@ class TestUUIDXMP(unittest.TestCase):
# The data should be an XMP packet, which gets interpreted as # The data should be an XMP packet, which gets interpreted as
# an ElementTree. # an ElementTree.
self.assertTrue(isinstance(jp2.box[-1].data, self.assertTrue(isinstance(jp2.box[-1].data,
xml.etree.ElementTree.ElementTree)) lxml.etree._ElementTree))
class TestUUIDExif(unittest.TestCase): class TestUUIDExif(unittest.TestCase):
"""Tests for UUIDs of Exif type.""" """Tests for UUIDs of Exif type."""

View file

@ -20,7 +20,6 @@ import sys
import tempfile import tempfile
import unittest import unittest
import warnings import warnings
import xml.etree.cElementTree as ET
if sys.hexversion < 0x03000000: if sys.hexversion < 0x03000000:
from StringIO import StringIO from StringIO import StringIO
@ -32,6 +31,8 @@ if sys.hexversion <= 0x03030000:
else: else:
from unittest.mock import patch from unittest.mock import patch
import lxml.etree as ET
import glymur import glymur
from glymur import Jp2k from glymur import Jp2k
from glymur.jp2box import ColourSpecificationBox, ContiguousCodestreamBox from glymur.jp2box import ColourSpecificationBox, ContiguousCodestreamBox

View file

@ -15,7 +15,6 @@ import struct
import sys import sys
import tempfile import tempfile
import warnings import warnings
from xml.etree import cElementTree as ET
import unittest import unittest
if sys.hexversion < 0x03000000: if sys.hexversion < 0x03000000:
@ -28,10 +27,12 @@ if sys.hexversion <= 0x03030000:
else: else:
from unittest.mock import patch from unittest.mock import patch
import lxml.etree as ET
import glymur import glymur
from glymur import Jp2k from glymur import Jp2k
from . import fixtures from . import fixtures
from .fixtures import OPJ_DATA_ROOT, opj_data_file, nemo_xmp_box from .fixtures import OPJ_DATA_ROOT, opj_data_file
from .fixtures import text_gbr_27, text_gbr_33, text_gbr_34 from .fixtures import text_gbr_27, text_gbr_33, text_gbr_34
@ -567,7 +568,7 @@ class TestPrinting(unittest.TestCase):
print(j.box[3]) print(j.box[3])
actual = fake_out.getvalue().strip() actual = fake_out.getvalue().strip()
expected = nemo_xmp_box expected = fixtures.nemo_xmp_box
self.assertEqual(actual, expected) self.assertEqual(actual, expected)
def test_codestream(self): def test_codestream(self):
@ -639,8 +640,7 @@ class TestPrinting(unittest.TestCase):
# #
# 2.7.5 (fedora 19) prints xml entities. # 2.7.5 (fedora 19) prints xml entities.
# 2.7.3 seems to want to print hex escapes. # 2.7.3 seems to want to print hex escapes.
text = u"""<?xml version="1.0" encoding="utf-8"?> text = u"""<flow>Strömung</flow>"""
<flow>Strömung</flow>"""
if sys.hexversion < 0x03000000: if sys.hexversion < 0x03000000:
xml = ET.parse(StringIO(text.encode('utf-8'))) xml = ET.parse(StringIO(text.encode('utf-8')))
else: else:
@ -668,8 +668,7 @@ class TestPrinting(unittest.TestCase):
# #
# 2.7.5 (fedora 19) prints xml entities. # 2.7.5 (fedora 19) prints xml entities.
# 2.7.3 seems to want to print hex escapes. # 2.7.3 seems to want to print hex escapes.
text = u"""<?xml version="1.0" encoding="utf-8"?> text = u"""<country>Россия</country>"""
<country>Россия</country>"""
if sys.hexversion < 0x03000000: if sys.hexversion < 0x03000000:
xml = ET.parse(StringIO(text.encode('utf-8'))) xml = ET.parse(StringIO(text.encode('utf-8')))
else: else:

View file

@ -16,7 +16,7 @@ kwargs = {'name': 'Glymur',
'license': 'MIT', 'license': 'MIT',
'test_suite': 'glymur.test'} 'test_suite': 'glymur.test'}
instllrqrs = ['numpy>=1.4.1'] instllrqrs = ['numpy>=1.4.1', 'lxml>=2.3.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')