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

This commit is contained in:
John Evans 2014-03-11 15:47:23 -04:00
commit 96f32395eb
11 changed files with 167 additions and 250 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*.pyc

View file

@ -13,7 +13,7 @@ both read and write JPEG 2000 files, but you may wish to install version 2.0
or the 2.0+ version from OpenJPEG's development trunk for better performance.
If you do that, you should compile it as a shared library (named *openjp2*
instead of *openjpeg*) from the developmental source that you can retrieve
via subversion. As of this time of writing, svn revision r2369 works.
via subversion. As of this time of writing, svn revision r2651 works.
You should also download the test data for the purpose of configuring
and running OpenJPEG's test suite, check their instructions for all this.
You should set the **OPJ_DATA_ROOT** environment variable for the purpose

View file

@ -39,16 +39,6 @@ from .lib import openjp2 as opj2
from . import version
from .lib import c as libc
# Codestream lengths for 24fps, 48fps
CINEMA_24_CS = 1302083
CINEMA_48_CS = 651041
# Maximum size per color components for 2K and 4K at 24 fps
COMP_24_CS = 1041666
# Maximum size per color components for 2K at 48 fps
COMP_48_CS = 520833
JP2_IDS = ['colr', 'cdef', 'cmap', 'jp2c', 'ftyp', 'ihdr', 'jp2h', 'jP ',
'pclr', 'res ', 'resc', 'resd', 'xml ', 'ulst', 'uinf', 'url ',
'uuid']
@ -176,6 +166,11 @@ class Jp2k(Jp2kBox):
fps : int
Frames per second, should be either 24 or 48.
"""
if version.openjpeg_version_tuple[0] == 1:
msg = "Writing Cinema2K or Cinema4K files is not supported with "
msg += 'openjpeg library versions less than 2.0.1.'
raise IOError(msg)
if cinema_mode == 'cinema2k':
if fps == 24:
cparams.cp_cinema = CINEMA_MODE['cinema2k_24']
@ -183,90 +178,10 @@ class Jp2k(Jp2kBox):
cparams.cp_cinema = CINEMA_MODE['cinema2k_48']
else:
raise IOError('Cinema2K frame rate must be either 24 or 48.')
cparams.cp_rsiz = RSIZ['CINEMA2K']
else:
cparams.cp_cinema = CINEMA_MODE['cinema4k_24']
cparams.cp_rsiz = RSIZ['CINEMA4K']
# No tiling
cparams.tile_size_on = opj2.FALSE
cparams.cp_tdx = 1
cparams.cp_tdy = 1
# One tile part for each component.
cparams.tp_flag = ord('C')
cparams.tp_on = 1
# tile and image shall be as (0,0)
cparams.cp_tx0 = 0
cparams.cp_ty0 = 0
cparams.image_offset_x0 = 0
cparams.image_offset_y0 = 0
# Codeblock size = 32 * 32
cparams.cblockw_init = 32
cparams.cblockh_init = 32
# code block style, no mode switch enabled.
cparams.mode = 0
# no ROI
cparams.roi_compno = -1
# no subsampling
cparams.subsampling_dx = 1
cparams.subsampling_dy = 1
# 9-7 transform
cparams.irreversible = 1
# number of layers
if cparams.tcp_numlayers > 1:
# TODO: warning or error
cparams.tcp_numlayers = 1
if cinema_mode == 'cinema2k':
if cparams.numresolution > 6:
# TODO: warning or error
cparams.numresolution = 6
else:
if cparams.numresolution < 2:
# TODO: warning or error
cparams.numresolution = 1
elif cparams.numresolution > 7:
cparams.numresolution = 7
# precincts
cparams.csty |= 0x01
cparams.res_spec = cparams.numresolution - 1
for j in range(cparams.res_spec):
cparams.prcw_init[j] = 256
cparams.prch_init[j] = 256
# Progression order shall be CPRL
cparams.prog_order = PROGRESSION_ORDER['CPRL']
# progression order changes not allowed for 2K
if cinema_mode == 'cinema2k':
cparams.numpocs = 0
else:
cparams.poc[0].tile = 1
cparams.poc[0].resno0 = 0
cparams.poc[0].compno0 = 0
cparams.poc[0].layno1 = 1
cparams.poc[0].resno1 = cparams.numresolution - 1
cparams.poc[0].compno1 = 3
cparams.poc[0].prg1 = PROGRESSION_ORDER['CPRL']
cparams.poc[1].tile = 1
cparams.poc[1].resno0 = 0
cparams.poc[1].compno0 = 0
cparams.poc[1].layno1 = 1
cparams.poc[1].resno1 = cparams.numresolution
cparams.poc[1].compno1 = 3
cparams.poc[1].prg1 = PROGRESSION_ORDER['CPRL']
cparams.numpocs = 2
return
def _populate_cparams(self, **kwargs):
"""Populate compression parameters structure from input arguments.
@ -421,6 +336,10 @@ class Jp2k(Jp2kBox):
colorspace : int
Either CLRSPC_SRGB or CLRSPC_GRAY
"""
if (('cinema2k' in kwargs or 'cinema4k' in kwargs) and
(len(set(kwargs)) > 1)):
msg = "Cannot specify cinema2k/cinema4k along with other options."
raise IOError(msg)
if 'cratios' in kwargs and 'psnr' in kwargs:
msg = "Cannot specify cratios and psnr together."
@ -465,6 +384,8 @@ class Jp2k(Jp2kBox):
Code block size (DY, DX).
cinema2k : int, optional
frames per second, either 24 or 48
cinema4k : bool, optional
Set to True to specify Cinema4K mode, defaults to false.
colorspace : str, optional
Either 'rgb' or 'gray'.
cratios : iterable
@ -596,48 +517,6 @@ class Jp2k(Jp2kBox):
self.parse()
def _set_cinema_rate(self, cparams, image):
max_rate = 0
temp_rate = 0
cparams.cp_disto_alloc = 1
num_pixels = image.contents.comps[0].w * image.contents.comps[0].h
num_samples = num_pixels * image.contents.numcomps
rate_numerator = num_samples * image.contents.comps[0].prec
rate_denominator = 8 * image.contents.comps[0].dx
rate_denominator *= image.contents.comps[0].dy
if cparams.cp_cinema in [CINEMA_MODE['cinema2k_24'],
CINEMA_MODE['cinema4k_24']]:
max_rate = rate_numerator / (rate_denominator * CINEMA_24_CS)
if cparams.tcp_rates[0] == 0:
cparams.tcp_rates[0] = max_rate
else:
temp_rate = rate_numerator / (cparams.tcp_rates[0] * 8 * num_pixels)
if temp_rate > CINEMA_24_CS:
# TODO warning, reset
cparams.tcp_rates[0] = max_rate
else:
# TODO warning
pass
cparams.max_comp_size = COMP_24_CS
else:
max_rate = rate_numerator / (rate_denominator * CINEMA_48_CS)
if cparams.tcp_rates[0] == 0:
cparams.tcp_rates[0] = max_rate
else:
temp_rate = rate_numerator / (cparams.tcp_rates[0] * 8 * num_pixels)
if temp_rate > CINEMA_48_CS:
# TODO warning, reset
cparams.tcp_rates[0] = max_rate
else:
# TODO warning
pass
cparams.max_comp_size = COMP_48_CS
def _write_openjp2(self, img_array, verbose=False, **kwargs):
"""
Write JPEG 2000 file using OpenJPEG 2.0 interface.
@ -657,11 +536,6 @@ class Jp2k(Jp2kBox):
_populate_image_struct(cparams, image, img_array)
if 'cinema2k' in kwargs:
self._set_cinema_rate(cparams, image)
if 'cinema4k' in kwargs:
self._set_cinema_rate(cparams, image)
codec = opj2.create_compress(cparams.codec_fmt)
stack.callback(opj2.destroy_codec, codec)

View file

@ -35,6 +35,7 @@ CLRSPC_UNSPECIFIED = 0
CLRSPC_SRGB = 1
CLRSPC_GRAY = 2
CLRSPC_YCC = 3
CLRSPC_EYCC = 4
COLOR_SPACE_TYPE = ctypes.c_int
# supported codec
@ -390,7 +391,11 @@ class ImageCompType(ctypes.Structure):
("factor", ctypes.c_uint32),
# image component data
("data", ctypes.POINTER(ctypes.c_int32))]
("data", ctypes.POINTER(ctypes.c_int32)),
# alpha channel
# TODO: exclude for 2.0, 1.5
("alpha", ctypes.POINTER(ctypes.c_uint16))]
class ImageType(ctypes.Structure):

View file

@ -554,15 +554,21 @@ UUID Box (uuid) @ (77, 3146)
UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
Contiguous Codestream Box (jp2c) @ (3223, 1132296)"""
# Output of reader requirement printing for file7.jp2
file7_rreq = r"""Reader Requirements Box (rreq) @ (44, 24)
Fully Understands Aspect Mask: 0xa0
Display Completely Mask: 0xc0
# Output of reader requirements printing for text_GBR.jp2
text_GBR_rreq = r"""Reader Requirements Box (rreq) @ (40, 109)
Fully Understands Aspect Mask: 0xffff
Display Completely Mask: 0xf8f0
Standard Features and Masks:
Feature 005: 0x80 Unrestricted JPEG 2000 Part 1 codestream, ITU-T Rec. T.800 | ISO/IEC 15444-1
Feature 060: 0x60 e-sRGB enumerated colorspace
Feature 043: 0x40 Deprecated - compositing layer uses restricted ICC profile
Vendor Features:"""
Feature 001: 0x8000 Deprecated - contains no extensions
Feature 005: 0x4080 Unrestricted JPEG 2000 Part 1 codestream, ITU-T Rec. T.800 | ISO/IEC 15444-1
Feature 012: 0x2040 Deprecated - codestream is contiguous
Feature 018: 0x1020 Deprecated - support for compositing is not required
Feature 044: 0x810 Compositing layer uses Any ICC profile
Vendor Features:
UUID 3a0d0218-0ae9-4115-b376-4bca41ce0e71
UUID 47c92ccc-d1a1-4581-b904-38bb5467713b
UUID bc45a774-dd50-4ec6-a9f6-f3a137f47e90
UUID d7c8c5ef-951f-43b2-8757-042500f538e8"""
file1_xml = """XML Box (xml ) @ (36, 439)
<IMAGE_CREATION xmlns="http://www.jpeg.org/jpx/1.0/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.jpeg.org/jpx/1.0/xml http://www.jpeg.org/metadata/15444-2.xsd">

