Merge branch 'issue179' into devel

Conflicts:
	glymur/test/test_jp2k.py
	glymur/test/test_opj_suite_write.py
This commit is contained in:
John Evans 2014-03-18 11:16:59 -04:00
commit ec8c5906e8
2 changed files with 39 additions and 19 deletions

View file

@ -696,8 +696,9 @@ class Jp2k(Jp2kBox):
(first_row, first_col, last_row, last_col) (first_row, first_col, last_row, last_col)
tile : int, optional tile : int, optional
Number of tile to decode. Number of tile to decode.
no_cxform : bool ignore_pclr_cmap_cdef : bool
Whether or not to apply intended color transforms. Whether or not to ignore the pclr, cmap, or cdef boxes during any
color transformation. Defaults to False.
verbose : bool, optional verbose : bool, optional
Print informational messages produced by the OpenJPEG library. Print informational messages produced by the OpenJPEG library.
@ -752,7 +753,7 @@ class Jp2k(Jp2kBox):
msg += "the read_bands method instead." msg += "the read_bands method instead."
raise RuntimeError(msg) raise RuntimeError(msg)
def _read_openjpeg(self, rlevel=0, no_cxform=False, verbose=False): def _read_openjpeg(self, rlevel=0, ignore_pclr_cmap_cdef=False, verbose=False):
"""Read a JPEG 2000 image using libopenjpeg. """Read a JPEG 2000 image using libopenjpeg.
Parameters Parameters
@ -760,8 +761,9 @@ class Jp2k(Jp2kBox):
rlevel : int, optional rlevel : int, optional
Factor by which to rlevel output resolution. Use -1 to get the Factor by which to rlevel output resolution. Use -1 to get the
lowest resolution thumbnail. lowest resolution thumbnail.
no_cxform : bool ignore_pclr_cmap_cdef : bool
Whether or not to apply intended color transforms. Whether or not to ignore the pclr, cmap, or cdef boxes during any
color transformation. Defaults to False.
verbose : bool, optional verbose : bool, optional
Print informational messages produced by the OpenJPEG library. Print informational messages produced by the OpenJPEG library.
@ -797,7 +799,7 @@ class Jp2k(Jp2kBox):
dparameters = opj.DecompressionParametersType() dparameters = opj.DecompressionParametersType()
opj.set_default_decoder_parameters(ctypes.byref(dparameters)) opj.set_default_decoder_parameters(ctypes.byref(dparameters))
if no_cxform is True: if ignore_pclr_cmap_cdef is True:
# Return raw codestream components. # Return raw codestream components.
dparameters.flags |= 1 dparameters.flags |= 1
@ -845,7 +847,7 @@ class Jp2k(Jp2kBox):
return data return data
def _read_openjp2(self, rlevel=0, layer=0, area=None, tile=None, def _read_openjp2(self, rlevel=0, layer=0, area=None, tile=None,
verbose=False, no_cxform=False): verbose=False, ignore_pclr_cmap_cdef=False):
"""Read a JPEG 2000 image using libopenjp2. """Read a JPEG 2000 image using libopenjp2.
Parameters Parameters
@ -875,7 +877,8 @@ class Jp2k(Jp2kBox):
""" """
self._subsampling_sanity_check() self._subsampling_sanity_check()
dparam = self._populate_dparam(layer, rlevel, area, tile, no_cxform) dparam = self._populate_dparam(layer, rlevel, area, tile,
ignore_pclr_cmap_cdef)
with ExitStack() as stack: with ExitStack() as stack:
if hasattr(opj2.OPENJP2, if hasattr(opj2.OPENJP2,
@ -919,7 +922,7 @@ class Jp2k(Jp2kBox):
return img_array return img_array
def _populate_dparam(self, layer, rlevel, area, tile, no_cxform): def _populate_dparam(self, layer, rlevel, area, tile, ignore_pclr_cmap_cdef):
"""Populate decompression structure with appropriate input parameters. """Populate decompression structure with appropriate input parameters.
Parameters Parameters
@ -933,8 +936,9 @@ class Jp2k(Jp2kBox):
(first_row, first_col, last_row, last_col) (first_row, first_col, last_row, last_col)
tile : int tile : int
Number of tile to decode. Number of tile to decode.
no_cxform : bool ignore_pclr_cmap_cdef : bool
Whether or not to apply intended color transforms. Whether or not to ignore the pclr, cmap, or cdef boxes during any
color transformation. Defaults to False.
Returns Returns
------- -------
@ -972,14 +976,14 @@ class Jp2k(Jp2kBox):
dparam.tile_index = tile dparam.tile_index = tile
dparam.nb_tile_to_decode = 1 dparam.nb_tile_to_decode = 1
if no_cxform is True: if ignore_pclr_cmap_cdef is True:
# Return raw codestream components. # Return raw codestream components.
dparam.flags |= 1 dparam.flags |= 1
return dparam return dparam
def read_bands(self, rlevel=0, layer=0, area=None, tile=None, def read_bands(self, rlevel=0, layer=0, area=None, tile=None,
verbose=False, no_cxform=False): verbose=False, ignore_pclr_cmap_cdef=False):
"""Read a JPEG 2000 image. """Read a JPEG 2000 image.
The only time you should use this method is when the image has The only time you should use this method is when the image has
@ -997,8 +1001,9 @@ class Jp2k(Jp2kBox):
(first_row, first_col, last_row, last_col) (first_row, first_col, last_row, last_col)
tile : int, optional tile : int, optional
Number of tile to decode. Number of tile to decode.
no_cxform : bool ignore_pclr_cmap_cdef : bool
Whether or not to apply intended color transforms. Whether or not to ignore the pclr, cmap, or cdef boxes during any
color transformation. Defaults to False.
verbose : bool, optional verbose : bool, optional
Print informational messages produced by the OpenJPEG library. Print informational messages produced by the OpenJPEG library.
@ -1028,7 +1033,7 @@ class Jp2k(Jp2kBox):
"of OpenJP2 installed before using " "of OpenJP2 installed before using "
"this functionality.") "this functionality.")
dparam = self._populate_dparam(layer, rlevel, area, tile, no_cxform) dparam = self._populate_dparam(layer, rlevel, area, tile, ignore_pclr_cmap_cdef)
with ExitStack() as stack: with ExitStack() as stack:
if hasattr(opj2.OPENJP2, if hasattr(opj2.OPENJP2,

View file

@ -96,7 +96,7 @@ class TestJp2k(unittest.TestCase):
"""Indices for pclr jpxfile if no color transform""" """Indices for pclr jpxfile if no color transform"""
j = Jp2k(self.jpxfile) j = Jp2k(self.jpxfile)
rgb = j.read() rgb = j.read()
idx = j.read(no_cxform=True) idx = j.read(ignore_pclr_cmap_cdef=True)
self.assertEqual(rgb.shape, (1024, 1024, 3)) self.assertEqual(rgb.shape, (1024, 1024, 3))
self.assertEqual(idx.shape, (1024, 1024)) self.assertEqual(idx.shape, (1024, 1024))
@ -109,6 +109,21 @@ class TestJp2k(unittest.TestCase):
rgb_from_idx[r, c] = palette[idx[r, c]] rgb_from_idx[r, c] = palette[idx[r, c]]
np.testing.assert_array_equal(rgb, rgb_from_idx) np.testing.assert_array_equal(rgb, rgb_from_idx)
def test_no_cxform_cmap(self):
"""Bands as physically ordered, not as physically intended"""
# This file has the components physically reversed. The cmap box
# tells the decoder how to order them, but this flag prevents that.
filename = opj_data_file('input/conformance/file2.jp2')
j = Jp2k(filename)
ycbcr = j.read()
crcby = j.read(ignore_pclr_cmap_cdef=True)
expected = np.zeros(ycbcr.shape, ycbcr.dtype)
for k in range(crcby.shape[2]):
expected[:,:,crcby.shape[2] - k - 1] = crcby[:,:,k]
np.testing.assert_array_equal(ycbcr, expected)
def test_file_not_present(self): def test_file_not_present(self):
"""Should error out if reading from a file that does not exist""" """Should error out if reading from a file that does not exist"""
# Verify that we error out appropriately if not given an existing file # Verify that we error out appropriately if not given an existing file
@ -763,7 +778,7 @@ class TestJp2kOpjDataRoot(unittest.TestCase):
filename = opj_data_file('input/conformance/file9.jp2') filename = opj_data_file('input/conformance/file9.jp2')
j = Jp2k(filename) j = Jp2k(filename)
rgb = j.read() rgb = j.read()
idx = j.read(no_cxform=True) idx = j.read(ignore_pclr_cmap_cdef=True)
self.assertEqual(rgb.shape, (512, 768, 3)) self.assertEqual(rgb.shape, (512, 768, 3))
self.assertEqual(idx.shape, (512, 768)) self.assertEqual(idx.shape, (512, 768))
@ -805,7 +820,7 @@ class TestJp2kOpjDataRoot(unittest.TestCase):
filename = opj_data_file('input/conformance/file2.jp2') filename = opj_data_file('input/conformance/file2.jp2')
j = Jp2k(filename) j = Jp2k(filename)
ycbcr = j.read() ycbcr = j.read()
crcby = j.read(no_cxform=True) crcby = j.read(ignore_pclr_cmap_cdef=True)
expected = np.zeros(ycbcr.shape, ycbcr.dtype) expected = np.zeros(ycbcr.shape, ycbcr.dtype)
for k in range(crcby.shape[2]): for k in range(crcby.shape[2]):