Bumping for 0.2.0 release, added to mac instructions.

This commit is contained in:
John Evans 2013-07-10 18:39:22 -04:00
commit ed79e61a35
8 changed files with 78 additions and 59 deletions

View file

@ -1,3 +1,5 @@
Jul 11, 2013 - v0.2.0 Support for Python 2.7 on windows, OpenJPEG 1.5.1.
Jun 27, 2013 - v0.1.10 Can wrap codestreams in custom JP2 jackets. Exposing Jun 27, 2013 - v0.1.10 Can wrap codestreams in custom JP2 jackets. Exposing
parameter to specify multi component transform. Added a raw codestream parameter to specify multi component transform. Added a raw codestream
file. file.

View file

@ -78,7 +78,7 @@ copyright = u'2013, John Evans'
# The short X.Y version. # The short X.Y version.
version = '0.1' version = '0.1'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '0.1.10' release = '0.2.0'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

View file

@ -65,6 +65,10 @@ additionally be installed:
* py33-scikit-image and either py33-Pillow or freeimage * py33-scikit-image and either py33-Pillow or freeimage
* py33-matplotlib and py33-Pillow * py33-matplotlib and py33-Pillow
MacPorts supplies both OpenJPEG 1.5.0 and OpenJPEG 2.0.0. As previously
mentioned, the 2.0.0 official release is not supported (although the 2.0+
development version via SVN *is* supported).
Linux Linux
----- -----

View file

@ -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 provided 2000 images. If you use windows, I suggest using the 1.5.1 windows installer
to you by the OpenJPEG folks at 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
@ -56,5 +56,5 @@ You can run the tests from within python as follows::
>>> glymur.runtests() >>> glymur.runtests()
Many tests are currently skipped; in fact most of them are skipped if you Many tests are currently skipped; in fact most of them are skipped if you
are relying on OpenJPEG 1.5.1. But the important thing is whether or not any are relying on OpenJPEG 1.5.1. But the important thing, though, is whether or
tests fail. not any tests fail.

View file

