Merge branch 'issue186' into devel

This commit is contained in:
John Evans 2014-03-13 14:36:55 -04:00
commit 48d2c97a39
4 changed files with 92 additions and 27 deletions

View file

@ -17,6 +17,7 @@ codestreams.
# the base Segment class.
# pylint: disable=R0903
import collections
import math
import struct
import sys
@ -30,12 +31,26 @@ from .core import WAVELET_XFORM_5X3_REVERSIBLE
from .core import _CAPABILITIES_DISPLAY
from .lib import openjp2 as opj2
_PROGRESSION_ORDER_DISPLAY = {
LRCP: 'LRCP',
RLCP: 'RLCP',
RPCL: 'RPCL',
PCRL: 'PCRL',
CPRL: 'CPRL'}
class _keydefaultdict(collections.defaultdict):
"""Unlisted keys help form their own error message.
Normally defaultdict uses a factory function with no input arguments, but
that's not quite the behavior we want.
"""
def __missing__(self, key):
if self.default_factory is None:
raise KeyError(key)
else:
ret = self[key] = self.default_factory(key)
return ret
_factory = lambda x: '{0} (invalid)'.format(x)
_PROGRESSION_ORDER_DISPLAY = _keydefaultdict(_factory,
{ LRCP: 'LRCP',
RLCP: 'RLCP',
RPCL: 'RPCL',
PCRL: 'PCRL',
CPRL: 'CPRL'})
_WAVELET_TRANSFORM_DISPLAY = {
WAVELET_XFORM_9X7_IRREVERSIBLE: '9-7 irreversible',
@ -371,6 +386,9 @@ class Codestream(object):
numbytes = offset + 2 + length - fptr.tell()
spcod = fptr.read(numbytes)
spcod = np.frombuffer(spcod, dtype=np.uint8)
if spcod[0] not in [LRCP, RLCP, RPCL, PCRL, CPRL]:
msg = "Invalid progression order in COD segment: {0}."
warnings.warn(msg.format(spcod[0]))
sop = (scod & 2) > 0
eph = (scod & 4) > 0

View file

@ -587,3 +587,26 @@ issue_183_colr = """Colour Specification Box (colr) @ (62, 12)
Method: restricted ICC profile
Precedence: 0
ICC Profile: None"""
# Progression order is invalid.
issue_186_progression_order = """COD marker segment @ (174, 12)
Coding style:
Entropy coder, without partitions
SOP marker segments: False
EPH marker segments: False
Coding style parameters:
Progression order: 33 (invalid)
Number of layers: 1
Multiple component transformation usage: reversible
Number of resolutions: 6
Code block height, width: (32 x 32)
Wavelet transform: 9-7 irreversible
Precinct size: default, 2^15 x 2^15
Code block context:
Selective arithmetic coding bypass: False
Reset context probabilities on coding pass boundaries: False
Termination on each coding pass: False
Vertically stripe causal context: False
Predictable termination: False
Segmentation symbols: False"""

View file

@ -29,8 +29,39 @@ class TestCodestream(unittest.TestCase):
def tearDown(self):
pass
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
def test_siz_segment_ssiz_unsigned(self):
"""ssiz attribute to be removed in future release"""
j = Jp2k(self.jp2file)
codestream = j.get_codestream()
# The ssiz attribute was simply a tuple of raw bytes.
# The first 7 bits are interpreted as the bitdepth, the MSB determines
# whether or not it is signed.
self.assertEqual(codestream.segment[1].ssiz, (7, 7, 7))
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
class TestCodestreamOpjData(unittest.TestCase):
"""Test suite for unusual codestream cases. Uses OPJ_DATA_ROOT"""
def setUp(self):
self.jp2file = glymur.data.nemo()
def tearDown(self):
pass
def test_invalid_progression_order(self):
"""Should still be able to parse even if prog order is invalid."""
jfile = opj_data_file('input/nonregression/2977.pdf.asan.67.2198.jp2')
if sys.hexversion < 0x03000000:
with warnings.catch_warnings():
warnings.simplefilter("ignore")
Jp2k(jfile)
else:
with self.assertWarns(UserWarning):
Jp2k(jfile)
def test_tile_height_is_zero(self):
"""Zero tile height should not cause an exception."""
filename = opj_data_file('input/nonregression/2539.pdf.SIGFPE.706.1712.jp2')
@ -43,8 +74,6 @@ class TestCodestream(unittest.TestCase):
Jp2k(filename)
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
def test_reserved_marker_segment(self):
"""Reserved marker segments are ok."""
@ -76,8 +105,6 @@ class TestCodestream(unittest.TestCase):
self.assertEqual(codestream.segment[2].length, 3)
self.assertEqual(codestream.segment[2].data, b'\x00')
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
@unittest.skipIf(sys.hexversion < 0x03020000,
"Uses features introduced in 3.2.")
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
@ -109,8 +136,6 @@ class TestCodestream(unittest.TestCase):
self.assertEqual(codestream.segment[2].length, 3)
self.assertEqual(codestream.segment[2].data, b'\x00')
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
def test_psot_is_zero(self):
"""Psot=0 in SOT is perfectly legal. Issue #78."""
filename = os.path.join(OPJ_DATA_ROOT,
@ -123,19 +148,6 @@ class TestCodestream(unittest.TestCase):
self.assertEqual(codestream.segment[-1].marker_id, 'EOC')
def test_siz_segment_ssiz_unsigned(self):
"""ssiz attribute to be removed in future release"""
j = Jp2k(self.jp2file)
codestream = j.get_codestream()
# The ssiz attribute was simply a tuple of raw bytes.
# The first 7 bits are interpreted as the bitdepth, the MSB determines
# whether or not it is signed.
self.assertEqual(codestream.segment[1].ssiz, (7, 7, 7))
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
def test_siz_segment_ssiz_signed(self):
"""ssiz attribute to be removed in future release"""
filename = os.path.join(OPJ_DATA_ROOT, 'input/conformance/p0_03.j2k')

View file

@ -645,6 +645,18 @@ class TestPrintingOpjDataRoot(unittest.TestCase):
def tearDown(self):
pass
def test_invalid_progression_order(self):
"""Should still be able to print even if prog order is invalid."""
jfile = opj_data_file('input/nonregression/2977.pdf.asan.67.2198.jp2')
with warnings.catch_warnings():
warnings.simplefilter("ignore")
jp2 = Jp2k(jfile)
codestream = jp2.get_codestream()
with patch('sys.stdout', new=StringIO()) as fake_out:
print(codestream.segment[2])
actual = fake_out.getvalue().strip()
self.assertEqual(actual, fixtures.issue_186_progression_order)
def test_crg(self):
"""verify printing of CRG segment"""
filename = opj_data_file('input/conformance/p0_03.j2k')