Finished Cinema2K upstream tests. #139

This commit is contained in:
jevans 2014-03-06 21:13:40 -05:00
commit 80326718a5
4 changed files with 127 additions and 27 deletions

View file

@ -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,

View file

@ -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

View file

@ -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

View file

@ -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,