@ -38,11 +38,13 @@ _METHOD_DISPLAY = {
ANY_ICC_PROFILE: 'any ICC profile', ANY_ICC_PROFILE: 'any ICC profile',
VENDOR_COLOR_METHOD: 'vendor color method'} VENDOR_COLOR_METHOD: 'vendor color method'}
_ = {1: 'accurately represents correct colorspace definition', _APPROX_DISPLAY = {1: 'accurately represents correct colorspace definition',
2: 'approximates correct colorspace definition, exceptional quality', 2: 'approximates correct colorspace definition, '
3: 'approximates correct colorspace definition, reasonable quality', + 'exceptional quality',
4: 'approximates correct colorspace definition, poor quality'} 3: 'approximates correct colorspace definition, '
_approximation_display = _ + 'reasonable quality',
4: 'approximates correct colorspace definition, '
+ 'poor quality'}
class Jp2kBox(object): class Jp2kBox(object):
@ -66,12 +68,15 @@ class Jp2kBox(object):
self.offset = offset self.offset = offset
self.longname = longname self.longname = longname
# should never be used except for last box in file.
self._file_size = -1
def __str__(self): def __str__(self):
msg = "{0} Box ({1})".format(self.longname, self.box_id) msg = "{0} Box ({1})".format(self.longname, self.box_id)
msg += " @ ({0}, {1})".format(self.offset, self.length) msg += " @ ({0}, {1})".format(self.offset, self.length)
return msg return msg
def write(self, fptr): def write(self, _):
"""Must be implemented in a subclass. """Must be implemented in a subclass.
""" """
msg = "Not supported for {0} box.".format(self.longname) msg = "Not supported for {0} box.".format(self.longname)
@ -120,7 +125,7 @@ class Jp2kBox(object):
# Call the proper parser for the given box with ID "T". # Call the proper parser for the given box with ID "T".
try: try:
box = _BOX_WITH_ID[box_id]._parse(fptr, start, num_bytes) box = _BOX_WITH_ID[box_id].parse(fptr, start, num_bytes)
except KeyError: except KeyError:
msg = 'Unrecognized box ({0}) encountered.'.format(box_id) msg = 'Unrecognized box ({0}) encountered.'.format(box_id)
warnings.warn(msg) warnings.warn(msg)
@ -177,6 +182,7 @@ class ColourSpecificationBox(Jp2kBox):
ICC profile header according to ICC profile specification. If ICC profile header according to ICC profile specification. If
colorspace is not None, then icc_profile must be empty. colorspace is not None, then icc_profile must be empty.
""" """
def __init__(self, method=ENUMERATED_COLORSPACE, precedence=0, def __init__(self, method=ENUMERATED_COLORSPACE, precedence=0,
approximation=0, colorspace=None, icc_profile=None, approximation=0, colorspace=None, icc_profile=None,
length=0, offset=-1): length=0, offset=-1):
@ -203,8 +209,9 @@ class ColourSpecificationBox(Jp2kBox):
msg += '\n Precedence: {0}'.format(self.precedence) msg += '\n Precedence: {0}'.format(self.precedence)
if self.approximation is not 0: if self.approximation is not 0:
dispvalue = _approximation_display[self.approximation] dispvalue = _APPROX_DISPLAY[self.approximation]
msg += '\n Approximation: {0}'.format(dispvalue) msg += '\n Approximation: {0}'.format(dispvalue)
if self.colorspace is not None: if self.colorspace is not None:
dispvalue = _COLORSPACE_MAP_DISPLAY[self.colorspace] dispvalue = _COLORSPACE_MAP_DISPLAY[self.colorspace]
msg += '\n Colorspace: {0}'.format(dispvalue) msg += '\n Colorspace: {0}'.format(dispvalue)
@ -240,7 +247,7 @@ class ColourSpecificationBox(Jp2kBox):
fptr.write(read_buffer) fptr.write(read_buffer)
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse JPEG 2000 color specification box. """Parse JPEG 2000 color specification box.
Parameters Parameters
@ -468,7 +475,7 @@ class ChannelDefinitionBox(Jp2kBox):
self.association[j])) self.association[j]))
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse component definition box. """Parse component definition box.
Parameters Parameters
@ -542,7 +549,7 @@ class ComponentMappingBox(Jp2kBox):
return msg return msg
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse component mapping box. """Parse component mapping box.
Parameters Parameters
@ -607,7 +614,7 @@ class ContiguousCodestreamBox(Jp2kBox):
return msg return msg
@staticmethod @staticmethod
def _parse(fptr, offset=0, length=0): def parse(fptr, offset=0, length=0):
"""Parse a codestream box. """Parse a codestream box.
Parameters Parameters
@ -685,7 +692,7 @@ class FileTypeBox(Jp2kBox):
fptr.write(item.encode()) fptr.write(item.encode())
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse JPEG 2000 file type box. """Parse JPEG 2000 file type box.
Parameters Parameters
@ -812,7 +819,7 @@ class ImageHeaderBox(Jp2kBox):
fptr.write(read_buffer) fptr.write(read_buffer)
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse JPEG 2000 image header box. """Parse JPEG 2000 image header box.
Parameters Parameters
@ -883,7 +890,7 @@ class AssociationBox(Jp2kBox):
return msg return msg
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse association box. """Parse association box.
Parameters Parameters
@ -956,7 +963,7 @@ class JP2HeaderBox(Jp2kBox):
fptr.seek(end_pos) fptr.seek(end_pos)
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse JPEG 2000 header box. """Parse JPEG 2000 header box.
Parameters Parameters
@ -1017,7 +1024,7 @@ class JPEG2000SignatureBox(Jp2kBox):
fptr.write(struct.pack('>BBBB', *self.signature)) fptr.write(struct.pack('>BBBB', *self.signature))
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse JPEG 2000 signature box. """Parse JPEG 2000 signature box.
Parameters Parameters
@ -1073,7 +1080,7 @@ class PaletteBox(Jp2kBox):
return msg return msg
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse palette box. """Parse palette box.
Parameters Parameters
@ -1220,6 +1227,8 @@ _READER_REQUIREMENTS_DISPLAY = {
+ 'requirements in M.9.2.3', + 'requirements in M.9.2.3',
73: 'YPbPr(1125/60) enumerated colourspace', 73: 'YPbPr(1125/60) enumerated colourspace',
74: 'YPbPr(1250/50) enumerated colourspace'} 74: 'YPbPr(1250/50) enumerated colourspace'}
class ReaderRequirementsBox(Jp2kBox): class ReaderRequirementsBox(Jp2kBox):
"""Container for reader requirements box information. """Container for reader requirements box information.
@ -1276,7 +1285,7 @@ class ReaderRequirementsBox(Jp2kBox):
return msg return msg
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse reader requirements box. """Parse reader requirements box.
Parameters Parameters
@ -1380,7 +1389,7 @@ class ResolutionBox(Jp2kBox):
return msg return msg
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse Resolution box. """Parse Resolution box.
Parameters Parameters
@ -1436,7 +1445,7 @@ class CaptureResolutionBox(Jp2kBox):
return msg return msg
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse Resolution box. """Parse Resolution box.
Parameters Parameters
@ -1493,7 +1502,7 @@ class DisplayResolutionBox(Jp2kBox):
return msg return msg
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse Resolution box. """Parse Resolution box.
Parameters Parameters
@ -1548,7 +1557,7 @@ class LabelBox(Jp2kBox):
return msg return msg
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse Label box. """Parse Label box.
Parameters Parameters
@ -1633,7 +1642,7 @@ class XMLBox(Jp2kBox):
fptr.write(read_buffer) fptr.write(read_buffer)
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse XML box. """Parse XML box.
Parameters Parameters
@ -1697,7 +1706,7 @@ class UUIDListBox(Jp2kBox):
return(msg) return(msg)
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse UUIDList box. """Parse UUIDList box.
Parameters Parameters
@ -1760,7 +1769,7 @@ class UUIDInfoBox(Jp2kBox):
return(msg) return(msg)
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse UUIDInfo super box. """Parse UUIDInfo super box.
Parameters Parameters
@ -1828,7 +1837,7 @@ class DataEntryURLBox(Jp2kBox):
return msg return msg
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse Data Entry URL box. """Parse Data Entry URL box.
Parameters Parameters
@ -1949,7 +1958,7 @@ class UUIDBox(Jp2kBox):
return msg return msg
@staticmethod @staticmethod
def _parse(fptr, offset, length): def parse(fptr, offset, length):
"""Parse UUID box. """Parse UUID box.
Parameters Parameters

