pylint work, #99

This commit is contained in:
John Evans 2013-08-11 14:49:44 -04:00
commit 2acb8d6c94

View file

@ -1,4 +1,21 @@
#pylint: disable-all """
Test suite specifically targeting JP2 box layout.
"""
# E1103: return value from read may be list or np array
# pylint: disable=E1103
# F0401: unittest2 is needed on python-2.6 (pylint on 2.7)
# pylint: disable=F0401
# R0902: More than 7 instance attributes are just fine for testing.
# pylint: disable=R0902
# R0904: Seems like pylint is fooled in this situation
# pylint: disable=R0904
# W0613: load_tests doesn't need to use ignore or loader arguments.
# pylint: disable=W0613
import doctest import doctest
import os import os
import sys import sys
@ -11,24 +28,25 @@ else:
import unittest import unittest
import numpy as np import numpy as np
import pkg_resources
import glymur import glymur
from glymur import Jp2k from glymur import Jp2k
from glymur.jp2box import * from glymur.jp2box import ColourSpecificationBox, ContiguousCodestreamBox
from glymur.jp2box import FileTypeBox, ImageHeaderBox, JP2HeaderBox
from glymur.jp2box import JPEG2000SignatureBox
from glymur.core import COLOR, OPACITY from glymur.core import COLOR, OPACITY
from glymur.core import RED, GREEN, BLUE, GREY, WHOLE_IMAGE from glymur.core import RED, GREEN, BLUE, GREY, WHOLE_IMAGE
from .fixtures import OPENJP2_IS_V2_OFFICIAL from .fixtures import OPENJP2_IS_V2_OFFICIAL
try: try:
format_corpus_data_root = os.environ['FORMAT_CORPUS_DATA_ROOT'] FORMAT_CORPUS_DATA_ROOT = os.environ['FORMAT_CORPUS_DATA_ROOT']
except KeyError: except KeyError:
format_corpus_data_root = None FORMAT_CORPUS_DATA_ROOT = None
# Doc tests should be run as well.
def load_tests(loader, tests, ignore): def load_tests(loader, tests, ignore):
"""Run doc tests as well."""
if os.name == "nt": if os.name == "nt":
# Can't do it on windows, temporary file issue. # Can't do it on windows, temporary file issue.
return tests return tests
@ -42,6 +60,7 @@ def load_tests(loader, tests, ignore):
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None, @unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
"Missing openjp2 library.") "Missing openjp2 library.")
class TestChannelDefinition(unittest.TestCase): class TestChannelDefinition(unittest.TestCase):
"""Test suite for channel definition boxes."""
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
@ -78,12 +97,12 @@ class TestChannelDefinition(unittest.TestCase):
self.j2kfile = glymur.data.goodstuff() self.j2kfile = glymur.data.goodstuff()
j2k = Jp2k(self.j2kfile) j2k = Jp2k(self.j2kfile)
c = j2k.get_codestream() codestream = j2k.get_codestream()
height = c.segment[1].ysiz height = codestream.segment[1].ysiz
width = c.segment[1].xsiz width = codestream.segment[1].xsiz
num_components = len(c.segment[1].xrsiz) num_components = len(codestream.segment[1].xrsiz)
self.jP = JPEG2000SignatureBox() self.jp2b = JPEG2000SignatureBox()
self.ftyp = FileTypeBox() self.ftyp = FileTypeBox()
self.jp2h = JP2HeaderBox() self.jp2h = JP2HeaderBox()
self.jp2c = ContiguousCodestreamBox() self.jp2c = ContiguousCodestreamBox()
@ -110,7 +129,7 @@ class TestChannelDefinition(unittest.TestCase):
association=association) association=association)
boxes = [self.ihdr, self.colr_rgb, cdef] boxes = [self.ihdr, self.colr_rgb, cdef]
self.jp2h.box = boxes self.jp2h.box = boxes
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c]
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
j2k.wrap(tfile.name, boxes=boxes) j2k.wrap(tfile.name, boxes=boxes)
@ -133,7 +152,7 @@ class TestChannelDefinition(unittest.TestCase):
association=association) association=association)
boxes = [self.ihdr, self.colr_rgb, cdef] boxes = [self.ihdr, self.colr_rgb, cdef]
self.jp2h.box = boxes self.jp2h.box = boxes
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c]
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
j2k.wrap(tfile.name, boxes=boxes) j2k.wrap(tfile.name, boxes=boxes)
@ -156,7 +175,7 @@ class TestChannelDefinition(unittest.TestCase):
association=association) association=association)
boxes = [self.ihdr, self.colr_rgb, cdef] boxes = [self.ihdr, self.colr_rgb, cdef]
self.jp2h.box = boxes self.jp2h.box = boxes
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c]
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
j2k.wrap(tfile.name, boxes=boxes) j2k.wrap(tfile.name, boxes=boxes)
@ -177,9 +196,9 @@ class TestChannelDefinition(unittest.TestCase):
association=association) association=association)
boxes = [self.ihdr, self.colr_rgb, cdef] boxes = [self.ihdr, self.colr_rgb, cdef]
self.jp2h.box = boxes self.jp2h.box = boxes
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c]
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
with self.assertRaises(IOError) as ce: with self.assertRaises(IOError):
j2k.wrap(tfile.name, boxes=boxes) j2k.wrap(tfile.name, boxes=boxes)
def test_grey(self): def test_grey(self):
@ -191,7 +210,7 @@ class TestChannelDefinition(unittest.TestCase):
association=association) association=association)
boxes = [self.ihdr, self.colr_gr, cdef] boxes = [self.ihdr, self.colr_gr, cdef]
self.jp2h.box = boxes self.jp2h.box = boxes
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c]
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
j2k.wrap(tfile.name, boxes=boxes) j2k.wrap(tfile.name, boxes=boxes)
@ -212,7 +231,7 @@ class TestChannelDefinition(unittest.TestCase):
association=association) association=association)
boxes = [self.ihdr, self.colr_gr, cdef] boxes = [self.ihdr, self.colr_gr, cdef]
self.jp2h.box = boxes self.jp2h.box = boxes
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c]
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
j2k.wrap(tfile.name, boxes=boxes) j2k.wrap(tfile.name, boxes=boxes)
@ -236,12 +255,12 @@ class TestChannelDefinition(unittest.TestCase):
association=association) association=association)
boxes = [self.ihdr, self.colr_gr, cdef] boxes = [self.ihdr, self.colr_gr, cdef]
self.jp2h.box = boxes self.jp2h.box = boxes
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c]
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
with self.assertRaises((OSError, IOError)) as ce: with self.assertRaises((OSError, IOError)):
j2k.wrap(tfile.name, boxes=boxes) j2k.wrap(tfile.name, boxes=boxes)
def test_only_one_cdef_in_jp2_header(self): def test_only_one_cdef_in_jp2h(self):
"""There can only be one channel definition box in the jp2 header.""" """There can only be one channel definition box in the jp2 header."""
j2k = Jp2k(self.j2kfile) j2k = Jp2k(self.j2kfile)
@ -253,13 +272,14 @@ class TestChannelDefinition(unittest.TestCase):
boxes = [self.ihdr, cdef, self.colr_rgb, cdef] boxes = [self.ihdr, cdef, self.colr_rgb, cdef]
self.jp2h.box = boxes self.jp2h.box = boxes
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c]
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
with self.assertRaises(IOError): with self.assertRaises(IOError):
j2k.wrap(tfile.name, boxes=boxes) j2k.wrap(tfile.name, boxes=boxes)
def test_not_in_jp2_header(self): def test_not_in_jp2h(self):
"""need cdef in jp2h"""
j2k = Jp2k(self.j2kfile) j2k = Jp2k(self.j2kfile)
boxes = [self.ihdr, self.colr_rgb] boxes = [self.ihdr, self.colr_rgb]
self.jp2h.box = boxes self.jp2h.box = boxes
@ -269,34 +289,37 @@ class TestChannelDefinition(unittest.TestCase):
cdef = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type, cdef = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
association=association) association=association)
boxes = [self.jP, self.ftyp, self.jp2h, cdef, self.jp2c] boxes = [self.jp2b, self.ftyp, self.jp2h, cdef, self.jp2c]
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
with self.assertRaises(IOError): with self.assertRaises(IOError):
j2k.wrap(tfile.name, boxes=boxes) j2k.wrap(tfile.name, boxes=boxes)
def test_bad_type(self): def test_bad_type(self):
# Channel types are limited to 0, 1, 2, 65535 """Channel types are limited to 0, 1, 2, 65535
# Should reject if not all of index, channel_type, association the Should reject if not all of index, channel_type, association the
# same length. same length.
"""
channel_type = (COLOR, COLOR, 3) channel_type = (COLOR, COLOR, 3)
association = (RED, GREEN, BLUE) association = (RED, GREEN, BLUE)
with self.assertRaises(IOError): with self.assertRaises(IOError):
box = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type, glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
association=association) association=association)
def test_wrong_lengths(self): def test_wrong_lengths(self):
# Should reject if not all of index, channel_type, association the """Should reject if not all of index, channel_type, association the
# same length. same length.
"""
channel_type = (COLOR, COLOR) channel_type = (COLOR, COLOR)
association = (RED, GREEN, BLUE) association = (RED, GREEN, BLUE)
with self.assertRaises(IOError): with self.assertRaises(IOError):
box = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type, glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type,
association=association) association=association)
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.") @unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
class TestXML(unittest.TestCase): class TestXML(unittest.TestCase):
"""Test suite for XML boxes."""
def setUp(self): def setUp(self):
self.jp2file = glymur.data.nemo() self.jp2file = glymur.data.nemo()
@ -331,12 +354,12 @@ class TestXML(unittest.TestCase):
self.xmlfile = tfile.name self.xmlfile = tfile.name
j2k = Jp2k(self.j2kfile) j2k = Jp2k(self.j2kfile)
c = j2k.get_codestream() codestream = j2k.get_codestream()
height = c.segment[1].ysiz height = codestream.segment[1].ysiz
width = c.segment[1].xsiz width = codestream.segment[1].xsiz
num_components = len(c.segment[1].xrsiz) num_components = len(codestream.segment[1].xrsiz)
self.jP = JPEG2000SignatureBox() self.jp2b = JPEG2000SignatureBox()
self.ftyp = FileTypeBox() self.ftyp = FileTypeBox()
self.jp2h = JP2HeaderBox() self.jp2h = JP2HeaderBox()
self.jp2c = ContiguousCodestreamBox() self.jp2c = ContiguousCodestreamBox()
@ -346,19 +369,17 @@ class TestXML(unittest.TestCase):
def tearDown(self): def tearDown(self):
os.unlink(self.xmlfile) os.unlink(self.xmlfile)
pass
def test_negative_both_file_and_xml_provided(self): def test_negative_file_and_xml(self):
"""The XML should come from only one source.""" """The XML should come from only one source."""
j2k = Jp2k(self.j2kfile)
xml_object = ET.parse(self.xmlfile) xml_object = ET.parse(self.xmlfile)
with self.assertRaises((IOError, OSError)) as ce: with self.assertRaises((IOError, OSError)):
xmlb = glymur.jp2box.XMLBox(filename=self.xmlfile, xml=xml_object) glymur.jp2box.XMLBox(filename=self.xmlfile, xml=xml_object)
@unittest.skipIf(os.name == "nt", @unittest.skipIf(os.name == "nt",
"Problems using NamedTemporaryFile on windows.") "Problems using NamedTemporaryFile on windows.")
def test_basic_xml(self): def test_basic_xml(self):
# Should be able to write an XMLBox. """Should be able to write a basic XMLBox"""
j2k = Jp2k(self.j2kfile) j2k = Jp2k(self.j2kfile)
self.jp2h.box = [self.ihdr, self.colr] self.jp2h.box = [self.ihdr, self.colr]
@ -368,7 +389,7 @@ class TestXML(unittest.TestCase):
self.assertEqual(ET.tostring(xmlb.xml), self.assertEqual(ET.tostring(xmlb.xml),
b'<data>0</data>') b'<data>0</data>')
boxes = [self.jP, self.ftyp, self.jp2h, xmlb, self.jp2c] boxes = [self.jp2b, self.ftyp, self.jp2h, xmlb, self.jp2c]
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
j2k.wrap(tfile.name, boxes=boxes) j2k.wrap(tfile.name, boxes=boxes)
@ -380,12 +401,13 @@ class TestXML(unittest.TestCase):
@unittest.skipIf(os.name == "nt", @unittest.skipIf(os.name == "nt",
"Problems using NamedTemporaryFile on windows.") "Problems using NamedTemporaryFile on windows.")
def test_xml_from_file(self): def test_xml_from_file(self):
"""Must be able to create an XML box from an XML file."""
j2k = Jp2k(self.j2kfile) j2k = Jp2k(self.j2kfile)
self.jp2h.box = [self.ihdr, self.colr] self.jp2h.box = [self.ihdr, self.colr]
xmlb = glymur.jp2box.XMLBox(filename=self.xmlfile) xmlb = glymur.jp2box.XMLBox(filename=self.xmlfile)
boxes = [self.jP, self.ftyp, self.jp2h, xmlb, self.jp2c] boxes = [self.jp2b, self.ftyp, self.jp2h, xmlb, self.jp2c]
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
j2k.wrap(tfile.name, boxes=boxes) j2k.wrap(tfile.name, boxes=boxes)
jp2 = Jp2k(tfile.name) jp2 = Jp2k(tfile.name)
@ -403,17 +425,18 @@ class TestXML(unittest.TestCase):
class TestColourSpecificationBox(unittest.TestCase): class TestColourSpecificationBox(unittest.TestCase):
"""Test suite for colr box instantiation."""
def setUp(self): def setUp(self):
self.j2kfile = glymur.data.goodstuff() self.j2kfile = glymur.data.goodstuff()
j2k = Jp2k(self.j2kfile) j2k = Jp2k(self.j2kfile)
c = j2k.get_codestream() codestream = j2k.get_codestream()
height = c.segment[1].ysiz height = codestream.segment[1].ysiz
width = c.segment[1].xsiz width = codestream.segment[1].xsiz
num_components = len(c.segment[1].xrsiz) num_components = len(codestream.segment[1].xrsiz)
self.jP = JPEG2000SignatureBox() self.jp2b = JPEG2000SignatureBox()
self.ftyp = FileTypeBox() self.ftyp = FileTypeBox()
self.jp2h = JP2HeaderBox() self.jp2h = JP2HeaderBox()
self.jp2c = ContiguousCodestreamBox() self.jp2c = ContiguousCodestreamBox()
@ -425,10 +448,11 @@ class TestColourSpecificationBox(unittest.TestCase):
@unittest.skipIf(os.name == "nt", @unittest.skipIf(os.name == "nt",
"Problems using NamedTemporaryFile on windows.") "Problems using NamedTemporaryFile on windows.")
def test_color_specification_box_with_out_enumerated_colorspace(self): def test_colr_with_out_enum_cspace(self):
"""must supply an enumerated colorspace when writing"""
j2k = Jp2k(self.j2kfile) j2k = Jp2k(self.j2kfile)
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c]
boxes[2].box = [self.ihdr, ColourSpecificationBox(colorspace=None)] boxes[2].box = [self.ihdr, ColourSpecificationBox(colorspace=None)]
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
@ -436,47 +460,52 @@ class TestColourSpecificationBox(unittest.TestCase):
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.") @unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
def test_missing_colr_box(self): def test_missing_colr_box(self):
"""jp2h must have a colr box"""
j2k = Jp2k(self.j2kfile) j2k = Jp2k(self.j2kfile)
boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c]
boxes[2].box = [self.ihdr] boxes[2].box = [self.ihdr]
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
with self.assertRaises(IOError): with self.assertRaises(IOError):
j2k.wrap(tfile.name, boxes=boxes) j2k.wrap(tfile.name, boxes=boxes)
def test_default_ColourSpecificationBox(self): def test_default_colr(self):
b = glymur.jp2box.ColourSpecificationBox(colorspace=glymur.core.SRGB) """basic colr instantiation"""
self.assertEqual(b.method, glymur.core.ENUMERATED_COLORSPACE) colr = ColourSpecificationBox(colorspace=glymur.core.SRGB)
self.assertEqual(b.precedence, 0) self.assertEqual(colr.method, glymur.core.ENUMERATED_COLORSPACE)
self.assertEqual(b.approximation, 0) self.assertEqual(colr.precedence, 0)
self.assertEqual(b.colorspace, glymur.core.SRGB) self.assertEqual(colr.approximation, 0)
self.assertIsNone(b.icc_profile) self.assertEqual(colr.colorspace, glymur.core.SRGB)
self.assertIsNone(colr.icc_profile)
def test_ColourSpecificationBox_with_colorspace_and_icc(self): def test_colr_with_cspace_and_icc(self):
# Colour specification boxes can't have both. """Colour specification boxes can't have both."""
with self.assertRaises((OSError, IOError)): with self.assertRaises((OSError, IOError)):
colorspace = glymur.core.SRGB colorspace = glymur.core.SRGB
icc_profile = b'\x01\x02\x03\x04' rawb = b'\x01\x02\x03\x04'
b = glymur.jp2box.ColourSpecificationBox(colorspace=colorspace, glymur.jp2box.ColourSpecificationBox(colorspace=colorspace,
icc_profile=icc_profile) icc_profile=rawb)
def test_ColourSpecificationBox_with_bad_method(self): def test_colr_with_bad_method(self):
"""colr must have a valid method field"""
colorspace = glymur.core.SRGB colorspace = glymur.core.SRGB
method = -1 method = -1
with self.assertRaises(IOError): with self.assertRaises(IOError):
b = glymur.jp2box.ColourSpecificationBox(colorspace=colorspace, glymur.jp2box.ColourSpecificationBox(colorspace=colorspace,
method=method) method=method)
def test_ColourSpecificationBox_with_bad_approximation(self): def test_colr_with_bad_approx(self):
"""colr must have a valid approximation field"""
colorspace = glymur.core.SRGB colorspace = glymur.core.SRGB
approx = -1 approx = -1
with self.assertRaises(IOError): with self.assertRaises(IOError):
b = glymur.jp2box.ColourSpecificationBox(colorspace=colorspace, glymur.jp2box.ColourSpecificationBox(colorspace=colorspace,
approximation=approx) approximation=approx)
@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None, @unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None,
"Missing openjp2 library.") "Missing openjp2 library.")
class TestWrap(unittest.TestCase): class TestWrap(unittest.TestCase):
"""Tests for wrap method."""
def setUp(self): def setUp(self):
self.j2kfile = glymur.data.goodstuff() self.j2kfile = glymur.data.goodstuff()
@ -486,7 +515,7 @@ class TestWrap(unittest.TestCase):
pass pass
def verify_wrapped_raw(self, jp2file): def verify_wrapped_raw(self, jp2file):
# Shared method by at least two tests. """Shared fixture"""
jp2 = Jp2k(jp2file) jp2 = Jp2k(jp2file)
self.assertEqual(len(jp2.box), 4) self.assertEqual(len(jp2.box), 4)
@ -536,6 +565,7 @@ class TestWrap(unittest.TestCase):
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.") @unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
def test_wrap(self): def test_wrap(self):
"""basic test for rewrapping a j2c file, no specified boxes"""
j2k = Jp2k(self.j2kfile) j2k = Jp2k(self.j2kfile)
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
j2k.wrap(tfile.name) j2k.wrap(tfile.name)
@ -543,6 +573,7 @@ class TestWrap(unittest.TestCase):
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.") @unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
def test_wrap_jp2(self): def test_wrap_jp2(self):
"""basic test for rewrapping a jp2 file, no specified boxes"""
j2k = Jp2k(self.jp2file) j2k = Jp2k(self.jp2file)
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
jp2 = j2k.wrap(tfile.name) jp2 = j2k.wrap(tfile.name)
@ -550,16 +581,17 @@ class TestWrap(unittest.TestCase):
self.assertEqual(boxes, ['jP ', 'ftyp', 'jp2h', 'jp2c']) self.assertEqual(boxes, ['jP ', 'ftyp', 'jp2h', 'jp2c'])
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.") @unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
def test_default_layout_but_with_specified_boxes(self): def test_default_layout_with_boxes(self):
"""basic test for rewrapping a jp2 file, boxes specified"""
j2k = Jp2k(self.j2kfile) j2k = Jp2k(self.j2kfile)
boxes = [JPEG2000SignatureBox(), boxes = [JPEG2000SignatureBox(),
FileTypeBox(), FileTypeBox(),
JP2HeaderBox(), JP2HeaderBox(),
ContiguousCodestreamBox()] ContiguousCodestreamBox()]
c = j2k.get_codestream() codestream = j2k.get_codestream()
height = c.segment[1].ysiz height = codestream.segment[1].ysiz
width = c.segment[1].xsiz width = codestream.segment[1].xsiz
num_components = len(c.segment[1].xrsiz) num_components = len(codestream.segment[1].xrsiz)
boxes[2].box = [ImageHeaderBox(height=height, boxes[2].box = [ImageHeaderBox(height=height,
width=width, width=width,
num_components=num_components), num_components=num_components),
@ -569,17 +601,17 @@ class TestWrap(unittest.TestCase):
self.verify_wrapped_raw(tfile.name) self.verify_wrapped_raw(tfile.name)
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.") @unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
def test_image_header_box_not_first_in_jp2_header(self): def test_ihdr_not_first_in_jp2h(self):
# The specification says that ihdr must be the first box in jp2h. """The specification says that ihdr must be the first box in jp2h."""
j2k = Jp2k(self.j2kfile) j2k = Jp2k(self.j2kfile)
boxes = [JPEG2000SignatureBox(), boxes = [JPEG2000SignatureBox(),
FileTypeBox(), FileTypeBox(),
JP2HeaderBox(), JP2HeaderBox(),
ContiguousCodestreamBox()] ContiguousCodestreamBox()]
c = j2k.get_codestream() codestream = j2k.get_codestream()
height = c.segment[1].ysiz height = codestream.segment[1].ysiz
width = c.segment[1].xsiz width = codestream.segment[1].xsiz
num_components = len(c.segment[1].xrsiz) num_components = len(codestream.segment[1].xrsiz)
boxes[2].box = [ColourSpecificationBox(colorspace=glymur.core.SRGB), boxes[2].box = [ColourSpecificationBox(colorspace=glymur.core.SRGB),
ImageHeaderBox(height=height, ImageHeaderBox(height=height,
width=width, width=width,
@ -589,14 +621,15 @@ class TestWrap(unittest.TestCase):
j2k.wrap(tfile.name, boxes=boxes) j2k.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.")
def test_first_2_boxes_not_jP_and_ftyp(self): def test_first_boxes_jp_and_ftyp(self):
"""first two boxes must be jP followed by ftyp"""
j2k = Jp2k(self.j2kfile) j2k = Jp2k(self.j2kfile)
c = j2k.get_codestream() codestream = j2k.get_codestream()
height = c.segment[1].ysiz height = codestream.segment[1].ysiz
width = c.segment[1].xsiz width = codestream.segment[1].xsiz
num_components = len(c.segment[1].xrsiz) num_components = len(codestream.segment[1].xrsiz)
jP = JPEG2000SignatureBox() jp2b = JPEG2000SignatureBox()
ftyp = FileTypeBox() ftyp = FileTypeBox()
jp2h = JP2HeaderBox() jp2h = JP2HeaderBox()
jp2c = ContiguousCodestreamBox() jp2c = ContiguousCodestreamBox()
@ -604,20 +637,21 @@ class TestWrap(unittest.TestCase):
ihdr = ImageHeaderBox(height=height, width=width, ihdr = ImageHeaderBox(height=height, width=width,
num_components=num_components) num_components=num_components)
jp2h.box = [ihdr, colr] jp2h.box = [ihdr, colr]
boxes = [ftyp, jP, jp2h, jp2c] boxes = [ftyp, jp2b, jp2h, jp2c]
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
with self.assertRaises(IOError): with self.assertRaises(IOError):
j2k.wrap(tfile.name, boxes=boxes) j2k.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.")
def test_jp2h_not_preceeding_jp2c(self): def test_jp2h_not_preceeding_jp2c(self):
"""jp2h must precede jp2c"""
j2k = Jp2k(self.j2kfile) j2k = Jp2k(self.j2kfile)
c = j2k.get_codestream() codestream = j2k.get_codestream()
height = c.segment[1].ysiz height = codestream.segment[1].ysiz
width = c.segment[1].xsiz width = codestream.segment[1].xsiz
num_components = len(c.segment[1].xrsiz) num_components = len(codestream.segment[1].xrsiz)
jP = JPEG2000SignatureBox() jp2b = JPEG2000SignatureBox()
ftyp = FileTypeBox() ftyp = FileTypeBox()
jp2h = JP2HeaderBox() jp2h = JP2HeaderBox()
jp2c = ContiguousCodestreamBox() jp2c = ContiguousCodestreamBox()
@ -625,68 +659,74 @@ class TestWrap(unittest.TestCase):
ihdr = ImageHeaderBox(height=height, width=width, ihdr = ImageHeaderBox(height=height, width=width,
num_components=num_components) num_components=num_components)
jp2h.box = [ihdr, colr] jp2h.box = [ihdr, colr]
boxes = [jP, ftyp, jp2c, jp2h] boxes = [jp2b, ftyp, jp2c, jp2h]
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
with self.assertRaises(IOError): with self.assertRaises(IOError):
j2k.wrap(tfile.name, boxes=boxes) j2k.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.")
def test_missing_codestream(self): def test_missing_codestream(self):
"""Need a codestream box in order to call wrap method."""
j2k = Jp2k(self.j2kfile) j2k = Jp2k(self.j2kfile)
c = j2k.get_codestream() codestream = j2k.get_codestream()
height = c.segment[1].ysiz height = codestream.segment[1].ysiz
width = c.segment[1].xsiz width = codestream.segment[1].xsiz
num_components = len(c.segment[1].xrsiz) num_components = len(codestream.segment[1].xrsiz)
jP = JPEG2000SignatureBox() jp2k = JPEG2000SignatureBox()
ftyp = FileTypeBox() ftyp = FileTypeBox()
jp2h = JP2HeaderBox() jp2h = JP2HeaderBox()
ihdr = ImageHeaderBox(height=height, width=width, ihdr = ImageHeaderBox(height=height, width=width,
num_components=num_components) num_components=num_components)
jp2h.box = [ihdr] jp2h.box = [ihdr]
boxes = [jP, ftyp, jp2h] boxes = [jp2k, ftyp, jp2h]
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
with self.assertRaises(IOError): with self.assertRaises(IOError):
j2k.wrap(tfile.name, boxes=boxes) j2k.wrap(tfile.name, boxes=boxes)
class TestJp2Boxes(unittest.TestCase): class TestJp2Boxes(unittest.TestCase):
"""Tests for canonical JP2 boxes."""
def test_default_JPEG2000SignatureBox(self): def test_default_jp2k(self):
# Should be able to instantiate a JPEG2000SignatureBox """Should be able to instantiate a JPEG2000SignatureBox"""
b = glymur.jp2box.JPEG2000SignatureBox() jp2k = glymur.jp2box.JPEG2000SignatureBox()
self.assertEqual(b.signature, (13, 10, 135, 10)) self.assertEqual(jp2k.signature, (13, 10, 135, 10))
def test_default_FileTypeBox(self): def test_default_ftyp(self):
# Should be able to instantiate a FileTypeBox """Should be able to instantiate a FileTypeBox"""
b = glymur.jp2box.FileTypeBox() ftyp = glymur.jp2box.FileTypeBox()
self.assertEqual(b.brand, 'jp2 ') self.assertEqual(ftyp.brand, 'jp2 ')
self.assertEqual(b.minor_version, 0) self.assertEqual(ftyp.minor_version, 0)
self.assertEqual(b.compatibility_list, ['jp2 ']) self.assertEqual(ftyp.compatibility_list, ['jp2 '])
def test_default_ImageHeaderBox(self): def test_default_ihdr(self):
# Should be able to instantiate an image header box. """Should be able to instantiate an image header box."""
b = glymur.jp2box.ImageHeaderBox(height=512, width=256, ihdr = glymur.jp2box.ImageHeaderBox(height=512, width=256,
num_components=3) num_components=3)
self.assertEqual(b.height, 512) self.assertEqual(ihdr.height, 512)
self.assertEqual(b.width, 256) self.assertEqual(ihdr.width, 256)
self.assertEqual(b.num_components, 3) self.assertEqual(ihdr.num_components, 3)
self.assertEqual(b.bits_per_component, 8) self.assertEqual(ihdr.bits_per_component, 8)
self.assertFalse(b.signed) self.assertFalse(ihdr.signed)
self.assertFalse(b.colorspace_unknown) self.assertFalse(ihdr.colorspace_unknown)
def test_default_JP2HeaderBox(self): def test_default_jp2headerbox(self):
b1 = JP2HeaderBox() """Should be able to set jp2h boxes."""
b1.box = [ImageHeaderBox(height=512, width=256), box = JP2HeaderBox()
box.box = [ImageHeaderBox(height=512, width=256),
ColourSpecificationBox(colorspace=glymur.core.GREYSCALE)] ColourSpecificationBox(colorspace=glymur.core.GREYSCALE)]
self.assertTrue(True)
def test_default_ContiguousCodestreamBox(self): def test_default_ccodestreambox(self):
b = ContiguousCodestreamBox() """Raw instantiation should not produce a main_header."""
self.assertEqual(b.box_id, 'jp2c') box = ContiguousCodestreamBox()
self.assertIsNone(b.main_header) self.assertEqual(box.box_id, 'jp2c')
self.assertIsNone(box.main_header)
class TestJpxBoxes(unittest.TestCase): class TestJpxBoxes(unittest.TestCase):
"""Tests for JPX boxes."""
def setUp(self): def setUp(self):
pass pass
@ -694,11 +734,11 @@ class TestJpxBoxes(unittest.TestCase):
def tearDown(self): def tearDown(self):
pass pass
@unittest.skipIf(format_corpus_data_root is None, @unittest.skipIf(FORMAT_CORPUS_DATA_ROOT is None,
"FORMAT_CORPUS_DATA_ROOT environment variable not set") "FORMAT_CORPUS_DATA_ROOT environment variable not set")
def test_codestream_header(self): def test_codestream_header(self):
# Should recognize codestream header box. """Should recognize codestream header box."""
jfile = os.path.join(format_corpus_data_root, jfile = os.path.join(FORMAT_CORPUS_DATA_ROOT,
'jp2k-formats/balloon.jpf') 'jp2k-formats/balloon.jpf')
jpx = Jp2k(jfile) jpx = Jp2k(jfile)
@ -706,11 +746,11 @@ class TestJpxBoxes(unittest.TestCase):
self.assertEqual(jpx.box[4].box_id, 'jpch') self.assertEqual(jpx.box[4].box_id, 'jpch')
self.assertEqual(len(jpx.box[4].box), 0) self.assertEqual(len(jpx.box[4].box), 0)
@unittest.skipIf(format_corpus_data_root is None, @unittest.skipIf(FORMAT_CORPUS_DATA_ROOT is None,
"FORMAT_CORPUS_DATA_ROOT environment variable not set") "FORMAT_CORPUS_DATA_ROOT environment variable not set")
def test_compositing_layer_header(self): def test_compositing_layer_header(self):
# Should recognize compositing layer header box. """Should recognize compositing layer header box."""
jfile = os.path.join(format_corpus_data_root, jfile = os.path.join(FORMAT_CORPUS_DATA_ROOT,
'jp2k-formats/balloon.jpf') 'jp2k-formats/balloon.jpf')
jpx = Jp2k(jfile) jpx = Jp2k(jfile)