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

This commit is contained in:
John Evans 2014-03-12 08:34:04 -04:00
commit 0ebb506800
8 changed files with 13 additions and 195 deletions

View file

@ -9,6 +9,7 @@ ChangeLog
* Added lxml requirement.
* added set_printoptions, get_printoptions function
* dropped support for Python 2.6, added support for Python 3.4
* dropped support for OpenJPEG versions 1.3 and 1.4
* dropped windows support (it might work, it might not, I don't much care)
* added write support for JP2 UUID, dataEntryURL, palette, and component mapping boxes
* added read/write support for JPX free, number list, and data reference boxes

View file

@ -14,17 +14,7 @@ XMP UUIDs. There is some very limited support for reading JPX metadata.
Glymur 0.6 works on Python versions 2.7, 3.3 and 3.4. If you have Python 2.6,
you should use the 0.5 series of Glymur.
OpenJPEG Installation
=====================
Glymur will read JPEG 2000 images with versions 1.3, 1.4, 1.5, 2.0,
and the trunk/development version of OpenJPEG. Writing images is
only supported with the 1.5 or better, however, and the trunk/development
version of OpenJPEG is strongly recommended. For more information about
OpenJPEG, please consult http://www.openjpeg.org.
If you use MacPorts or if you have a sufficiently recent version of
Linux, your package manager should already provide you with a version of
OpenJPEG 1.X which glymur can already use.
For more information about OpenJPEG, please consult http://www.openjpeg.org.
Glymur Installation
===================

View file

@ -772,19 +772,6 @@ class Jp2k(Jp2kBox):
"""
self._subsampling_sanity_check()
if rlevel != 0:
# Must check the specified rlevel against the maximum.
# OpenJPEG 1.3 will segfault if rlevel is too high.
codestream = self.get_codestream()
max_rlevel = codestream.segment[2].spcod[4]
if rlevel == -1:
# -1 is shorthand for the largest rlevel
rlevel = max_rlevel
if rlevel < -1 or rlevel > max_rlevel:
msg = "rlevel must be in the range [-1, {0}] for this image."
msg = msg.format(max_rlevel)
raise IOError(msg)
with ExitStack() as stack:
try:
# Set decoding parameters.

View file

@ -1,148 +0,0 @@
"""
These tests deal with JPX/JP2/J2K images in the format-corpus repository.
"""
# R0904: Not too many methods in unittest.
# pylint: disable=R0904
# E1101: assertWarns introduced in python 3.2
# pylint: disable=E1101
import os
from os.path import join
import re
import sys
import tempfile
import unittest
import glymur
from glymur import Jp2k
try:
FORMAT_CORPUS_DATA_ROOT = os.environ['FORMAT_CORPUS_DATA_ROOT']
except KeyError:
FORMAT_CORPUS_DATA_ROOT = None
try:
OPJ_DATA_ROOT = os.environ['OPJ_DATA_ROOT']
except KeyError:
OPJ_DATA_ROOT = None
@unittest.skipIf(sys.hexversion < 0x03020000,
"Requires features introduced in 3.2 (assertWarns)")
class TestSuiteConformance(unittest.TestCase):
"""Test suite for conformance."""
def setUp(self):
self.j2kfile = glymur.data.goodstuff()
def tearDown(self):
pass
@unittest.skipIf(re.match(r"""1\.[0123]""",
glymur.version.openjpeg_version) is not None,
"Needs 1.3+ to catch this.")
def test_truncated_eoc(self):
"""Has one byte shaved off of EOC marker."""
with open(self.j2kfile, 'rb') as ifile:
data = ifile.read()
with tempfile.NamedTemporaryFile(suffix='.j2k') as ofile:
ofile.write(data[:-1])
ofile.flush()
j2k = Jp2k(ofile.name)
with self.assertWarns(UserWarning):
codestream = j2k.get_codestream(header_only=False)
# The last segment is truncated, so there should not be an EOC
# marker.
self.assertNotEqual(codestream.segment[-1].marker_id, 'EOC')
# The codestream is not as long as claimed.
with self.assertRaises(OSError):
j2k.read(rlevel=-1)
@unittest.skipIf(FORMAT_CORPUS_DATA_ROOT is None,
"FORMAT_CORPUS_DATA_ROOT environment variable not set")
@unittest.skipIf(sys.hexversion < 0x03020000,
"Requires features introduced in 3.2 (assertWarns)")
class TestSuiteFormatCorpus(unittest.TestCase):
"""Test suite for files in format corpus repository."""
@unittest.skipIf(re.match(r"""1\.[01234]""",
glymur.version.openjpeg_version) is not None,
"Needs 1.4+ to catch this.")
def test_balloon_trunc2(self):
"""Shortened by 5000 bytes."""
jfile = os.path.join(FORMAT_CORPUS_DATA_ROOT,
'jp2k-test/byteCorruption/balloon_trunc2.jp2')
j2k = Jp2k(jfile)
with self.assertWarns(UserWarning):
codestream = j2k.get_codestream(header_only=False)
# The last segment is truncated, so there should not be an EOC marker.
self.assertNotEqual(codestream.segment[-1].marker_id, 'EOC')
# The codestream is not as long as claimed.
with self.assertRaises(OSError):
j2k.read(rlevel=-1)
def test_balloon_trunc3(self):
"""Most of last tile is missing."""
jfile = os.path.join(FORMAT_CORPUS_DATA_ROOT,
'jp2k-test/byteCorruption/balloon_trunc3.jp2')
j2k = Jp2k(jfile)
with self.assertWarns(UserWarning):
codestream = j2k.get_codestream(header_only=False)
# The last segment is truncated, so there should not be an EOC marker.
self.assertNotEqual(codestream.segment[-1].marker_id, 'EOC')
# Should error out, it does not.
#with self.assertRaises(OSError):
# j2k.read(rlevel=-1)
def test_jp2_brand_any_icc_profile(self):
"""If 'jp2 ', then the method cannot be any icc profile."""
jfile = os.path.join(FORMAT_CORPUS_DATA_ROOT,
'jp2k-test', 'icc',
'balloon_eciRGBv2_ps_adobeplugin.jpf')
with self.assertWarns(UserWarning):
Jp2k(jfile)
def test_jp2_brand_iccpr_mult_colr(self):
"""Has colr box, one that conforms, one that does not."""
# Wrong 'brand' field; contains two versions of ICC profile: one
# embedded using "Any ICC" method; other embedded using "Restricted
# ICC" method, with description ("Modified eciRGB v2") and profileClass
# ("Input Device") changed relative to original profile.
jfile = join(FORMAT_CORPUS_DATA_ROOT, 'jp2k-test', 'icc',
'balloon_eciRGBv2_ps_adobeplugin_jp2compatible.jpf')
with self.assertWarns(UserWarning):
Jp2k(jfile)
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
@unittest.skipIf(sys.hexversion < 0x03020000,
"Requires features introduced in 3.2 (assertWarns)")
class TestSuiteOpj(unittest.TestCase):
"""Test suite for files in openjpeg repository."""
def setUp(self):
pass
def tearDown(self):
pass
def test_jp2_brand_any_icc_profile(self):
"""If 'jp2 ', then the method cannot be any icc profile."""
filename = os.path.join(OPJ_DATA_ROOT,
'input/nonregression/text_GBR.jp2')
with self.assertWarns(UserWarning):
Jp2k(filename)
if __name__ == "__main__":
unittest.main()

View file

@ -386,15 +386,9 @@ class TestJp2k(unittest.TestCase):
# The file in question has multiple codestreams.
jpx = Jp2k(self.jpxfile)
data = jpx.read()
if re.match(r"""1\.[0123]""", glymur.version.openjpeg_version):
# openjpeg 1.3 doesn't apply the palette, so it's a 2D image here
self.assertEqual(data.shape, (1024, 1024))
else:
self.assertEqual(data.shape, (1024, 1024, 3))
self.assertEqual(data.shape, (1024, 1024, 3))
@unittest.skipIf(re.match(r"""1\.[01234]""", glymur.version.openjpeg_version),
"Requires at least version 1.5")
class TestJp2k_write(unittest.TestCase):
"""Write tests, can be run by versions 1.5+"""

View file

@ -381,11 +381,7 @@ class TestSuite(unittest.TestCase):
jfile = opj_data_file('input/conformance/file9.jp2')
jp2k = Jp2k(jfile)
jpdata = jp2k.read()
if re.match(r"""1\.3""", glymur.version.openjpeg_version):
# Version 1.3 reads the indexed image as indices, not as RGB.
self.assertEqual(jpdata.shape, (512, 768))
else:
self.assertEqual(jpdata.shape, (512, 768, 3))
self.assertEqual(jpdata.shape, (512, 768, 3))
def test_NR_DEC_Bretagne2_j2k_1_decode(self):
jfile = opj_data_file('input/nonregression/Bretagne2.j2k')
@ -6307,11 +6303,16 @@ class TestSuiteDump(unittest.TestCase):
[8, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10])
def test_NR_text_GBR_dump(self):
# brand is 'jp2 ', but has any icc profile.
# Verify the warning on python3, but ignore it otherwise.
jfile = opj_data_file('input/nonregression/text_GBR.jp2')
with warnings.catch_warnings():
# brand is 'jp2 ', but has any icc profile.
warnings.simplefilter("ignore")
jp2 = Jp2k(jfile)
if sys.hexversion > 0x03030000:
with self.assertWarns(UserWarning):
jp2 = Jp2k(jfile)
else:
with warnings.catch_warnings():
warnings.simplefilter("ignore")
jp2 = Jp2k(jfile)
ids = [box.box_id for box in jp2.box]
lst = ['jP ', 'ftyp', 'rreq', 'jp2h',

View file

@ -23,8 +23,6 @@ from glymur import Jp2k
import glymur
@unittest.skipIf(re.match(r"""1\.[01234]""", glymur.version.openjpeg_version),
"Functionality not implemented for 1.3, 1.4")
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_OPJ_DATA_ROOT environment variable not set")
class TestSuiteNegative2pointzero(unittest.TestCase):
@ -48,8 +46,6 @@ class TestSuiteNegative2pointzero(unittest.TestCase):
j.write(data, psnr=[30, 35, 40], cratios=[2, 3, 4])
@unittest.skipIf(re.match(r"""1\.[01234]""", glymur.version.openjpeg_version),
"Functionality not implemented for 1.3, 1.4")
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_OPJ_DATA_ROOT environment variable not set")
class TestSuiteNegative(unittest.TestCase):

View file

@ -249,9 +249,6 @@ class TestSuiteNegative2pointzero(unittest.TestCase):
@unittest.skipIf(os.name == "nt", "no write support on windows, period")
@unittest.skipIf(re.match(r"""1\.[01234]\.\d""",
glymur.version.openjpeg_version) is not None,
"Writing only supported with openjpeg version 1.5+.")
@unittest.skipIf(NO_READ_BACKEND, NO_READ_BACKEND_MSG)
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")