View file

@ -31,7 +31,7 @@ class TestICC(unittest.TestCase):
"""basic ICC profile"""
filename = opj_data_file('input/conformance/file5.jp2')
j = Jp2k(filename)
profile = j.box[3].box[1].icc_profile
profile = j.box[2].box[1].icc_profile
self.assertEqual(profile['Size'], 546)
self.assertEqual(profile['Preferred CMM Type'], 0)
self.assertEqual(profile['Version'], '2.2.0')

View file

@ -35,6 +35,7 @@ if HAS_PYTHON_XMP_TOOLKIT:
from libxmp import XMPMeta
from .fixtures import OPJ_DATA_ROOT, opj_data_file
from . import fixtures
# Doc tests should be run as well.
@ -376,6 +377,10 @@ class TestJp2k(unittest.TestCase):
creator_tool = xmp.get_property(libxmp.consts.XMP_NS_XMP, 'CreatorTool')
self.assertEqual(creator_tool, 'Google')
@unittest.skipIf(fixtures.OPENJP2_IS_V2_OFFICIAL,
"Feature not supported in 2.0.0 official")
@unittest.skipIf(glymur.version.openjpeg_version_tuple[0] == 1,
"Feature not supported in 1.5")
def test_jpx_mult_codestreams_jp2_brand(self):
"""Read JPX codestream when jp2-compatible."""
# The file in question has multiple codestreams.

View file

@ -3297,7 +3297,7 @@ class TestSuiteDump(unittest.TestCase):
def test_NR_file5_dump(self):
# Three 8-bit components in the ROMM-RGB colourspace, encapsulated in a
# JP2 compatible JPX file. The components have been transformed using
# JPX file. The components have been transformed using
# the RCT. The colourspace is specified using both a Restricted ICC
# profile and using the JPX-defined enumerated code for the ROMM-RGB
# colourspace.
@ -3305,49 +3305,37 @@ class TestSuiteDump(unittest.TestCase):
jp2 = Jp2k(jfile)
ids = [box.box_id for box in jp2.box]
self.assertEqual(ids, ['jP ', 'ftyp', 'rreq', 'jp2h', 'jp2c'])
self.assertEqual(ids, ['jP ', 'ftyp', 'jp2h', 'jp2c'])
ids = [box.box_id for box in jp2.box[3].box]
self.assertEqual(ids, ['ihdr', 'colr', 'colr'])
ids = [box.box_id for box in jp2.box[2].box]
self.assertEqual(ids, ['ihdr', 'colr'])
# Signature box. Check for corruption.
self.assertEqual(jp2.box[0].signature, (13, 10, 135, 10))
# File type box.
self.assertEqual(jp2.box[1].brand, 'jpx ')
self.assertEqual(jp2.box[1].brand, 'jp2 ')
self.assertEqual(jp2.box[1].minor_version, 0)
self.assertEqual(jp2.box[1].compatibility_list[1], 'jp2 ')
self.assertEqual(jp2.box[1].compatibility_list[2], 'jpx ')
self.assertEqual(jp2.box[1].compatibility_list[3], 'jpxb')
# Jp2 Header
# Image header
self.assertEqual(jp2.box[3].box[0].height, 512)
self.assertEqual(jp2.box[3].box[0].width, 768)
self.assertEqual(jp2.box[3].box[0].num_components, 3)
self.assertEqual(jp2.box[3].box[0].signed, False)
self.assertEqual(jp2.box[3].box[0].compression, 7) # wavelet
self.assertEqual(jp2.box[3].box[0].colorspace_unknown, False)
self.assertEqual(jp2.box[3].box[0].ip_provided, False)
self.assertEqual(jp2.box[2].box[0].height, 512)
self.assertEqual(jp2.box[2].box[0].width, 768)
self.assertEqual(jp2.box[2].box[0].num_components, 3)
self.assertEqual(jp2.box[2].box[0].signed, False)
self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet
self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False)
self.assertEqual(jp2.box[2].box[0].ip_provided, False)
# Jp2 Header
# Colour specification
self.assertEqual(jp2.box[3].box[1].method,
self.assertEqual(jp2.box[2].box[1].method,
glymur.core.RESTRICTED_ICC_PROFILE) # enumerated
self.assertEqual(jp2.box[3].box[1].precedence, 0)
self.assertEqual(jp2.box[3].box[1].approximation, 1) # JPX exact
self.assertEqual(jp2.box[3].box[1].icc_profile['Size'], 546)
self.assertIsNone(jp2.box[3].box[1].colorspace)
# Jp2 Header
# Colour specification
self.assertEqual(jp2.box[3].box[2].method,
glymur.core.ENUMERATED_COLORSPACE)
self.assertEqual(jp2.box[3].box[2].precedence, 1)
self.assertEqual(jp2.box[3].box[2].approximation, 1) # JPX exact
self.assertIsNone(jp2.box[3].box[2].icc_profile)
self.assertEqual(jp2.box[3].box[2].colorspace,
glymur.core.ROMM_RGB)
self.assertEqual(jp2.box[2].box[1].precedence, 0)
self.assertEqual(jp2.box[2].box[1].approximation, 1) # JPX exact
self.assertEqual(jp2.box[2].box[1].icc_profile['Size'], 546)
self.assertIsNone(jp2.box[2].box[1].colorspace)
def test_NR_file6_dump(self):
jfile = opj_data_file('input/conformance/file6.jp2')
@ -3398,54 +3386,37 @@ class TestSuiteDump(unittest.TestCase):
jp2 = Jp2k(jfile)
ids = [box.box_id for box in jp2.box]
self.assertEqual(ids, ['jP ', 'ftyp', 'rreq', 'jp2h', 'jp2c'])
self.assertEqual(ids, ['jP ', 'ftyp', 'jp2h', 'jp2c'])
ids = [box.box_id for box in jp2.box[3].box]
self.assertEqual(ids, ['ihdr', 'colr', 'colr'])
ids = [box.box_id for box in jp2.box[2].box]
self.assertEqual(ids, ['ihdr', 'colr'])
# Signature box. Check for corruption.
self.assertEqual(jp2.box[0].signature, (13, 10, 135, 10))
# File type box.
self.assertEqual(jp2.box[1].brand, 'jpx ')
self.assertEqual(jp2.box[1].brand, 'jp2 ')
self.assertEqual(jp2.box[1].compatibility_list[1], 'jp2 ')
self.assertEqual(jp2.box[1].compatibility_list[2], 'jpx ')
self.assertEqual(jp2.box[1].compatibility_list[3], 'jpxb')
self.assertEqual(jp2.box[1].minor_version, 0)
# Reader requirements talk.
# e-SRGB enumerated colourspace
self.assertTrue(60 in jp2.box[2].standard_flag)
# Jp2 Header
# Image header
self.assertEqual(jp2.box[3].box[0].height, 640)
self.assertEqual(jp2.box[3].box[0].width, 480)
self.assertEqual(jp2.box[3].box[0].num_components, 3)
self.assertEqual(jp2.box[3].box[0].bits_per_component, 16)
self.assertEqual(jp2.box[3].box[0].signed, False)
self.assertEqual(jp2.box[3].box[0].compression, 7) # wavelet
self.assertEqual(jp2.box[3].box[0].colorspace_unknown, False)
self.assertEqual(jp2.box[3].box[0].ip_provided, False)
self.assertEqual(jp2.box[2].box[0].height, 640)
self.assertEqual(jp2.box[2].box[0].width, 480)
self.assertEqual(jp2.box[2].box[0].num_components, 3)
self.assertEqual(jp2.box[2].box[0].bits_per_component, 16)
self.assertEqual(jp2.box[2].box[0].signed, False)
self.assertEqual(jp2.box[2].box[0].compression, 7) # wavelet
self.assertEqual(jp2.box[2].box[0].colorspace_unknown, False)
self.assertEqual(jp2.box[2].box[0].ip_provided, False)
# Jp2 Header
# Colour specification
self.assertEqual(jp2.box[3].box[1].method,
self.assertEqual(jp2.box[2].box[1].method,
glymur.core.RESTRICTED_ICC_PROFILE)
self.assertEqual(jp2.box[3].box[1].precedence, 0)
self.assertEqual(jp2.box[3].box[1].approximation, 1) # JPX exact
self.assertEqual(jp2.box[3].box[1].icc_profile['Size'], 13332)
self.assertIsNone(jp2.box[3].box[1].colorspace)
# Jp2 Header
# Colour specification
self.assertEqual(jp2.box[3].box[2].method,
glymur.core.ENUMERATED_COLORSPACE)
self.assertEqual(jp2.box[3].box[2].precedence, 1)
self.assertEqual(jp2.box[3].box[2].approximation, 1) # JPX exact
self.assertIsNone(jp2.box[3].box[2].icc_profile)
self.assertEqual(jp2.box[3].box[2].colorspace,
glymur.core.E_SRGB)
self.assertEqual(jp2.box[2].box[1].precedence, 0)
self.assertEqual(jp2.box[2].box[1].approximation, 1)
self.assertEqual(jp2.box[2].box[1].icc_profile['Size'], 13332)
self.assertIsNone(jp2.box[2].box[1].colorspace)
def test_NR_file8_dump(self):
# One 8-bit component in a gamma 1.8 space. The colourspace is
@ -6647,6 +6618,7 @@ class TestSuite2point1(unittest.TestCase):
Jp2k(jfile).read()
self.assertTrue(True)
@unittest.skip("Failing as of r2436")
def test_NR_DEC_mem_b2ace68c_1381_jp2_34_decode(self):
jfile = opj_data_file('input/nonregression/mem-b2ace68c-1381.jp2')
with warnings.catch_warnings():

View file

@ -23,6 +23,31 @@ 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):
"""Feature set not supported for versions less than 2.0"""
def setUp(self):
self.jp2file = glymur.data.nemo()
self.j2kfile = glymur.data.goodstuff()
def tearDown(self):
pass
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
def test_cinema_mode(self):
"""Cinema mode not supported for less than 2.0.1."""
infile = opj_data_file('input/nonregression/Bretagne1.ppm')
data = read_image(infile)
with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile:
j = Jp2k(tfile.name, 'wb')
with self.assertRaises(IOError):
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,

View file

@ -21,22 +21,25 @@ except ((ImportError, RuntimeError)):
from .fixtures import read_image, NO_READ_BACKEND, NO_READ_BACKEND_MSG
from .fixtures import OPJ_DATA_ROOT, opj_data_file
from . import fixtures
from glymur import Jp2k
import glymur
@unittest.skipIf(not _HAS_SKIMAGE_FREEIMAGE_SUPPORT,
"Cannot read input image without scikit-image/freeimage")
@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(fixtures.OPENJP2_IS_V2_OFFICIAL,
"Feature not supported in 2.0.0 official")
@unittest.skipIf(glymur.version.openjpeg_version_tuple[0] == 1,
"Feature not supported in 1.5")
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
class TestSuiteWrite(unittest.TestCase):
class TestSuiteWriteCinema(unittest.TestCase):
"""Tests for writing with openjp2 backend.
These tests roughly correspond with those tests with similar names in the
OpenJPEG test suite.
These tests either roughly correspond with those tests with similar names
in the OpenJPEG test suite or are closely associated.
"""
def setUp(self):
pass
@ -44,6 +47,26 @@ class TestSuiteWrite(unittest.TestCase):
def tearDown(self):
pass
def test_cinema2K_with_others(self):
"""Can't specify cinema2k with any other options."""
relfile = 'input/nonregression/X_5_2K_24_235_CBR_STEM24_000.tif'
infile = opj_data_file(relfile)
data = skimage.io.imread(infile)
with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile:
j = Jp2k(tfile.name, 'wb')
with self.assertRaises(IOError):
j.write(data, cinema2k=48, cratios=[200, 100, 50])
def test_cinema4K_with_others(self):
"""Can't specify cinema4k with any other options."""
relfile = 'input/nonregression/ElephantDream_4K.tif'
infile = opj_data_file(relfile)
data = skimage.io.imread(infile)
with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile:
j = Jp2k(tfile.name, 'wb')
with self.assertRaises(IOError):
j.write(data, cinema4k=True, cratios=[200, 100, 50])
def check_cinema4k_codestream(self, codestream, image_size):
"""Common out for cinema2k tests."""
# SIZ: Image and tile size
@ -128,8 +151,6 @@ class TestSuiteWrite(unittest.TestCase):
@unittest.skipIf(not _HAS_SKIMAGE_FREEIMAGE_SUPPORT,
"Cannot read input image without scikit-image/freeimage")
def test_NR_ENC_ElephantDream_4K_tif_21_encode(self):
relfile = 'input/nonregression/ElephantDream_4K.tif'
infile = opj_data_file(relfile)
@ -142,8 +163,6 @@ class TestSuiteWrite(unittest.TestCase):
self.check_cinema4k_codestream(codestream, (4096, 2160))
@unittest.skipIf(not _HAS_SKIMAGE_FREEIMAGE_SUPPORT,
"Cannot read input image without scikit-image/freeimage")
def test_NR_ENC_X_5_2K_24_235_CBR_STEM24_000_tif_19_encode(self):
relfile = 'input/nonregression/X_5_2K_24_235_CBR_STEM24_000.tif'
infile = opj_data_file(relfile)
@ -156,8 +175,6 @@ class TestSuiteWrite(unittest.TestCase):
self.check_cinema2k_codestream(codestream, (2048, 857))
@unittest.skipIf(not _HAS_SKIMAGE_FREEIMAGE_SUPPORT,
"Cannot read input image without scikit-image/freeimage")
def test_NR_ENC_X_6_2K_24_FULL_CBR_CIRCLE_000_tif_20_encode(self):
relfile = 'input/nonregression/X_6_2K_24_FULL_CBR_CIRCLE_000.tif'
infile = opj_data_file(relfile)
@ -170,8 +187,6 @@ class TestSuiteWrite(unittest.TestCase):
self.check_cinema2k_codestream(codestream, (2048, 1080))
@unittest.skipIf(not _HAS_SKIMAGE_FREEIMAGE_SUPPORT,
"Cannot read input image without scikit-image/freeimage")
def test_NR_ENC_X_6_2K_24_FULL_CBR_CIRCLE_000_tif_17_encode(self):
relfile = 'input/nonregression/X_6_2K_24_FULL_CBR_CIRCLE_000.tif'
infile = opj_data_file(relfile)
@ -184,8 +199,6 @@ class TestSuiteWrite(unittest.TestCase):
self.check_cinema2k_codestream(codestream, (2048, 1080))
@unittest.skipIf(not _HAS_SKIMAGE_FREEIMAGE_SUPPORT,
"Cannot read input image without scikit-image/freeimage")
def test_NR_ENC_X_5_2K_24_235_CBR_STEM24_000_tif_16_encode(self):
relfile = 'input/nonregression/X_5_2K_24_235_CBR_STEM24_000.tif'
infile = opj_data_file(relfile)
@ -198,8 +211,6 @@ class TestSuiteWrite(unittest.TestCase):
self.check_cinema2k_codestream(codestream, (2048, 857))
@unittest.skipIf(not _HAS_SKIMAGE_FREEIMAGE_SUPPORT,
"Cannot read input image without scikit-image/freeimage")
def test_NR_ENC_X_4_2K_24_185_CBR_WB_000_tif_18_encode(self):
relfile = 'input/nonregression/X_4_2K_24_185_CBR_WB_000.tif'
infile = opj_data_file(relfile)
@ -212,32 +223,50 @@ class TestSuiteWrite(unittest.TestCase):
self.check_cinema2k_codestream(codestream, (1998, 1080))
@unittest.skipIf(not _HAS_SKIMAGE_FREEIMAGE_SUPPORT,
"Cannot read input image without scikit-image/freeimage")
def test_NR_ENC_X_4_2K_24_185_CBR_WB_000_tif_15_encode(self):
relfile = 'input/nonregression/X_4_2K_24_185_CBR_WB_000.tif'
infile = opj_data_file(relfile)
data = skimage.io.imread(infile)
with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile:
j = Jp2k(tfile.name, 'wb')
j.write(data, cinema2k=24)
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
@unittest.skipIf(re.match(r"""2\.0""", glymur.version.openjpeg_version),
"Functionality implemented for 2.1")
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_OPJ_DATA_ROOT environment variable not set")
class TestSuiteNegative2pointzero(unittest.TestCase):
"""Feature set not supported for versions less than 2.0"""
codestream = j.get_codestream()
self.check_cinema2k_codestream(codestream, (1998, 1080))
def setUp(self):
self.jp2file = glymur.data.nemo()
self.j2kfile = glymur.data.goodstuff()
def tearDown(self):
pass
@unittest.skipIf(not _HAS_SKIMAGE_FREEIMAGE_SUPPORT,
"Cannot read input image without scikit-image/freeimage")
def test_cinema2k_bad_frame_rate(self):
def test_cinema_mode(self):
relfile = 'input/nonregression/X_4_2K_24_185_CBR_WB_000.tif'
infile = opj_data_file(relfile)
data = skimage.io.imread(infile)
with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile:
j = Jp2k(tfile.name, 'wb')
with self.assertRaises(IOError):
j.write(data, cinema2k=36)
j.write(data, cinema2k=48)
@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")
class TestSuiteWrite(unittest.TestCase):
"""Tests for writing with openjp2 backend.
These tests either roughly correspond with those tests with similar names
in the OpenJPEG test suite or are closely associated.
"""
def setUp(self):
pass
def tearDown(self):
pass
def test_NR_ENC_Bretagne1_ppm_1_encode(self):
"""NR-ENC-Bretagne1.ppm-1-encode"""
infile = opj_data_file('input/nonregression/Bretagne1.ppm')
@ -1052,5 +1081,6 @@ class TestSuiteWrite(unittest.TestCase):
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
self.assertEqual(len(codestream.segment[2].spcod), 9)
if __name__ == "__main__":
unittest.main()

View file

@ -735,18 +735,17 @@ class TestPrinting(unittest.TestCase):
expected = '\n'.join(lines)
self.assertEqual(actual, expected)
@unittest.skip("file7 no longer has a rreq")
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
def test_rreq(self):
"""verify printing of reader requirements box"""
filename = opj_data_file('input/conformance/file7.jp2')
filename = opj_data_file('input/nonregression/text_GBR.jp2')
j = glymur.Jp2k(filename)
with patch('sys.stdout', new=StringIO()) as fake_out:
print(j.box[2])
actual = fake_out.getvalue().strip()
self.maxDiff = None
expected = fixtures.file7_rreq
self.assertEqual(actual, expected)
self.assertEqual(actual, fixtures.text_GBR_rreq)
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")