Merge branch 'devel' of github.com:quintusdias/glymur into devel
This commit is contained in:
commit
96f32395eb
11 changed files with 167 additions and 250 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
*.pyc
|
||||
|
|
@ -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
|
||||
|
|
|
|||
150
glymur/jp2k.py
150
glymur/jp2k.py
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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():
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue