Merge branch 'issue104' of https://github.com/quintusdias/glymur into issue104

Conflicts:
	glymur/_uuid_io/Exif.py
	glymur/_uuid_io/__init__.py
	glymur/jp2box.py
	glymur/test/test_jp2box_uuid.py
	glymur/test/test_jp2k.py
This commit is contained in:
jevans 2014-01-25 15:43:03 -05:00
commit 84c50c8499
11 changed files with 219 additions and 193 deletions

View file

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

View file

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

View file

@ -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:
<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>"""
UUID Data: <?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Exempi + XMP Core 4.4.0">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:xmp="http://ns.adobe.com/xap/1.0/">
<xmp:CreatorTool>Google</xmp:CreatorTool>
<xmp:CreateDate>2013-02-09T14:47:53</xmp:CreateDate>
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:tiff="http://ns.adobe.com/tiff/1.0/">
<tiff:YCbCrPositioning>1</tiff:YCbCrPositioning>
<tiff:XResolution>72/1</tiff:XResolution>
<tiff:YResolution>72/1</tiff:YResolution>
<tiff:ResolutionUnit>2</tiff:ResolutionUnit>
<tiff:Make>HTC</tiff:Make>
<tiff:Model>HTC Glacier</tiff:Model>
<tiff:ImageWidth>2592</tiff:ImageWidth>
<tiff:ImageLength>1456</tiff:ImageLength>
<tiff:BitsPerSample>
<rdf:Seq>
<rdf:li>8</rdf:li>
<rdf:li>8</rdf:li>
<rdf:li>8</rdf:li>
</rdf:Seq>
</tiff:BitsPerSample>
<tiff:PhotometricInterpretation>2</tiff:PhotometricInterpretation>
<tiff:SamplesPerPixel>3</tiff:SamplesPerPixel>
<tiff:WhitePoint>
<rdf:Seq>
<rdf:li>1343036288/4294967295</rdf:li>
<rdf:li>1413044224/4294967295</rdf:li>
</rdf:Seq>
</tiff:WhitePoint>
<tiff: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>
</tiff:PrimaryChromaticities>
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:exif="http://ns.adobe.com/exif/1.0/">
<exif:ColorSpace>1</exif:ColorSpace>
<exif:PixelXDimension>2528</exif:PixelXDimension>
<exif:PixelYDimension>1424</exif:PixelYDimension>
<exif:FocalLength>353/100</exif:FocalLength>
<exif:GPSAltitudeRef>0</exif:GPSAltitudeRef>
<exif:GPSAltitude>0/1</exif:GPSAltitude>
<exif:GPSMapDatum>WGS-84</exif:GPSMapDatum>
<exif:DateTimeOriginal>2013-02-09T14:47:53</exif:DateTimeOriginal>
<exif:ISOSpeedRatings>
<rdf:Seq>
<rdf:li>76</rdf:li>
</rdf:Seq>
</exif:ISOSpeedRatings>
<exif:ExifVersion>0220</exif:ExifVersion>
<exif:FlashpixVersion>0100</exif:FlashpixVersion>
<exif: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>
</exif:ComponentsConfiguration>
<exif:GPSLatitude>42,20.56N</exif:GPSLatitude>
<exif:GPSLongitude>71,5.29W</exif:GPSLongitude>
<exif:GPSTimeStamp>2013-02-09T19:47:53Z</exif:GPSTimeStamp>
<exif:GPSProcessingMethod>NETWORK</exif:GPSProcessingMethod>
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
<photoshop:DateCreated>2013-02-09T14:47:53</photoshop:DateCreated>
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:Creator>
<rdf:Seq>
<rdf:li>Glymur</rdf:li>
<rdf:li>Python XMP Toolkit</rdf:li>
</rdf:Seq>
</dc:Creator>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>"""
SimpleRDF = """<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<rdf:Description rdf:about='Test:XMPCoreCoverage/kSimpleRDF'

View file

@ -894,9 +894,9 @@ class TestRepr(unittest.TestCase):
tree = ET.ElementTree(elt)
box = glymur.jp2box.XMLBox(xml=tree)
regexp = "glymur.jp2box.XMLBox"
regexp += "\(xml=<(xml.etree.ElementTree.){0,1}ElementTree object "
regexp += "at 0x([a-f0-9]*)>\)"
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=<byte\sarray\s10\selements>\)"
regexp = r"""glymur.jp2box.UUIDBox\("""
regexp += """the_uuid=UUID\('00000000-0000-0000-0000-000000000000'\),\s"""
regexp += """raw_data=<byte\sarray\s10\selements>\)"""
if sys.hexversion < 0x03000000:
self.assertRegexpMatches(repr(box), regexp)

View file

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

View file

@ -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'<test>this is a test</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)

View file

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