View file

@ -98,7 +98,7 @@ class Jp2k(Jp2kBox):
# Parse the file for JP2/JPX contents only if we are reading it. # Parse the file for JP2/JPX contents only if we are reading it.
if mode == 'rb': if mode == 'rb':
self._parse() self.parse()
def __str__(self): def __str__(self):
metadata = ['File: ' + os.path.basename(self.filename)] metadata = ['File: ' + os.path.basename(self.filename)]
@ -110,7 +110,7 @@ class Jp2k(Jp2kBox):
metadata.append(str(codestream)) metadata.append(str(codestream))
return '\n'.join(metadata) return '\n'.join(metadata)
def _parse(self): def parse(self):
"""Parses the JPEG 2000 file. """Parses the JPEG 2000 file.
Raises Raises
@ -425,7 +425,7 @@ class Jp2k(Jp2kBox):
_opj2.destroy_codec(codec) _opj2.destroy_codec(codec)
_opj2.image_destroy(image) _opj2.image_destroy(image)
self._parse() self.parse()
def wrap(self, filename, boxes=None): def wrap(self, filename, boxes=None):
"""Write the codestream back out to file, wrapped in new JP2 jacket. """Write the codestream back out to file, wrapped in new JP2 jacket.

View file

@ -1,22 +1,25 @@
| OS | Python 2.7 | Python 3.3 | Notes | | OS | Python 2.7 | Python 3.3 | Notes |
+------------+------------+------------+----------------------------------+ +------------+------------+------------+--------------------------------------+
| Windows | X | | Python(xy) with OpenJPEG 1.5.1. | | Windows | X | | Python(xy) with OpenJPEG 1.5.1. |
| | | | At least 25 tests should pass | | | | | At least 25 tests should pass |
+------------+------------+------------+----------------------------------+ +------------+------------+------------+--------------------------------------+
| Mac | X | | MacPorts with both OpenJPEG 1.5.1| | Mac | X | | MacPorts with both OpenJPEG 1.5.1 |
| | | | and OpenJPEG svn. Maximum number| | | | | and OpenJPEG svn. 370 of 450 tests |
| | | | of tests should pass. | | | | | should pass. |
+------------+------------+------------+----------------------------------+ +------------+------------+------------+--------------------------------------+
| Mac | | X | MacPorts with both OpenJPEG 1.5.1| | Mac | | X | MacPorts with both OpenJPEG 1.5.1 |
| | | | and OpenJPEG svn. Maximum number| | | | | and OpenJPEG svn. 390 of 450 |
| | | | of tests should pass. | | | | | tests should pass. |
+------------+------------+------------+----------------------------------+ +------------+------------+------------+--------------------------------------+
| Raspberry | X | | Ships with only 1.3. Should | | Raspberry | X | | Ships with only 1.3. Should |
| | | | error out gracefully. | | | | | error out gracefully. |
+------------+------------+------------+----------------------------------+ +------------+------------+------------+--------------------------------------+
| Fedora 17 | X | | Ships with 1.4. Should error out| | Fedora 17 | X | | Ships with 1.4. Should error out |
| | | | gracefully. | | | | | gracefully. |
+------------+------------+------------+----------------------------------+ +------------+------------+------------+--------------------------------------+
| Fedora 18 | | X | Ships with 1.5.1. Some tests | | Fedora 18 | | X | Ships with 1.5.1. Some tests |
| | | | should pass. | | | | | should pass. |
+------------+------------+------------+----------------------------------+ +------------+------------+------------+--------------------------------------+
Pylint on entire package should be at least 0.95.
pep8 should be pass cleanly.

View file

@ -2,7 +2,7 @@ from setuptools import setup, find_packages
import sys import sys
kwargs = {'name': 'Glymur', kwargs = {'name': 'Glymur',
'version': '0.1.10', 'version': '0.2.0',
'description': 'Tools for accessing JPEG2000 files', 'description': 'Tools for accessing JPEG2000 files',
'long_description': open('README.md').read(), 'long_description': open('README.md').read(),
'author': 'John Evans', 'author': 'John Evans',
@ -29,6 +29,7 @@ clssfrs = ["Programming Language :: Python",
"Development Status :: 3 - Alpha", "Development Status :: 3 - Alpha",
"Operating System :: MacOS", "Operating System :: MacOS",
"Operating System :: POSIX :: Linux", "Operating System :: POSIX :: Linux",
"Operating System :: Microsoft :: Windows :: Windows XP",
"Intended Audience :: Science/Research", "Intended Audience :: Science/Research",
"Intended Audience :: Information Technology", "Intended Audience :: Information Technology",
"Topic :: Software Development :: Libraries :: Python Modules"] "Topic :: Software Development :: Libraries :: Python Modules"]