Starting to implement cinema2k support. #139
Need to add scikit-image with freeimage backend in order to read 16-bit TIFFs.
This commit is contained in:
parent
2fbdf146b4
commit
b6a17d60f1
3 changed files with 106 additions and 19 deletions
|
|
@ -219,6 +219,63 @@ class Jp2k(Jp2kBox):
|
||||||
cparams.tcp_numlayers = 1
|
cparams.tcp_numlayers = 1
|
||||||
cparams.cp_disto_alloc = 1
|
cparams.cp_disto_alloc = 1
|
||||||
|
|
||||||
|
if 'cinema2K' in kwargs:
|
||||||
|
cparams.cp_rsiz = kwargs['cinema2K']
|
||||||
|
# No tiling
|
||||||
|
cparams.tile_size_on = opj2.FALSE
|
||||||
|
cparams.cp_tdx = 1
|
||||||
|
cparams.cp_tdy = 1
|
||||||
|
|
||||||
|
# One tile part for each component.
|
||||||
|
cparams.tp_cflag = 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_layers > 1:
|
||||||
|
# TODO: warning or error
|
||||||
|
cparams.tcp_numlayers = 1
|
||||||
|
|
||||||
|
if cparams.numresolution > 6:
|
||||||
|
# TODO: warning or error
|
||||||
|
cparams.numresolution = 6
|
||||||
|
|
||||||
|
# precincts
|
||||||
|
cparams.csty |= 0x01
|
||||||
|
cparams.res_spec = cparams.numresolution - 1
|
||||||
|
for j in range(cparams.res_spec):
|
||||||
|
cparams.prcw_init[i] = 256
|
||||||
|
cparams.prch_init[i] = 256
|
||||||
|
|
||||||
|
# Progression order shall be CPRL
|
||||||
|
cparams.prog_order = PROGRESSION_ORDER['CPRL']
|
||||||
|
|
||||||
|
# progression order changes not allowed for 2K
|
||||||
|
cparams.numpocs = 0
|
||||||
|
return cparams
|
||||||
|
|
||||||
if 'cbsize' in kwargs:
|
if 'cbsize' in kwargs:
|
||||||
cparams.cblockw_init = kwargs['cbsize'][1]
|
cparams.cblockw_init = kwargs['cbsize'][1]
|
||||||
cparams.cblockh_init = kwargs['cbsize'][0]
|
cparams.cblockh_init = kwargs['cbsize'][0]
|
||||||
|
|
@ -340,6 +397,8 @@ class Jp2k(Jp2kBox):
|
||||||
Image data to be written to file.
|
Image data to be written to file.
|
||||||
cbsize : tuple, optional
|
cbsize : tuple, optional
|
||||||
Code block size (DY, DX).
|
Code block size (DY, DX).
|
||||||
|
cinema2K : int, optional
|
||||||
|
either 24 or 48
|
||||||
colorspace : str, optional
|
colorspace : str, optional
|
||||||
Either 'rgb' or 'gray'.
|
Either 'rgb' or 'gray'.
|
||||||
cratios : iterable
|
cratios : iterable
|
||||||
|
|
@ -473,7 +532,7 @@ class Jp2k(Jp2kBox):
|
||||||
|
|
||||||
def _write_openjp2(self, img_array, verbose=False, **kwargs):
|
def _write_openjp2(self, img_array, verbose=False, **kwargs):
|
||||||
"""
|
"""
|
||||||
Write JPEG 2000 file using OpenJPEG 1.5 interface.
|
Write JPEG 2000 file using OpenJPEG 2.0 interface.
|
||||||
"""
|
"""
|
||||||
cparams, colorspace = self._process_write_inputs(img_array, **kwargs)
|
cparams, colorspace = self._process_write_inputs(img_array, **kwargs)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import os
|
||||||
from os.path import join
|
from os.path import join
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import glymur
|
import glymur
|
||||||
|
|
@ -27,6 +28,41 @@ except KeyError:
|
||||||
OPJ_DATA_ROOT = None
|
OPJ_DATA_ROOT = None
|
||||||
|
|
||||||
|
|
||||||
|
@unittest.skipIf(sys.hexversion < 0x03020000,
|
||||||
|
"Requires features introduced in 3.2 (assertWarns)")
|
||||||
|
class TestSuiteConformance(unittest.TestCase):
|
||||||
|
"""Test suite for conformance."""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.j2kfile = glymur.data.goodstuff()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@unittest.skipIf(re.match(r"""1\.[0123]""",
|
||||||
|
glymur.version.openjpeg_version) is not None,
|
||||||
|
"Needs 1.3+ to catch this.")
|
||||||
|
def test_truncated_eoc(self):
|
||||||
|
"""Has one byte shaved off of EOC marker."""
|
||||||
|
with open(self.j2kfile, 'rb') as ifile:
|
||||||
|
data = ifile.read()
|
||||||
|
with tempfile.NamedTemporaryFile(suffix='.j2k') as ofile:
|
||||||
|
ofile.write(data[:-1])
|
||||||
|
ofile.flush()
|
||||||
|
|
||||||
|
j2k = Jp2k(ofile.name)
|
||||||
|
with self.assertWarns(UserWarning):
|
||||||
|
codestream = j2k.get_codestream(header_only=False)
|
||||||
|
|
||||||
|
# The last segment is truncated, so there should not be an EOC
|
||||||
|
# marker.
|
||||||
|
self.assertNotEqual(codestream.segment[-1].marker_id, 'EOC')
|
||||||
|
|
||||||
|
# The codestream is not as long as claimed.
|
||||||
|
with self.assertRaises(OSError):
|
||||||
|
j2k.read(rlevel=-1)
|
||||||
|
|
||||||
|
|
||||||
@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")
|
||||||
@unittest.skipIf(sys.hexversion < 0x03020000,
|
@unittest.skipIf(sys.hexversion < 0x03020000,
|
||||||
|
|
@ -34,24 +70,6 @@ except KeyError:
|
||||||
class TestSuiteFormatCorpus(unittest.TestCase):
|
class TestSuiteFormatCorpus(unittest.TestCase):
|
||||||
"""Test suite for files in format corpus repository."""
|
"""Test suite for files in format corpus repository."""
|
||||||
|
|
||||||
@unittest.skipIf(re.match(r"""1\.[0123]""",
|
|
||||||
glymur.version.openjpeg_version) is not None,
|
|
||||||
"Needs 1.3+ to catch this.")
|
|
||||||
def test_balloon_trunc1(self):
|
|
||||||
"""Has one byte shaved off of EOC marker."""
|
|
||||||
jfile = os.path.join(FORMAT_CORPUS_DATA_ROOT,
|
|
||||||
'jp2k-test/byteCorruption/balloon_trunc1.jp2')
|
|
||||||
j2k = Jp2k(jfile)
|
|
||||||
with self.assertWarns(UserWarning):
|
|
||||||
codestream = j2k.get_codestream(header_only=False)
|
|
||||||
|
|
||||||
# The last segment is truncated, so there should not be an EOC marker.
|
|
||||||
self.assertNotEqual(codestream.segment[-1].marker_id, 'EOC')
|
|
||||||
|
|
||||||
# The codestream is not as long as claimed.
|
|
||||||
with self.assertRaises(OSError):
|
|
||||||
j2k.read(rlevel=-1)
|
|
||||||
|
|
||||||
@unittest.skipIf(re.match(r"""1\.[01234]""",
|
@unittest.skipIf(re.match(r"""1\.[01234]""",
|
||||||
glymur.version.openjpeg_version) is not None,
|
glymur.version.openjpeg_version) is not None,
|
||||||
"Needs 1.4+ to catch this.")
|
"Needs 1.4+ to catch this.")
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,16 @@ class TestSuiteWrite(unittest.TestCase):
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@unittest.skip("Cannot read input image using PILLOW???")
|
||||||
|
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'
|
||||||
|
import pdb; pdb.set_trace()
|
||||||
|
infile = opj_data_file(relfile)
|
||||||
|
data = read_image(infile)
|
||||||
|
with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile:
|
||||||
|
j = Jp2k(tfile.name, 'wb')
|
||||||
|
j.write(data, 'cinema2K', 24)
|
||||||
|
|
||||||
def test_NR_ENC_Bretagne1_ppm_1_encode(self):
|
def test_NR_ENC_Bretagne1_ppm_1_encode(self):
|
||||||
"""NR-ENC-Bretagne1.ppm-1-encode"""
|
"""NR-ENC-Bretagne1.ppm-1-encode"""
|
||||||
infile = opj_data_file('input/nonregression/Bretagne1.ppm')
|
infile = opj_data_file('input/nonregression/Bretagne1.ppm')
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue