Merge branch 'devel' into issue40

This commit is contained in:
jevans 2013-06-15 21:42:37 -04:00
commit 596d502f15
11 changed files with 305 additions and 47 deletions

View file

@ -1,4 +1,5 @@
Jun 11, 2013 - Added reduce=-1 option to get lowest resolution thumbnail Jun 11, 2013 - v0.1.8 Added reduce=-1 option to get lowest resolution
thumbnail.
Jun 07, 2013 - v0.1.7 Changed Exif dictionary names from ['Exif', 'Photo', Jun 07, 2013 - v0.1.7 Changed Exif dictionary names from ['Exif', 'Photo',
'Iop', 'GPSInfo'] to ['Image', 'Photo', 'Iop', 'GPSInfo']. 'Iop', 'GPSInfo'] to ['Image', 'Photo', 'Iop', 'GPSInfo'].

View file

@ -1,4 +1,3 @@
include *.txt *.md include *.txt *.md
recursive-include *.txt *.py
prune build prune build
exclude readthedocs-pip-requirements.txt exclude readthedocs-pip-requirements.txt

View file

@ -78,7 +78,7 @@ copyright = u'2013, John Evans'
# The short X.Y version. # The short X.Y version.
version = '0.1' version = '0.1'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '0.1.7' release = '0.1.8'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

View file

@ -7,7 +7,7 @@ Read the lowest resolution thumbnail?
===================================== =====================================
Printing the Jp2k object should reveal the number of resolutions (look in the Printing the Jp2k object should reveal the number of resolutions (look in the
COD segment section), but you can take a shortcut by supplying -1 as the reduce COD segment section), but you can take a shortcut by supplying -1 as the reduce
level. level. ::
>>> import pkg_resources >>> import pkg_resources
>>> import glymur >>> import glymur
@ -38,7 +38,7 @@ codestream box, only the main header is printed. It is possible to print
Work with XMP UUIDs? Work with XMP UUIDs?
==================== ====================
The example JP2 file shipped with glymur has an XMP UUID:: The example JP2 file shipped with glymur has an XMP UUID. ::
>>> import pkg_resources >>> import pkg_resources
>>> from glymur import Jp2k >>> from glymur import Jp2k

View file

@ -12,6 +12,7 @@ References
""" """
import copy import copy
import datetime
import math import math
import os import os
import pprint import pprint
@ -153,9 +154,9 @@ class ColourSpecificationBox(Jp2kBox):
colorspace : int or None colorspace : int or None
Enumerated colorspace, corresponds to one of 'sRGB', 'greyscale', or Enumerated colorspace, corresponds to one of 'sRGB', 'greyscale', or
'YCC'. If not None, then icc_profile must be None. 'YCC'. If not None, then icc_profile must be None.
icc_profile : byte array or None icc_profile : _ICCProfile or None
ICC profile according to ICC profile specification. If not None, then ICC profile header according to ICC profile specification. If not
color_space must be None. None, then color_space must be None.
""" """
def __init__(self, **kwargs): def __init__(self, **kwargs):
Jp2kBox.__init__(self, id='', longname='Colour Specification') Jp2kBox.__init__(self, id='', longname='Colour Specification')
@ -174,8 +175,7 @@ class ColourSpecificationBox(Jp2kBox):
x = _colorspace_map_display[self.colorspace] x = _colorspace_map_display[self.colorspace]
msg += '\n Colorspace: {0}'.format(x) msg += '\n Colorspace: {0}'.format(x)
else: else:
x = len(self.icc_profile) msg += '\n ICC Profile: {0}'.format(self.icc_profile.__str__())
msg += '\n ICC Profile: {0} bytes'.format(x)
return msg return msg
@ -221,12 +221,169 @@ class ColourSpecificationBox(Jp2kBox):
# ICC profile # ICC profile
kwargs['colorspace'] = None kwargs['colorspace'] = None
n = offset + length - f.tell() n = offset + length - f.tell()
kwargs['icc_profile'] = f.read(n) if n < 128:
msg = "ICC profile header is corrupt, length is "
msg += "only {0} instead of 128."
warnings.warn(msg.format(n), UserWarning)
kwargs['icc_profile'] = None
else:
icc_profile = _ICCProfile(f.read(n))
kwargs['icc_profile'] = icc_profile
box = ColourSpecificationBox(**kwargs) box = ColourSpecificationBox(**kwargs)
return box return box
class _ICCProfile:
"""
"""
profile_class = {b'scnr': 'input device profile',
b'mntr': 'display device profile',
b'prtr': 'output device profile',
b'link': 'devicelink profile',
b'spac': 'colorspace conversion profile',
b'abst': 'abstract profile',
b'nmcl': 'name colour profile'}
colour_space_dict = {b'XYZ ': 'XYZ',
b'Lab ': 'Lab',
b'Luv ': 'Luv',
b'YCbr': 'YCbCr',
b'Yxy ': 'Yxy',
b'RGB ': 'RGB',
b'GRAY': 'gray',
b'HSV ': 'hsv',
b'HLS ': 'hls',
b'CMYK': 'CMYK',
b'CMY ': 'cmy',
b'2CLR': '2colour',
b'3CLR': '3colour',
b'4CLR': '4colour',
b'5CLR': '5colour',
b'6CLR': '6colour',
b'7CLR': '7colour',
b'8CLR': '8colour',
b'9CLR': '9colour',
b'ACLR': '10colour',
b'BCLR': '11colour',
b'CCLR': '12colour',
b'DCLR': '13colour',
b'ECLR': '14colour',
b'FCLR': '15colour'}
rendering_intent_dict = {0: 'perceptual',
1: 'media-relative colorimetric',
2: 'saturation',
3: 'ICC-absolute colorimetric'}
def __init__(self, buffer):
self._raw_buffer = buffer
self.size, = struct.unpack('>I', self._raw_buffer[0:4])
self.preferred_cmm_type, = struct.unpack('>I', self._raw_buffer[4:8])
data = struct.unpack('>BB', self._raw_buffer[8:10])
major = data[0]
minor = (data[1] & 0xf0) >> 4
bugfix = (data[1] & 0x0f)
self.version = '{0}.{1}.{2}'.format(major, minor, bugfix)
self.device_class = self.profile_class[self._raw_buffer[12:16]]
self.colour_space = self.colour_space_dict[self._raw_buffer[16:20]]
self.connection_space = self.colour_space_dict[self._raw_buffer[20:24]]
data = struct.unpack('>HHHHHH', self._raw_buffer[24:36])
self.datetime = datetime.datetime(*data)
self.file_signature = buffer[36:40].decode('utf-8')
if buffer[40:44] == b'\x00\x00\x00\x00':
self.platform = 'unrecognized'
else:
self.platform = buffer[40:44].decode('utf-8')
self.flags, = struct.unpack('>I', buffer[44:48])
self.device_manufacturer = buffer[48:52].decode('utf-8')
if buffer[52:56] == b'\x00\x00\x00\x00':
self.device_model = ''
else:
self.device_model = buffer[52:56].decode('utf-8')
self.device_attributes, = struct.unpack('>Q', buffer[56:64])
self.rendering_intent, = struct.unpack('>I', buffer[64:68])
data = struct.unpack('>iii', buffer[68:80])
self.illuminant = np.array(data, dtype=np.float64) / 65536
if buffer[80:84] == b'\x00\x00\x00\x00':
self.creator = 'unrecognized'
else:
self.creator = buffer[80:84].decode('utf-8')
self.profile_id = buffer[84:100]
self.reserved = buffer[100:127]
def __str__(self):
msg = "\n Size: {0}"
msg += "\n Preferred CMM type: {1:x}"
msg += "\n Version: {2}"
msg += "\n Device class signature: {3}"
msg += "\n Color space: {4}"
msg += "\n Connection space: {5}"
msg += "\n Creation time: {6}"
msg += "\n File signature: {7}"
msg += "\n Platform: {8}"
msg += "\n Flags: {9}"
msg += "\n Device manufacturer: {10}"
msg += "\n Device model: {11}"
msg += "\n Device attributes: {12}"
msg += "\n Rendering intent: {13}"
msg += "\n Illuminant: {14}"
msg += "\n Creator signature: {15}"
if self.flags & 0x01:
flag_string = 'embedded, '
else:
flag_string = 'not embedded, '
if self.flags & 0x02:
flag_string += 'cannot be used independently'
else:
flag_string += 'can be used independently'
if self.device_attributes & 0x01:
attr_string = 'transparency, '
else:
attr_string = 'reflective, '
if self.device_attributes & 0x02:
attr_string += 'matte, '
else:
attr_string += 'glossy, '
if self.device_attributes & 0x04:
attr_string += 'negative media polarity, '
else:
attr_string += 'positive media polarity, '
if self.device_attributes & 0x08:
attr_string += 'black and white media'
else:
attr_string += 'color media'
msg = msg.format(self.size,
self.preferred_cmm_type,
self.version,
self.device_class,
self.colour_space,
self.connection_space,
self.datetime,
self.file_signature,
self.platform,
flag_string,
self.device_manufacturer,
self.device_model,
attr_string,
self.rendering_intent_dict[self.rendering_intent],
self.illuminant,
self.creator)
return(msg)
class ComponentDefinitionBox(Jp2kBox): class ComponentDefinitionBox(Jp2kBox):
"""Container for component definition box information. """Container for component definition box information.

View file

@ -138,7 +138,7 @@ class Jp2k(Jp2kBox):
f.seek(0) f.seek(0)
self.box = self._parse_superbox(f) self.box = self._parse_superbox(f)
def write(self, data, cratios=None, eph=False, psnr=None, numres=None, def write(self, img_array, cratios=None, eph=False, psnr=None, numres=None,
cbsize=None, psizes=None, grid_offset=None, sop=False, cbsize=None, psizes=None, grid_offset=None, sop=False,
subsam=None, tilesize=None, prog=None, modesw=None, subsam=None, tilesize=None, prog=None, modesw=None,
colorspace=None, verbose=False): colorspace=None, verbose=False):
@ -150,7 +150,7 @@ class Jp2k(Jp2kBox):
Parameters Parameters
---------- ----------
data : array img_array : ndarray
Image data to be written to file. Image data to be written to file.
callbacks : bool, optional callbacks : bool, optional
If true, enable default info handler such that INFO messages If true, enable default info handler such that INFO messages
@ -307,19 +307,19 @@ class Jp2k(Jp2kBox):
msg = "Cannot specify cratios and psnr together." msg = "Cannot specify cratios and psnr together."
raise RuntimeError(msg) raise RuntimeError(msg)
if data.ndim == 2: if img_array.ndim == 2:
numrows, numcols = data.shape numrows, numcols = img_array.shape
data = data.reshape(numrows, numcols, 1) img_array = img_array.reshape(numrows, numcols, 1)
elif data.ndim == 3: elif img_array.ndim == 3:
pass pass
else: else:
msg = "{0}D imagery is not allowed.".format(data.ndim) msg = "{0}D imagery is not allowed.".format(img_array.ndim)
raise IOError(msg) raise IOError(msg)
numrows, numcols, num_comps = data.shape numrows, numcols, num_comps = img_array.shape
if colorspace is None: if colorspace is None:
if data.shape[2] == 1 or data.shape[2] == 2: if img_array.shape[2] == 1 or img_array.shape[2] == 2:
colorspace = opj2._CLRSPC_GRAY colorspace = opj2._CLRSPC_GRAY
else: else:
# No YCC unless specifically told to do so. # No YCC unless specifically told to do so.
@ -331,15 +331,15 @@ class Jp2k(Jp2kBox):
if colorspace not in ('rgb', 'grey', 'gray'): if colorspace not in ('rgb', 'grey', 'gray'):
msg = 'Invalid colorspace "{0}"'.format(colorspace) msg = 'Invalid colorspace "{0}"'.format(colorspace)
raise IOError(msg) raise IOError(msg)
elif colorspace == 'rgb' and data.shape[2] < 3: elif colorspace == 'rgb' and img_array.shape[2] < 3:
msg = 'RGB colorspace requires at least 3 components.' msg = 'RGB colorspace requires at least 3 components.'
raise IOError(msg) raise IOError(msg)
else: else:
colorspace = _cspace_map[colorspace] colorspace = _cspace_map[colorspace]
if data.dtype == np.uint8: if img_array.dtype == np.uint8:
comp_prec = 8 comp_prec = 8
elif data.dtype == np.uint16: elif img_array.dtype == np.uint16:
comp_prec = 16 comp_prec = 16
else: else:
raise RuntimeError("unhandled datatype") raise RuntimeError("unhandled datatype")
@ -368,7 +368,7 @@ class Jp2k(Jp2kBox):
# Stage the image data to the openjpeg data structure. # Stage the image data to the openjpeg data structure.
for k in range(0, num_comps): for k in range(0, num_comps):
layer = np.ascontiguousarray(data[:, :, k], dtype=np.int32) layer = np.ascontiguousarray(img_array[:, :, k], dtype=np.int32)
dest = image.contents.comps[k].data dest = image.contents.comps[k].data
src = layer.ctypes.data src = layer.ctypes.data
ctypes.memmove(dest, src, layer.nbytes) ctypes.memmove(dest, src, layer.nbytes)
@ -419,7 +419,7 @@ class Jp2k(Jp2kBox):
Returns Returns
------- -------
result : array img_array : ndarray
The image data. The image data.
Raises Raises
@ -451,18 +451,18 @@ class Jp2k(Jp2kBox):
msg = "Components must all have the same subsampling factors." msg = "Components must all have the same subsampling factors."
raise IOError(msg) raise IOError(msg)
data = self._read_common(reduce=reduce, img_array = self._read_common(reduce=reduce,
layer=layer, layer=layer,
area=area, area=area,
tile=tile, tile=tile,
verbose=verbose, verbose=verbose,
as_bands=False) as_bands=False)
if data.shape[2] == 1: if img_array.shape[2] == 1:
data = data.view() img_array = img_array.view()
data.shape = data.shape[0:2] img_array.shape = img_array.shape[0:2]
return data return img_array
def _read_common(self, reduce=0, layer=0, area=None, tile=None, def _read_common(self, reduce=0, layer=0, area=None, tile=None,
verbose=False, as_bands=False): verbose=False, as_bands=False):
@ -486,7 +486,7 @@ class Jp2k(Jp2kBox):
Returns Returns
------- -------
data : list or array img_array : ndarray
The individual image components or a single array. The individual image components or a single array.
""" """
dparam = opj2._set_default_decoder_parameters() dparam = opj2._set_default_decoder_parameters()

View file

@ -1,6 +1,7 @@
from .test_callbacks import TestCallbacks as callbacks from .test_callbacks import TestCallbacks as callbacks
from .test_codestream import TestCodestream as codestream from .test_codestream import TestCodestream as codestream
from .test_jp2k import TestJp2k as jp2k from .test_jp2k import TestJp2k as jp2k
from .test_icc import TestICC as icc
from .test_printing import TestPrinting as printing from .test_printing import TestPrinting as printing
from .test_opj_suite import TestSuite as suite from .test_opj_suite import TestSuite as suite
from .test_opj_suite_write import TestSuiteWrite as suitew from .test_opj_suite_write import TestSuiteWrite as suitew

74
glymur/test/test_icc.py Normal file
View file

@ -0,0 +1,74 @@
import datetime
import os
import struct
import sys
import tempfile
import unittest
import warnings
from xml.etree import cElementTree as ET
import numpy as np
import pkg_resources
from glymur import Jp2k
import glymur
try:
data_root = os.environ['OPJ_DATA_ROOT']
except KeyError:
data_root = None
except:
raise
@unittest.skipIf(data_root is None,
"OPJ_DATA_ROOT environment variable not set")
class TestICC(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def test_file5(self):
filename = os.path.join(data_root, 'input/conformance/file5.jp2')
j = Jp2k(filename)
profile = j.box[3].box[1].icc_profile
self.assertEqual(profile.size, 546)
self.assertEqual(profile.preferred_cmm_type, 0)
self.assertEqual(profile.version, '2.2.0')
self.assertEqual(profile.device_class, 'input device profile')
self.assertEqual(profile.colour_space, 'RGB')
self.assertEqual(profile.datetime,
datetime.datetime(2001, 8, 30, 13, 32, 37))
self.assertEqual(profile.file_signature, 'acsp')
self.assertEqual(profile.platform, 'unrecognized')
self.assertTrue(profile.flags & 0x01) # embedded
self.assertFalse(profile.flags & 0x02) # use anywhere
self.assertEqual(profile.device_manufacturer, 'KODA')
self.assertEqual(profile.device_model, 'ROMM')
self.assertFalse(profile.device_attributes & 0x01) # reflective
self.assertFalse(profile.device_attributes & 0x02) # glossy
self.assertFalse(profile.device_attributes & 0x04) # positive
self.assertFalse(profile.device_attributes & 0x08) # colour
self.assertEqual(profile.rendering_intent & 0x00ff, 0) # perceptual
np.testing.assert_almost_equal(profile.illuminant,
(0.964203, 1.000000, 0.824905),
decimal=6)
self.assertEqual(profile.creator, 'JPEG')
@unittest.skipIf(sys.hexversion < 0x03020000,
"Uses features introduced in 3.2.")
def test_invalid_profile_header(self):
jfile = os.path.join(data_root,
'input/nonregression/orb-blue10-lin-jp2.jp2')
with self.assertWarns(UserWarning) as cw:
data = Jp2k(jfile).read()
if __name__ == "__main__":
unittest.main()

View file

@ -3579,7 +3579,7 @@ class TestSuite(unittest.TestCase):
self.assertEqual(jp2.box[3].box[1].method, 2) # enumerated self.assertEqual(jp2.box[3].box[1].method, 2) # enumerated
self.assertEqual(jp2.box[3].box[1].precedence, 0) 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].approximation, 1) # JPX exact
self.assertEqual(len(jp2.box[3].box[1].icc_profile), 546) self.assertEqual(jp2.box[3].box[1].icc_profile.size, 546)
self.assertIsNone(jp2.box[3].box[1].colorspace) self.assertIsNone(jp2.box[3].box[1].colorspace)
# Jp2 Header # Jp2 Header
@ -3674,7 +3674,7 @@ class TestSuite(unittest.TestCase):
self.assertEqual(jp2.box[3].box[1].method, 2) self.assertEqual(jp2.box[3].box[1].method, 2)
self.assertEqual(jp2.box[3].box[1].precedence, 0) 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].approximation, 1) # JPX exact
self.assertEqual(len(jp2.box[3].box[1].icc_profile), 13332) self.assertEqual(jp2.box[3].box[1].icc_profile.size, 13332)
self.assertIsNone(jp2.box[3].box[1].colorspace) self.assertIsNone(jp2.box[3].box[1].colorspace)
# Jp2 Header # Jp2 Header
@ -3723,7 +3723,7 @@ class TestSuite(unittest.TestCase):
self.assertEqual(jp2.box[2].box[1].method, 2) # enumerated self.assertEqual(jp2.box[2].box[1].method, 2) # enumerated
self.assertEqual(jp2.box[2].box[1].precedence, 0) 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].approximation, 1) # JPX exact
self.assertEqual(len(jp2.box[2].box[1].icc_profile), 414) self.assertEqual(jp2.box[2].box[1].icc_profile.size, 414)
self.assertIsNone(jp2.box[2].box[1].colorspace) self.assertIsNone(jp2.box[2].box[1].colorspace)
# XML box # XML box
@ -6394,7 +6394,10 @@ class TestSuite(unittest.TestCase):
def test_NR_orb_blue10_lin_jp2_dump(self): def test_NR_orb_blue10_lin_jp2_dump(self):
jfile = os.path.join(data_root, jfile = os.path.join(data_root,
'input/nonregression/orb-blue10-lin-jp2.jp2') 'input/nonregression/orb-blue10-lin-jp2.jp2')
jp2 = Jp2k(jfile) with warnings.catch_warnings():
# This file has an invalid ICC profile
warnings.simplefilter("ignore")
jp2 = Jp2k(jfile)
ids = [box.id for box in jp2.box] ids = [box.id for box in jp2.box]
self.assertEqual(ids, ['jP ', 'ftyp', 'jp2h', 'jp2c']) self.assertEqual(ids, ['jP ', 'ftyp', 'jp2h', 'jp2c'])
@ -6426,7 +6429,7 @@ class TestSuite(unittest.TestCase):
self.assertEqual(jp2.box[2].box[1].method, 2) # res icc self.assertEqual(jp2.box[2].box[1].method, 2) # res icc
self.assertEqual(jp2.box[2].box[1].precedence, 0) self.assertEqual(jp2.box[2].box[1].precedence, 0)
self.assertEqual(jp2.box[2].box[1].approximation, 0) # JP2 self.assertEqual(jp2.box[2].box[1].approximation, 0) # JP2
self.assertEqual(len(jp2.box[2].box[1].icc_profile), 1) self.assertIsNone(jp2.box[2].box[1].icc_profile)
self.assertIsNone(jp2.box[2].box[1].colorspace) self.assertIsNone(jp2.box[2].box[1].colorspace)
c = jp2.box[3].main_header c = jp2.box[3].main_header
@ -6490,7 +6493,10 @@ class TestSuite(unittest.TestCase):
def test_NR_orb_blue10_win_jp2_dump(self): def test_NR_orb_blue10_win_jp2_dump(self):
jfile = os.path.join(data_root, jfile = os.path.join(data_root,
'input/nonregression/orb-blue10-win-jp2.jp2') 'input/nonregression/orb-blue10-win-jp2.jp2')
jp2 = Jp2k(jfile) with warnings.catch_warnings():
# This file has an invalid ICC profile
warnings.simplefilter("ignore")
jp2 = Jp2k(jfile)
ids = [box.id for box in jp2.box] ids = [box.id for box in jp2.box]
self.assertEqual(ids, ['jP ', 'ftyp', 'jp2h', 'jp2c']) self.assertEqual(ids, ['jP ', 'ftyp', 'jp2h', 'jp2c'])
@ -6522,7 +6528,7 @@ class TestSuite(unittest.TestCase):
self.assertEqual(jp2.box[2].box[1].method, 2) # restricted icc self.assertEqual(jp2.box[2].box[1].method, 2) # restricted icc
self.assertEqual(jp2.box[2].box[1].precedence, 0) self.assertEqual(jp2.box[2].box[1].precedence, 0)
self.assertEqual(jp2.box[2].box[1].approximation, 0) # JP2 self.assertEqual(jp2.box[2].box[1].approximation, 0) # JP2
self.assertEqual(len(jp2.box[2].box[1].icc_profile), 1) self.assertIsNone(jp2.box[2].box[1].icc_profile)
self.assertIsNone(jp2.box[2].box[1].colorspace) self.assertIsNone(jp2.box[2].box[1].colorspace)
c = jp2.box[3].main_header c = jp2.box[3].main_header
@ -6624,7 +6630,7 @@ class TestSuite(unittest.TestCase):
self.assertEqual(jp2.box[3].box[1].method, 3) # any icc self.assertEqual(jp2.box[3].box[1].method, 3) # any icc
self.assertEqual(jp2.box[3].box[1].precedence, 2) self.assertEqual(jp2.box[3].box[1].precedence, 2)
self.assertEqual(jp2.box[3].box[1].approximation, 1) # JPX exact self.assertEqual(jp2.box[3].box[1].approximation, 1) # JPX exact
self.assertEqual(len(jp2.box[3].box[1].icc_profile), 1328) self.assertEqual(jp2.box[3].box[1].icc_profile.size, 1328)
self.assertIsNone(jp2.box[3].box[1].colorspace) self.assertIsNone(jp2.box[3].box[1].colorspace)
# UUID boxes. All mentioned in the RREQ box. # UUID boxes. All mentioned in the RREQ box.
@ -6859,7 +6865,10 @@ class TestSuite(unittest.TestCase):
def test_NR_DEC_orb_blue_lin_jp2_25_decode(self): def test_NR_DEC_orb_blue_lin_jp2_25_decode(self):
jfile = os.path.join(data_root, jfile = os.path.join(data_root,
'input/nonregression/orb-blue10-lin-jp2.jp2') 'input/nonregression/orb-blue10-lin-jp2.jp2')
data = Jp2k(jfile).read() with warnings.catch_warnings():
# This file has an invalid ICC profile
warnings.simplefilter("ignore")
data = Jp2k(jfile).read()
self.assertTrue(True) self.assertTrue(True)
def test_NR_DEC_orb_blue_win_jp2_26_decode(self): def test_NR_DEC_orb_blue_win_jp2_26_decode(self):

View file

@ -790,7 +790,24 @@ class TestPrinting(unittest.TestCase):
' Precedence: 2', ' Precedence: 2',
' Approximation: accurately represents ' ' Approximation: accurately represents '
+ 'correct colorspace definition', + 'correct colorspace definition',
' ICC Profile: 1328 bytes'] ' ICC Profile: ',
' Size: 1328',
' Preferred CMM type: 6170706c',
' Version: 2.2.0',
' Device class signature: display device profile',
' Color space: RGB',
' Connection space: XYZ',
' Creation time: 2009-02-25 11:26:11',
' File signature: acsp',
' Platform: APPL',
' Flags: not embedded, can be used independently',
' Device manufacturer: appl',
' Device model: ',
' Device attributes: '
+ 'reflective, glossy, positive media polarity, color media',
' Rendering intent: perceptual',
' Illuminant: [ 0.96420288 1. 0.8249054 ]',
' Creator signature: appl']
expected = '\n'.join(lines) expected = '\n'.join(lines)
self.assertEqual(actual, expected) self.assertEqual(actual, expected)

View file

@ -1,7 +1,7 @@
from distutils.core import setup from distutils.core import setup
kwargs = {'name': 'Glymur', kwargs = {'name': 'Glymur',
'version': '0.1.7', 'version': '0.1.8',
'description': 'Tools for accessing JPEG2000 files', 'description': 'Tools for accessing JPEG2000 files',
'long_description': open('README.md').read(), 'long_description': open('README.md').read(),
'author': 'John Evans', 'author': 'John Evans',