More negative tests, pylint work. #175
This commit is contained in:
parent
f8ced317db
commit
16ce2ef883
3 changed files with 72 additions and 27 deletions
|
|
@ -124,7 +124,7 @@ class Jp2kBox(object):
|
||||||
fptr.write(struct.pack('>I', end_pos - orig_pos))
|
fptr.write(struct.pack('>I', end_pos - orig_pos))
|
||||||
fptr.seek(end_pos)
|
fptr.seek(end_pos)
|
||||||
|
|
||||||
def parse_this_box(self, fptr, box_id, start, num_bytes):
|
def _parse_this_box(self, fptr, box_id, start, num_bytes):
|
||||||
"""Parse the current box.
|
"""Parse the current box.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
|
|
@ -214,7 +214,7 @@ class Jp2kBox(object):
|
||||||
# The box_length value really is the length of the box!
|
# The box_length value really is the length of the box!
|
||||||
num_bytes = box_length
|
num_bytes = box_length
|
||||||
|
|
||||||
box = self.parse_this_box(fptr, box_id, start, num_bytes)
|
box = self._parse_this_box(fptr, box_id, start, num_bytes)
|
||||||
|
|
||||||
superbox.append(box)
|
superbox.append(box)
|
||||||
|
|
||||||
|
|
@ -560,7 +560,8 @@ class ChannelDefinitionBox(Jp2kBox):
|
||||||
def _validate(self):
|
def _validate(self):
|
||||||
"""Verify that the box obeys the specifications."""
|
"""Verify that the box obeys the specifications."""
|
||||||
# channel type and association must be specified.
|
# channel type and association must be specified.
|
||||||
if not (len(self.index) == len(self.channel_type) == len(self.association)):
|
if not ((len(self.index) == len(self.channel_type)) and
|
||||||
|
(len(self.channel_type) == len(self.association))):
|
||||||
msg = "Length of channel definition box inputs must be the same."
|
msg = "Length of channel definition box inputs must be the same."
|
||||||
raise IOError(msg)
|
raise IOError(msg)
|
||||||
|
|
||||||
|
|
@ -953,10 +954,18 @@ class DataReferenceBox(Jp2kBox):
|
||||||
msg += 'entry URL boxes.'
|
msg += 'entry URL boxes.'
|
||||||
raise IOError(msg)
|
raise IOError(msg)
|
||||||
|
|
||||||
|
def _write_validate(self):
|
||||||
|
"""Verify that the box obeys the specifications for writing.
|
||||||
|
"""
|
||||||
|
if len(self.DR) == 0:
|
||||||
|
msg = "A data reference box cannot be empty when written to a file."
|
||||||
|
raise IOError(msg)
|
||||||
|
self._validate()
|
||||||
|
|
||||||
def write(self, fptr):
|
def write(self, fptr):
|
||||||
"""Write a Data Reference box to file.
|
"""Write a Data Reference box to file.
|
||||||
"""
|
"""
|
||||||
self._validate()
|
self._write_validate()
|
||||||
|
|
||||||
# Very similar to the say a superbox is written.
|
# Very similar to the say a superbox is written.
|
||||||
orig_pos = fptr.tell()
|
orig_pos = fptr.tell()
|
||||||
|
|
|
||||||
|
|
@ -1110,6 +1110,10 @@ def _validate_nonzero_image_size(nrows, ncols, component_index):
|
||||||
raise IOError(msg)
|
raise IOError(msg)
|
||||||
|
|
||||||
|
|
||||||
|
JP2_IDS = ['colr', 'cdef', 'cmap', 'jp2c', 'ftyp', 'ihdr', 'jp2h', 'jP ',
|
||||||
|
'pclr', 'res ', 'resc', 'resd', 'xml ', 'ulst', 'uinf', 'url ',
|
||||||
|
'uuid']
|
||||||
|
|
||||||
def _validate_jp2_box_sequence(boxes):
|
def _validate_jp2_box_sequence(boxes):
|
||||||
"""Run through series of tests for JP2 box legality.
|
"""Run through series of tests for JP2 box legality.
|
||||||
|
|
||||||
|
|
@ -1118,6 +1122,18 @@ def _validate_jp2_box_sequence(boxes):
|
||||||
_validate_signature_compatibility(boxes)
|
_validate_signature_compatibility(boxes)
|
||||||
_validate_jp2h(boxes)
|
_validate_jp2h(boxes)
|
||||||
_validate_jp2c(boxes)
|
_validate_jp2c(boxes)
|
||||||
|
if boxes[1].brand == 'jpx ':
|
||||||
|
_validate_jpx_box_sequence(boxes)
|
||||||
|
else:
|
||||||
|
count = _collect_box_count(boxes)
|
||||||
|
for id in count.keys():
|
||||||
|
if id not in JP2_IDS:
|
||||||
|
msg = "The presence of a '{0}' box requires that the file type "
|
||||||
|
msg += "brand be set to 'jpx '."
|
||||||
|
raise IOError(msg.format(id))
|
||||||
|
|
||||||
|
def _validate_jpx_box_sequence(boxes):
|
||||||
|
"""Run through series of tests for JPX box legality."""
|
||||||
_validate_association(boxes)
|
_validate_association(boxes)
|
||||||
_validate_label(boxes)
|
_validate_label(boxes)
|
||||||
_validate_jpx_brand(boxes, boxes[1].brand)
|
_validate_jpx_brand(boxes, boxes[1].brand)
|
||||||
|
|
@ -1125,7 +1141,6 @@ def _validate_jp2_box_sequence(boxes):
|
||||||
_validate_singletons(boxes)
|
_validate_singletons(boxes)
|
||||||
_validate_top_level(boxes)
|
_validate_top_level(boxes)
|
||||||
|
|
||||||
|
|
||||||
def _validate_signature_compatibility(boxes):
|
def _validate_signature_compatibility(boxes):
|
||||||
"""Validate the file signature and compatibility status."""
|
"""Validate the file signature and compatibility status."""
|
||||||
# Check for a bad sequence of boxes.
|
# Check for a bad sequence of boxes.
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,10 @@ Test suite specifically targeting JPX box layout.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import shutil
|
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
import warnings
|
|
||||||
import xml.etree.cElementTree as ET
|
import xml.etree.cElementTree as ET
|
||||||
|
|
||||||
import glymur
|
import glymur
|
||||||
|
|
@ -41,6 +39,18 @@ class TestJPXWrap(unittest.TestCase):
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
os.unlink(self.xmlfile)
|
os.unlink(self.xmlfile)
|
||||||
|
|
||||||
|
def test_jp2_with_jpx_box(self):
|
||||||
|
"""If the brand is jp2, then no jpx boxes are allowed."""
|
||||||
|
jp2 = Jp2k(self.jp2file)
|
||||||
|
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
|
||||||
|
boxes = jp2.box
|
||||||
|
|
||||||
|
boxes.append(glymur.jp2box.AssociationBox())
|
||||||
|
|
||||||
|
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
|
||||||
|
with self.assertRaises(IOError):
|
||||||
|
jp2.wrap(tfile.name, boxes=boxes)
|
||||||
|
|
||||||
def test_ftbl(self):
|
def test_ftbl(self):
|
||||||
"""Write a fragment table box."""
|
"""Write a fragment table box."""
|
||||||
# Add a negative test where offset < 0
|
# Add a negative test where offset < 0
|
||||||
|
|
@ -128,17 +138,18 @@ class TestJPXWrap(unittest.TestCase):
|
||||||
self.assertEqual(jpx.box[-1].box[2].label, label)
|
self.assertEqual(jpx.box[-1].box[2].label, label)
|
||||||
|
|
||||||
def test_empty_data_reference(self):
|
def test_empty_data_reference(self):
|
||||||
"""Data reference boxes can be empty."""
|
"""Empty data reference boxes can be created, but not written."""
|
||||||
jp2 = Jp2k(self.jp2file)
|
jp2 = Jp2k(self.jp2file)
|
||||||
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
|
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
|
||||||
|
|
||||||
|
boxes[1].brand = 'jpx '
|
||||||
|
|
||||||
dref = glymur.jp2box.DataReferenceBox()
|
dref = glymur.jp2box.DataReferenceBox()
|
||||||
boxes.append(dref)
|
boxes.append(dref)
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
|
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
|
||||||
jpx = jp2.wrap(tfile.name, boxes=boxes)
|
with self.assertRaises(IOError):
|
||||||
self.assertEqual(jpx.box[-1].box_id, 'dtbl')
|
jp2.wrap(tfile.name, boxes=boxes)
|
||||||
self.assertEqual(len(jpx.box[-1].box), 0)
|
|
||||||
|
|
||||||
def test_deurl_child_of_dtbl(self):
|
def test_deurl_child_of_dtbl(self):
|
||||||
"""Data reference boxes can only contain data entry url boxes."""
|
"""Data reference boxes can only contain data entry url boxes."""
|
||||||
|
|
@ -157,13 +168,16 @@ class TestJPXWrap(unittest.TestCase):
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
|
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
|
||||||
with self.assertRaises(IOError):
|
with self.assertRaises(IOError):
|
||||||
jpx = jp2.wrap(tfile.name, boxes=boxes)
|
jp2.wrap(tfile.name, boxes=boxes)
|
||||||
|
|
||||||
def test_only_one_data_reference(self):
|
def test_only_one_data_reference(self):
|
||||||
"""Data reference boxes cannot be inside a superbox ."""
|
"""Data reference boxes cannot be inside a superbox ."""
|
||||||
jp2 = Jp2k(self.jp2file)
|
jp2 = Jp2k(self.jp2file)
|
||||||
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
|
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
|
||||||
|
|
||||||
|
# Have to make the ftyp brand jpx.
|
||||||
|
boxes[1].brand = 'jpx '
|
||||||
|
|
||||||
flag = 0
|
flag = 0
|
||||||
version = (0, 0, 0)
|
version = (0, 0, 0)
|
||||||
url = 'file:////usr/local/bin'
|
url = 'file:////usr/local/bin'
|
||||||
|
|
@ -174,16 +188,16 @@ class TestJPXWrap(unittest.TestCase):
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
|
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
|
||||||
with self.assertRaises(IOError):
|
with self.assertRaises(IOError):
|
||||||
jpx = jp2.wrap(tfile.name, boxes=boxes)
|
jp2.wrap(tfile.name, boxes=boxes)
|
||||||
|
|
||||||
def test_lbl_at_top_level(self):
|
def test_lbl_at_top_level(self):
|
||||||
"""Label boxes can only be inside a asoc box ."""
|
"""Label boxes can only be inside a asoc box ."""
|
||||||
jp2 = Jp2k(self.jp2file)
|
jp2 = Jp2k(self.jp2file)
|
||||||
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
|
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
|
||||||
|
|
||||||
flag = 0
|
# Have to make the ftyp brand jpx.
|
||||||
version = (0, 0, 0)
|
boxes[1].brand = 'jpx '
|
||||||
url = 'file:////usr/local/bin'
|
|
||||||
lblb = glymur.jp2box.LabelBox('hi there')
|
lblb = glymur.jp2box.LabelBox('hi there')
|
||||||
|
|
||||||
# Put it inside the jp2 header box.
|
# Put it inside the jp2 header box.
|
||||||
|
|
@ -191,13 +205,16 @@ class TestJPXWrap(unittest.TestCase):
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
|
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
|
||||||
with self.assertRaises(IOError):
|
with self.assertRaises(IOError):
|
||||||
jpx = jp2.wrap(tfile.name, boxes=boxes)
|
jp2.wrap(tfile.name, boxes=boxes)
|
||||||
|
|
||||||
def test_data_reference_not_at_top_level(self):
|
def test_data_reference_in_subbox(self):
|
||||||
"""Data reference boxes cannot be inside a superbox ."""
|
"""Data reference boxes cannot be inside a superbox ."""
|
||||||
jp2 = Jp2k(self.jp2file)
|
jp2 = Jp2k(self.jp2file)
|
||||||
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
|
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
|
||||||
|
|
||||||
|
# Have to make the ftyp brand jpx.
|
||||||
|
boxes[1].brand = 'jpx '
|
||||||
|
|
||||||
flag = 0
|
flag = 0
|
||||||
version = (0, 0, 0)
|
version = (0, 0, 0)
|
||||||
url = 'file:////usr/local/bin'
|
url = 'file:////usr/local/bin'
|
||||||
|
|
@ -209,13 +226,17 @@ class TestJPXWrap(unittest.TestCase):
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
|
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
|
||||||
with self.assertRaises(IOError):
|
with self.assertRaises(IOError):
|
||||||
jpx = jp2.wrap(tfile.name, boxes=boxes)
|
jp2.wrap(tfile.name, boxes=boxes)
|
||||||
|
|
||||||
def test_jp2_to_jpx_sans_jp2_compatibility(self):
|
def test_jp2_to_jpx_sans_jp2_compatibility(self):
|
||||||
"""jp2 wrapped to jpx not including jp2 compatibility is wrong."""
|
"""jp2 wrapped to jpx not including jp2 compatibility is wrong."""
|
||||||
jp2 = Jp2k(self.jp2file)
|
jp2 = Jp2k(self.jp2file)
|
||||||
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
|
boxes = [jp2.box[idx] for idx in [0, 1, 2, 4]]
|
||||||
|
|
||||||
|
# Have to make the ftyp brand jpx.
|
||||||
|
boxes[1].brand = 'jpx '
|
||||||
boxes[1].compatibility_list.append('jp2 ')
|
boxes[1].compatibility_list.append('jp2 ')
|
||||||
|
|
||||||
numbers = [0, 1]
|
numbers = [0, 1]
|
||||||
nlst = glymur.jp2box.NumberListBox(numbers)
|
nlst = glymur.jp2box.NumberListBox(numbers)
|
||||||
the_xml = ET.fromstring('<?xml version="1.0"?><data>0</data>')
|
the_xml = ET.fromstring('<?xml version="1.0"?><data>0</data>')
|
||||||
|
|
@ -225,7 +246,7 @@ class TestJPXWrap(unittest.TestCase):
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
|
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(RuntimeError):
|
||||||
jpx = jp2.wrap(tfile.name, boxes=boxes)
|
jp2.wrap(tfile.name, boxes=boxes)
|
||||||
|
|
||||||
def test_jp2_to_jpx_sans_jpx_brand(self):
|
def test_jp2_to_jpx_sans_jpx_brand(self):
|
||||||
"""Verify error when jp2 wrapped to jpx does not include jpx brand."""
|
"""Verify error when jp2 wrapped to jpx does not include jpx brand."""
|
||||||
|
|
@ -241,7 +262,7 @@ class TestJPXWrap(unittest.TestCase):
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
|
with tempfile.NamedTemporaryFile(suffix=".jpx") as tfile:
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(RuntimeError):
|
||||||
jpx = jp2.wrap(tfile.name, boxes=boxes)
|
jp2.wrap(tfile.name, boxes=boxes)
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
|
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
|
||||||
|
|
@ -262,7 +283,7 @@ class TestJPX(unittest.TestCase):
|
||||||
flst = glymur.jp2box.FragmentListBox(offset, length, reference)
|
flst = glymur.jp2box.FragmentListBox(offset, length, reference)
|
||||||
with self.assertRaises(IOError):
|
with self.assertRaises(IOError):
|
||||||
with tempfile.TemporaryFile() as tfile:
|
with tempfile.TemporaryFile() as tfile:
|
||||||
flst.write(tfile)
|
flst.write(tfile)
|
||||||
|
|
||||||
def test_flst_offsets_not_positive(self):
|
def test_flst_offsets_not_positive(self):
|
||||||
"""A fragment list box offsets must be positive."""
|
"""A fragment list box offsets must be positive."""
|
||||||
|
|
@ -272,7 +293,7 @@ class TestJPX(unittest.TestCase):
|
||||||
flst = glymur.jp2box.FragmentListBox(offset, length, reference)
|
flst = glymur.jp2box.FragmentListBox(offset, length, reference)
|
||||||
with self.assertRaises(IOError):
|
with self.assertRaises(IOError):
|
||||||
with tempfile.TemporaryFile() as tfile:
|
with tempfile.TemporaryFile() as tfile:
|
||||||
flst.write(tfile)
|
flst.write(tfile)
|
||||||
|
|
||||||
def test_flst_lengths_not_positive(self):
|
def test_flst_lengths_not_positive(self):
|
||||||
"""A fragment list box lengths must be positive."""
|
"""A fragment list box lengths must be positive."""
|
||||||
|
|
@ -282,7 +303,7 @@ class TestJPX(unittest.TestCase):
|
||||||
flst = glymur.jp2box.FragmentListBox(offset, length, reference)
|
flst = glymur.jp2box.FragmentListBox(offset, length, reference)
|
||||||
with self.assertRaises(IOError):
|
with self.assertRaises(IOError):
|
||||||
with tempfile.TemporaryFile() as tfile:
|
with tempfile.TemporaryFile() as tfile:
|
||||||
flst.write(tfile)
|
flst.write(tfile)
|
||||||
|
|
||||||
def test_ftbl_boxes_empty(self):
|
def test_ftbl_boxes_empty(self):
|
||||||
"""A fragment table box must have at least one child box."""
|
"""A fragment table box must have at least one child box."""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue