Finished Cinema2K upstream tests. #139
This commit is contained in:
parent
3bad8a4b2e
commit
80326718a5
4 changed files with 127 additions and 27 deletions
|
|
@ -1,4 +1,5 @@
|
|||
Feb 09, 2014 - Changed constructor for ChannelDefinition box. Removed support
|
||||
Mar 06, 2014 - Added Cinema2K write support.
|
||||
Changed constructor for ChannelDefinition box. Removed support
|
||||
for Python 2.6. Added write support for JP2 UUID, DataEntryURL,
|
||||
Palette and Component Mapping boxes, JPX Association, NumberList
|
||||
and DataReference boxes. Added read support for JPX free,
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@ ChangeLog
|
|||
0.6.0 (pending)
|
||||
===============
|
||||
|
||||
* Added Cinema2K write support.
|
||||
* Added lxml requirement.
|
||||
* added set_printoptions, get_printoptions function
|
||||
* dropped support for Python 2.6, added support for Python 3.4
|
||||
* dropped windows support
|
||||
* dropped windows support (it might work, it might not, I don't much care)
|
||||
* added write support for JP2 UUID, dataEntryURL, palette, and component mapping boxes
|
||||
* added read/write support for JPX free, number list, and data reference boxes
|
||||
* Added read support for JPX fragment list and fragment table boxes
|
||||
|
|
|
|||
|
|
@ -163,9 +163,12 @@ class Jp2k(Jp2kBox):
|
|||
fps : int
|
||||
Frames per second, should be either 24 or 48.
|
||||
"""
|
||||
if fps not in [24, 48]:
|
||||
if fps == 24:
|
||||
cparams.cp_cinema = CINEMA_MODE['cinema2k_24']
|
||||
elif fps == 48:
|
||||
cparams.cp_cinema = CINEMA_MODE['cinema2k_48']
|
||||
else:
|
||||
raise IOError('Cinema2K frame rate must be either 24 or 48.')
|
||||
cparams.cp_cinema = fps
|
||||
|
||||
cparams.cp_rsiz = RSIZ['CINEMA2K']
|
||||
# No tiling
|
||||
|
|
@ -205,7 +208,7 @@ class Jp2k(Jp2kBox):
|
|||
# TODO: warning or error
|
||||
cparams.tcp_numlayers = 1
|
||||
|
||||
if cparams.numresolution > 6:
|
||||
if cparams.numresolution > 6: #TODO only for cinema2k
|
||||
# TODO: warning or error
|
||||
cparams.numresolution = 6
|
||||
|
||||
|
|
@ -219,7 +222,7 @@ class Jp2k(Jp2kBox):
|
|||
# Progression order shall be CPRL
|
||||
cparams.prog_order = PROGRESSION_ORDER['CPRL']
|
||||
|
||||
# progression order changes not allowed for 2K
|
||||
# progression order changes not allowed for 2K # TODO not for 4K:
|
||||
cparams.numpocs = 0
|
||||
|
||||
def _populate_cparams(self, **kwargs):
|
||||
|
|
@ -554,8 +557,12 @@ class Jp2k(Jp2kBox):
|
|||
if cparams.cp_cinema in [CINEMA_MODE['cinema2k_24'],
|
||||
CINEMA_MODE['cinema2k_48']]:
|
||||
num_pixels = image.contents.comps[0].w * image.contents.comps[0].h
|
||||
rate_numerator = num_pixels * image.contents.comps[0].prec
|
||||
max_rate = rate_numerator / (CINEMA_24_CS * 8 * num_pixels)
|
||||
num_samples = num_pixels * image.contents.numcomps
|
||||
rate_numerator = num_samples * image.contents.comps[0].prec
|
||||
rate_denominator = CINEMA_24_CS * 8
|
||||
rate_denominator *= image.contents.comps[0].dx
|
||||
rate_denominator *= image.contents.comps[0].dy
|
||||
max_rate = rate_numerator / rate_denominator
|
||||
if cparams.tcp_rates[0] == 0:
|
||||
cparams.tcp_rates[0] = max_rate
|
||||
else:
|
||||
|
|
@ -567,7 +574,7 @@ class Jp2k(Jp2kBox):
|
|||
# TODO warning
|
||||
pass
|
||||
|
||||
cparams.max_comp_size = COMP_24_CS
|
||||
cparams.max_comp_size = CINEMA_24_CS
|
||||
|
||||
def _write_openjp2(self, img_array, verbose=False, **kwargs):
|
||||
"""
|
||||
|
|
@ -1608,6 +1615,10 @@ def _populate_image_struct(cparams, image, imgdata):
|
|||
|
||||
# Stage the image data to the openjpeg data structure.
|
||||
for k in range(0, num_comps):
|
||||
if cparams.cp_cinema:
|
||||
image.contents.comps[k].prec = 12
|
||||
image.contents.comps[k].bpp = 12
|
||||
|
||||
layer = np.ascontiguousarray(imgdata[:, :, k], dtype=np.int32)
|
||||
dest = image.contents.comps[k].data
|
||||
src = layer.ctypes.data
|
||||
|
|
|
|||
|
|
@ -44,6 +44,108 @@ class TestSuiteWrite(unittest.TestCase):
|
|||
def tearDown(self):
|
||||
pass
|
||||
|
||||
@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)
|
||||
data = skimage.io.imread(infile)
|
||||
with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile:
|
||||
j = Jp2k(tfile.name, 'wb')
|
||||
j.write(data, cinema2k=24)
|
||||
|
||||
codestream = j.get_codestream()
|
||||
|
||||
# SIZ: Image and tile size
|
||||
# Profile: "3" means cinema2K
|
||||
self.assertEqual(codestream.segment[1].rsiz, 3)
|
||||
# Reference grid size
|
||||
self.assertEqual((codestream.segment[1].xsiz,
|
||||
codestream.segment[1].ysiz),
|
||||
(2048, 1080))
|
||||
# Reference grid offset
|
||||
self.assertEqual((codestream.segment[1].xosiz,
|
||||
codestream.segment[1].yosiz), (0, 0))
|
||||
# Tile size
|
||||
self.assertEqual((codestream.segment[1].xtsiz,
|
||||
codestream.segment[1].ytsiz),
|
||||
(2048, 1080))
|
||||
# Tile offset
|
||||
self.assertEqual((codestream.segment[1].xtosiz,
|
||||
codestream.segment[1].ytosiz),
|
||||
(0, 0))
|
||||
# bitdepth
|
||||
self.assertEqual(codestream.segment[1].bitdepth, (12, 12, 12))
|
||||
# signed
|
||||
self.assertEqual(codestream.segment[1].signed,
|
||||
(False, False, False))
|
||||
# subsampling
|
||||
self.assertEqual(list(zip(codestream.segment[1].xrsiz,
|
||||
codestream.segment[1].yrsiz)),
|
||||
[(1, 1)] * 3)
|
||||
|
||||
# COD: Coding style default
|
||||
self.assertFalse(codestream.segment[2].scod & 2) # no sop
|
||||
self.assertFalse(codestream.segment[2].scod & 4) # no eph
|
||||
self.assertEqual(codestream.segment[2].spcod[0], glymur.core.CPRL)
|
||||
self.assertEqual(codestream.segment[2].layers, 1)
|
||||
self.assertEqual(codestream.segment[2].spcod[3], 1) # mct
|
||||
self.assertEqual(codestream.segment[2].spcod[4], 5) # levels
|
||||
self.assertEqual(tuple(codestream.segment[2].code_block_size),
|
||||
(32, 32)) # cblksz
|
||||
|
||||
|
||||
@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)
|
||||
data = skimage.io.imread(infile)
|
||||
with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile:
|
||||
j = Jp2k(tfile.name, 'wb')
|
||||
j.write(data, cinema2k=24)
|
||||
|
||||
codestream = j.get_codestream()
|
||||
|
||||
# SIZ: Image and tile size
|
||||
# Profile: "3" means cinema2K
|
||||
self.assertEqual(codestream.segment[1].rsiz, 3)
|
||||
# Reference grid size
|
||||
self.assertEqual((codestream.segment[1].xsiz,
|
||||
codestream.segment[1].ysiz),
|
||||
(2048, 857))
|
||||
# Reference grid offset
|
||||
self.assertEqual((codestream.segment[1].xosiz,
|
||||
codestream.segment[1].yosiz), (0, 0))
|
||||
# Tile size
|
||||
self.assertEqual((codestream.segment[1].xtsiz,
|
||||
codestream.segment[1].ytsiz),
|
||||
(2048, 857))
|
||||
# Tile offset
|
||||
self.assertEqual((codestream.segment[1].xtosiz,
|
||||
codestream.segment[1].ytosiz),
|
||||
(0, 0))
|
||||
# bitdepth
|
||||
self.assertEqual(codestream.segment[1].bitdepth, (12, 12, 12))
|
||||
# signed
|
||||
self.assertEqual(codestream.segment[1].signed,
|
||||
(False, False, False))
|
||||
# subsampling
|
||||
self.assertEqual(list(zip(codestream.segment[1].xrsiz,
|
||||
codestream.segment[1].yrsiz)),
|
||||
[(1, 1)] * 3)
|
||||
|
||||
# COD: Coding style default
|
||||
self.assertFalse(codestream.segment[2].scod & 2) # no sop
|
||||
self.assertFalse(codestream.segment[2].scod & 4) # no eph
|
||||
self.assertEqual(codestream.segment[2].spcod[0], glymur.core.CPRL)
|
||||
self.assertEqual(codestream.segment[2].layers, 1)
|
||||
self.assertEqual(codestream.segment[2].spcod[3], 1) # mct
|
||||
self.assertEqual(codestream.segment[2].spcod[4], 5) # levels
|
||||
self.assertEqual(tuple(codestream.segment[2].code_block_size),
|
||||
(32, 32)) # cblksz
|
||||
|
||||
|
||||
@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):
|
||||
|
|
@ -87,27 +189,12 @@ class TestSuiteWrite(unittest.TestCase):
|
|||
# COD: Coding style default
|
||||
self.assertFalse(codestream.segment[2].scod & 2) # no sop
|
||||
self.assertFalse(codestream.segment[2].scod & 4) # no eph
|
||||
self.assertEqual(codestream.segment[2].spcod[0], glymur.core.CRLP)
|
||||
self.assertEqual(codestream.segment[2].layers, 3) # layers = 3
|
||||
self.assertEqual(codestream.segment[2].spcod[0], glymur.core.CPRL)
|
||||
self.assertEqual(codestream.segment[2].layers, 1)
|
||||
self.assertEqual(codestream.segment[2].spcod[3], 1) # mct
|
||||
self.assertEqual(codestream.segment[2].spcod[4], 5) # levels
|
||||
self.assertEqual(tuple(codestream.segment[2].code_block_size),
|
||||
(64, 64)) # cblksz
|
||||
# Selective arithmetic coding bypass
|
||||
self.assertFalse(codestream.segment[2].spcod[7] & 0x01)
|
||||
# Reset context probabilities
|
||||
self.assertFalse(codestream.segment[2].spcod[7] & 0x02)
|
||||
# Termination on each coding pass
|
||||
self.assertFalse(codestream.segment[2].spcod[7] & 0x04)
|
||||
# Vertically causal context
|
||||
self.assertFalse(codestream.segment[2].spcod[7] & 0x08)
|
||||
# Predictable termination
|
||||
self.assertFalse(codestream.segment[2].spcod[7] & 0x0010)
|
||||
# Segmentation symbols
|
||||
self.assertFalse(codestream.segment[2].spcod[7] & 0x0020)
|
||||
self.assertEqual(codestream.segment[2].spcod[8],
|
||||
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
|
||||
self.assertEqual(len(codestream.segment[2].spcod), 9)
|
||||
(32, 32)) # cblksz
|
||||
|
||||
|
||||
@unittest.skipIf(not _HAS_SKIMAGE_FREEIMAGE_SUPPORT,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue