merge branch 'devel' of https://github.com/quintusdias/glymur into devel
Conflicts: glymur/test/test_config.py glymur/test/test_glymur_warnings.py glymur/test/test_opj_suite_dump.py glymur/test/test_printing.py
This commit is contained in:
commit
e2465c5c73
32 changed files with 274 additions and 518 deletions
|
|
@ -9,7 +9,6 @@ before_install:
|
|||
- sudo apt-get install -qq python-numpy
|
||||
- wget http://openjpeg.googlecode.com/files/openjpeg-1.5.0-Linux-x86_64.tar.gz
|
||||
- sudo tar -xvf openjpeg-1.5.0-Linux-x86_64.tar.gz --strip-components=1 -C /
|
||||
- pip install coveralls
|
||||
|
||||
# command to install dependencies
|
||||
install:
|
||||
|
|
@ -20,11 +19,6 @@ install:
|
|||
# command to run tests
|
||||
script:
|
||||
- python -m unittest discover
|
||||
after_success:
|
||||
- if [[ $ENV == pythone=3.4* ]]; then
|
||||
coveralls;
|
||||
fi
|
||||
|
||||
|
||||
notifications:
|
||||
email: "john.g.evans.ne@gmail.com"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
# serve to show the default.
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
class Mock(object):
|
||||
|
|
@ -42,12 +41,12 @@ for mod_name in MOCK_MODULES:
|
|||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ----------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
|
|
@ -62,7 +61,7 @@ templates_path = ['_templates']
|
|||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
# source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
|
@ -82,13 +81,13 @@ release = '0.7.2'
|
|||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
# language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
# today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
|
|
@ -96,24 +95,24 @@ exclude_patterns = []
|
|||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#default_role = None
|
||||
# default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
# add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
# add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
# show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
# modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- Options for HTML output --------------------------------------------------
|
||||
|
|
@ -125,26 +124,26 @@ html_theme = 'default'
|
|||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
# html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
# html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
# html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
# html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
# html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
# html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
|
|
@ -153,44 +152,44 @@ html_static_path = ['_static']
|
|||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
# html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
# html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
# html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
# html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
# html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
# html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
# html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
# html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
# html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
# html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
# html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'glymurdoc'
|
||||
|
|
@ -199,13 +198,13 @@ htmlhelp_basename = 'glymurdoc'
|
|||
# -- Options for LaTeX output -------------------------------------------------
|
||||
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
# 'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
# 'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
# 'preamble': '',
|
||||
latex_elements = {}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
|
|
@ -216,23 +215,23 @@ latex_documents = [('index', 'glymur.tex', u'glymur Documentation',
|
|||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
# latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
# latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
# latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
# latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
# latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
# latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output -------------------------------------------
|
||||
|
|
@ -245,7 +244,7 @@ man_pages = [
|
|||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
# man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -----------------------------------------------
|
||||
|
|
@ -258,13 +257,13 @@ texinfo_documents = [('index', 'glymur', u'glymur Documentation',
|
|||
'One line description of project.', 'Miscellaneous'), ]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
# texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
# texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
# texinfo_show_urls = 'footnote'
|
||||
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
|
|
|
|||
|
|
@ -214,9 +214,9 @@ making use of the :py:meth:`set_printoptions` function::
|
|||
UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
|
||||
Contiguous Codestream Box (jp2c) @ (3223, 1132296)
|
||||
|
||||
It is possible to print all the gory codestream details as well, i.e. ::
|
||||
It is possible to easily print the codestream header details as well, i.e. ::
|
||||
|
||||
>>> print(j.get_codestream()) # details not shown
|
||||
>>> print(j.codestream) # details not show
|
||||
|
||||
... add XML metadata?
|
||||
=====================
|
||||
|
|
|
|||
|
|
@ -1,21 +1,25 @@
|
|||
"""glymur - read, write, and interrogate JPEG 2000 files
|
||||
"""
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from glymur import version
|
||||
__version__ = version.version
|
||||
|
||||
from .jp2k import Jp2k
|
||||
from .jp2box import (
|
||||
get_printoptions, set_printoptions,
|
||||
get_parseoptions, set_parseoptions
|
||||
)
|
||||
from .jp2box import (get_printoptions,
|
||||
set_printoptions,
|
||||
get_parseoptions,
|
||||
set_parseoptions)
|
||||
|
||||
from . import data
|
||||
|
||||
|
||||
def runtests():
|
||||
"""Discover and run all tests for the glymur package.
|
||||
"""
|
||||
suite = unittest.defaultTestLoader.discover(__path__[0])
|
||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
||||
|
||||
|
||||
__all__ = [__version__, Jp2k, get_printoptions, set_printoptions,
|
||||
get_parseoptions, set_parseoptions, data, runtests]
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
Part of glymur.
|
||||
"""
|
||||
from collections import OrderedDict
|
||||
import pprint
|
||||
import re
|
||||
import struct
|
||||
import sys
|
||||
import warnings
|
||||
|
|
|
|||
|
|
@ -6,16 +6,13 @@ codestreams.
|
|||
|
||||
# The number of lines in the module is long and that's ok. It would not help
|
||||
# matters to move anything out to another file.
|
||||
# pylint: disable=C0302
|
||||
|
||||
# "Too many instance attributes", "Too many arguments"
|
||||
# Some segments just have a lot of information.
|
||||
# It doesn't make sense to subclass just for that.
|
||||
# pylint: disable=R0902,R0913
|
||||
|
||||
# "Too few public methods" Some segments don't define any new methods from
|
||||
# the base Segment class.
|
||||
# pylint: disable=R0903
|
||||
|
||||
import math
|
||||
import struct
|
||||
|
|
@ -31,16 +28,15 @@ from .core import (LRCP, RLCP, RPCL, PCRL, CPRL,
|
|||
from .lib import openjp2 as opj2
|
||||
|
||||
_factory = lambda x: '{0} (invalid)'.format(x)
|
||||
_PROGRESSION_ORDER_DISPLAY = _Keydefaultdict(_factory,
|
||||
{ LRCP: 'LRCP',
|
||||
RLCP: 'RLCP',
|
||||
RPCL: 'RPCL',
|
||||
PCRL: 'PCRL',
|
||||
CPRL: 'CPRL'})
|
||||
_PROGRESSION_ORDER_DISPLAY = _Keydefaultdict(_factory, {LRCP: 'LRCP',
|
||||
RLCP: 'RLCP',
|
||||
RPCL: 'RPCL',
|
||||
PCRL: 'PCRL',
|
||||
CPRL: 'CPRL'})
|
||||
|
||||
_WAVELET_TRANSFORM_DISPLAY = _Keydefaultdict(_factory,
|
||||
{ WAVELET_XFORM_9X7_IRREVERSIBLE: '9-7 irreversible',
|
||||
WAVELET_XFORM_5X3_REVERSIBLE: '5-3 reversible'})
|
||||
_keysvalues = {WAVELET_XFORM_9X7_IRREVERSIBLE: '9-7 irreversible',
|
||||
WAVELET_XFORM_5X3_REVERSIBLE: '5-3 reversible'}
|
||||
_WAVELET_TRANSFORM_DISPLAY = _Keydefaultdict(_factory, _keysvalues)
|
||||
|
||||
_NO_PROFILE = 0
|
||||
_PROFILE_0 = 1
|
||||
|
|
@ -51,12 +47,11 @@ _PROFILE_4 = 4
|
|||
_KNOWN_PROFILES = [_NO_PROFILE, _PROFILE_0, _PROFILE_1, _PROFILE_3, _PROFILE_4]
|
||||
|
||||
# How to display the codestream profile.
|
||||
_CAPABILITIES_DISPLAY = _Keydefaultdict(_factory,
|
||||
{ _NO_PROFILE: 'no profile',
|
||||
_PROFILE_0: '0',
|
||||
_PROFILE_1: '1',
|
||||
_PROFILE_3: 'Cinema 2K',
|
||||
_PROFILE_4: 'Cinema 4K'})
|
||||
_CAPABILITIES_DISPLAY = _Keydefaultdict(_factory, {_NO_PROFILE: 'no profile',
|
||||
_PROFILE_0: '0',
|
||||
_PROFILE_1: '1',
|
||||
_PROFILE_3: 'Cinema 2K',
|
||||
_PROFILE_4: 'Cinema 4K'})
|
||||
|
||||
# Need a catch-all list of valid markers.
|
||||
# See table A-1 in ISO/IEC FCD15444-1.
|
||||
|
|
@ -298,7 +293,6 @@ class Codestream(object):
|
|||
msg += ''.join(strs)
|
||||
return msg
|
||||
|
||||
# pylint: disable=R0201
|
||||
def _parse_cme_segment(self, fptr):
|
||||
"""Parse the CME marker segment.
|
||||
|
||||
|
|
@ -694,7 +688,7 @@ class Codestream(object):
|
|||
try:
|
||||
num_tiles_x = (xysiz[0] - xyosiz[0]) / (xytsiz[0] - xytosiz[0])
|
||||
num_tiles_y = (xysiz[1] - xyosiz[1]) / (xytsiz[1] - xytosiz[1])
|
||||
except ZeroDivisionError as err:
|
||||
except ZeroDivisionError:
|
||||
warnings.warn("Invalid tile dimensions.")
|
||||
else:
|
||||
numtiles = math.ceil(num_tiles_x) * math.ceil(num_tiles_y)
|
||||
|
|
@ -828,7 +822,6 @@ class Codestream(object):
|
|||
|
||||
return TLMsegment(length, offset, ztlm, ttlm, ptlm)
|
||||
|
||||
# pylint: disable=W0613
|
||||
def _parse_reserved_marker(self, fptr):
|
||||
"""Marker range between 0xff30 and 0xff39.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ Entry point for console script jp2dump.
|
|||
"""
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
from . import Jp2k, set_printoptions, lib
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
"""Core definitions to be shared amongst the modules.
|
||||
"""
|
||||
import collections
|
||||
import copy
|
||||
import lxml.etree as ET
|
||||
|
||||
|
||||
class _Keydefaultdict(collections.defaultdict):
|
||||
|
|
|
|||
|
|
@ -43,4 +43,3 @@ def jpxfile():
|
|||
"""
|
||||
filename = pkg_resources.resource_filename(__name__, "heliov.jpx")
|
||||
return filename
|
||||
|
||||
|
|
|
|||
212
glymur/jp2box.py
212
glymur/jp2box.py
|
|
@ -11,8 +11,6 @@ References
|
|||
Extensions
|
||||
"""
|
||||
|
||||
# pylint: disable=C0302,R0903,R0913,W0142
|
||||
|
||||
from collections import OrderedDict
|
||||
import datetime
|
||||
import io
|
||||
|
|
@ -22,7 +20,7 @@ import pprint
|
|||
import struct
|
||||
import sys
|
||||
import textwrap
|
||||
import uuid
|
||||
from uuid import UUID
|
||||
import warnings
|
||||
|
||||
import lxml.etree as ET
|
||||
|
|
@ -37,18 +35,21 @@ from .core import (_COLORSPACE_MAP_DISPLAY, _COLOR_TYPE_MAP_DISPLAY,
|
|||
|
||||
from . import _uuid_io
|
||||
|
||||
_METHOD_DISPLAY = {
|
||||
ENUMERATED_COLORSPACE: 'enumerated colorspace',
|
||||
RESTRICTED_ICC_PROFILE: 'restricted ICC profile',
|
||||
ANY_ICC_PROFILE: 'any ICC profile',
|
||||
VENDOR_COLOR_METHOD: 'vendor color method'}
|
||||
_factory = lambda x: '{0} (invalid)'.format(x)
|
||||
_keysvalues = {ENUMERATED_COLORSPACE: 'enumerated colorspace',
|
||||
RESTRICTED_ICC_PROFILE: 'restricted ICC profile',
|
||||
ANY_ICC_PROFILE: 'any ICC profile',
|
||||
VENDOR_COLOR_METHOD: 'vendor color method'}
|
||||
_METHOD_DISPLAY = _Keydefaultdict(_factory, _keysvalues)
|
||||
|
||||
_factory = lambda x: '{0} (invalid)'.format(x)
|
||||
_APPROX_DISPLAY = _Keydefaultdict(_factory,
|
||||
{1: 'accurately represents correct colorspace definition',
|
||||
2: 'approximates correct colorspace definition, exceptional quality',
|
||||
3: 'approximates correct colorspace definition, reasonable quality',
|
||||
4: 'approximates correct colorspace definition, poor quality'})
|
||||
_keysvalues = {1: 'accurately represents correct colorspace definition',
|
||||
2: ('approximates correct colorspace definition, '
|
||||
'exceptional quality'),
|
||||
3: ('approximates correct colorspace definition, '
|
||||
'reasonable quality'),
|
||||
4: 'approximates correct colorspace definition, poor quality'}
|
||||
_APPROX_DISPLAY = _Keydefaultdict(_factory, _keysvalues)
|
||||
|
||||
|
||||
class Jp2kBox(object):
|
||||
|
|
@ -1317,7 +1318,13 @@ class FileTypeBox(Jp2kBox):
|
|||
for j in range(int(num_entries)):
|
||||
entry, = struct.unpack_from('>4s', read_buffer, 8 + j * 4)
|
||||
if sys.hexversion >= 0x03000000:
|
||||
entry = entry.decode('utf-8')
|
||||
try:
|
||||
entry = entry.decode('utf-8')
|
||||
except UnicodeDecodeError as err:
|
||||
# The entry is invalid, but we've got code to catch this
|
||||
# later on.
|
||||
pass
|
||||
|
||||
compatibility_list.append(entry)
|
||||
|
||||
return cls(brand=brand, minor_version=minor_version,
|
||||
|
|
@ -1983,7 +1990,6 @@ class PaletteBox(Jp2kBox):
|
|||
*bps_signed)
|
||||
fptr.write(write_buffer)
|
||||
|
||||
bps = self.bits_per_component
|
||||
# All components are the same. Writing is straightforward.
|
||||
if self.bits_per_component[0] <= 8:
|
||||
write_buffer = memoryview(self.palette.astype(np.uint8))
|
||||
|
|
@ -2023,13 +2029,10 @@ class PaletteBox(Jp2kBox):
|
|||
# Ok the palette has the same datatype for all columns. We should
|
||||
# be able to efficiently read it.
|
||||
if bps[0] <= 8:
|
||||
nbytes_per_row = ncols
|
||||
dtype = np.uint8
|
||||
elif bps[0] <= 16:
|
||||
nbytes_per_row = 2 * ncols
|
||||
dtype = np.uint16
|
||||
elif bps[0] <= 32:
|
||||
nbytes_per_row = 3 * ncols
|
||||
dtype = np.uint32
|
||||
|
||||
palette = np.frombuffer(read_buffer[3 + ncols:], dtype=dtype)
|
||||
|
|
@ -2073,80 +2076,80 @@ _READER_REQUIREMENTS_DISPLAY = {
|
|||
7: 'JPEG codestream as defined in ISO/IEC 10918-1',
|
||||
8: 'Deprecated - does not contain opacity',
|
||||
9: 'Non-premultiplied opacity channel',
|
||||
10: 'Premultiplied opacity channel',
|
||||
11: 'Chroma-key based opacity',
|
||||
12: 'Deprecated - codestream is contiguous',
|
||||
13: 'Fragmented codestream where all fragments are in file and in order',
|
||||
14: 'Fragmented codestream where all fragments are in file '
|
||||
+ 'but are out of order',
|
||||
15: 'Fragmented codestream where not all fragments are within the file '
|
||||
+ 'but are all in locally accessible files',
|
||||
16: 'Fragmented codestream where some fragments may be accessible '
|
||||
+ 'only through a URL specified network connection',
|
||||
17: 'Compositing required to produce rendered result from multiple '
|
||||
+ 'compositing layers',
|
||||
18: 'Deprecated - support for compositing is not required',
|
||||
19: 'Deprecated - contains multiple, discrete layers that should not '
|
||||
+ 'be combined through either animation or compositing',
|
||||
20: 'Deprecated - compositing layers each contain only a single '
|
||||
+ 'codestream',
|
||||
21: 'At least one compositing layer consists of multiple codestreams',
|
||||
22: 'Deprecated - all compositing layers are in the same colourspace',
|
||||
23: 'Colourspace transformations are required to combine compositing '
|
||||
+ 'layers; not all compositing layers are in the same colourspace',
|
||||
24: 'Deprecated - rendered result created without using animation',
|
||||
25: 'Deprecated - animated, but first layer covers entire area and is '
|
||||
+ 'opaque',
|
||||
26: 'First animation layer does not cover entire rendered result',
|
||||
27: 'Deprecated - animated, and no layer is reused',
|
||||
28: 'Reuse of animation layers',
|
||||
29: 'Deprecated - animated, but layers are reused',
|
||||
30: 'Some animated frames are non-persistent',
|
||||
31: 'Deprecated - rendered result created without using scaling',
|
||||
32: 'Rendered result involves scaling within a layer',
|
||||
33: 'Rendered result involves scaling between layers',
|
||||
34: 'ROI metadata',
|
||||
35: 'IPR metadata',
|
||||
36: 'Content metadata',
|
||||
37: 'History metadata',
|
||||
38: 'Creation metadata',
|
||||
39: 'JPX digital signatures',
|
||||
40: 'JPX checksums',
|
||||
41: 'Desires Graphics Arts Reproduction specified',
|
||||
42: 'Deprecated - compositing layer uses palettized colour',
|
||||
43: 'Deprecated - compositing layer uses restricted ICC profile',
|
||||
44: 'Compositing layer uses Any ICC profile',
|
||||
45: 'Deprecated - compositing layer uses sRGB enumerated colourspace',
|
||||
46: 'Deprecated - compositing layer uses sRGB-grey enumerated colourspace',
|
||||
47: 'BiLevel 1 enumerated colourspace',
|
||||
48: 'BiLevel 2 enumerated colourspace',
|
||||
49: 'YCbCr 1 enumerated colourspace',
|
||||
50: 'YCbCr 2 enumerated colourspace',
|
||||
51: 'YCbCr 3 enumerated colourspace',
|
||||
52: 'PhotoYCC enumerated colourspace',
|
||||
53: 'YCCK enumerated colourspace',
|
||||
54: 'CMY enumerated colourspace',
|
||||
55: 'CMYK enumerated colorspace',
|
||||
56: 'CIELab enumerated colourspace with default parameters',
|
||||
57: 'CIELab enumerated colourspace with non-default parameters',
|
||||
58: 'CIEJab enumerated colourspace with default parameters',
|
||||
59: 'CIEJab enumerated colourspace with non-default parameters',
|
||||
60: 'e-sRGB enumerated colorspace',
|
||||
61: 'ROMM_RGB enumerated colorspace',
|
||||
62: 'Non-square samples',
|
||||
63: 'Deprecated - compositing layers have labels',
|
||||
64: 'Deprecated - codestreams have labels',
|
||||
65: 'Deprecated - compositing layers have different colour spaces',
|
||||
66: 'Deprecated - compositing layers have different metadata',
|
||||
67: 'GIS metadata XML box',
|
||||
68: 'JPSEC extensions in codestream as specified by ISO/IEC 15444-8',
|
||||
69: 'JP3D extensions in codestream as specified by ISO/IEC 15444-10',
|
||||
70: 'Deprecated - compositing layer uses sYCC enumerated colour space',
|
||||
71: 'e-sYCC enumerated colourspace',
|
||||
72: 'JPEG 2000 Part 2 codestream as restricted by baseline conformance '
|
||||
+ 'requirements in M.9.2.3',
|
||||
73: 'YPbPr(1125/60) enumerated colourspace',
|
||||
74: 'YPbPr(1250/50) enumerated colourspace'}
|
||||
10: 'Premultiplied opacity channel',
|
||||
11: 'Chroma-key based opacity',
|
||||
12: 'Deprecated - codestream is contiguous',
|
||||
13: 'Fragmented codestream where all fragments are in file and in order',
|
||||
14: ('Fragmented codestream where all fragments are in file '
|
||||
'but are out of order'),
|
||||
15: ('Fragmented codestream where not all fragments are within the file '
|
||||
'but are all in locally accessible files'),
|
||||
16: ('Fragmented codestream where some fragments may be accessible '
|
||||
'only through a URL specified network connection'),
|
||||
17: ('Compositing required to produce rendered result from multiple '
|
||||
'compositing layers'),
|
||||
18: 'Deprecated - support for compositing is not required',
|
||||
19: ('Deprecated - contains multiple, discrete layers that should not '
|
||||
'be combined through either animation or compositing'),
|
||||
20: ('Deprecated - compositing layers each contain only a single '
|
||||
'codestream'),
|
||||
21: 'At least one compositing layer consists of multiple codestreams',
|
||||
22: 'Deprecated - all compositing layers are in the same colourspace',
|
||||
23: ('Colourspace transformations are required to combine compositing '
|
||||
'layers; not all compositing layers are in the same colourspace'),
|
||||
24: 'Deprecated - rendered result created without using animation',
|
||||
25: ('Deprecated - animated, but first layer covers entire area and is '
|
||||
'opaque'),
|
||||
26: 'First animation layer does not cover entire rendered result',
|
||||
27: 'Deprecated - animated, and no layer is reused',
|
||||
28: 'Reuse of animation layers',
|
||||
29: 'Deprecated - animated, but layers are reused',
|
||||
30: 'Some animated frames are non-persistent',
|
||||
31: 'Deprecated - rendered result created without using scaling',
|
||||
32: 'Rendered result involves scaling within a layer',
|
||||
33: 'Rendered result involves scaling between layers',
|
||||
34: 'ROI metadata',
|
||||
35: 'IPR metadata',
|
||||
36: 'Content metadata',
|
||||
37: 'History metadata',
|
||||
38: 'Creation metadata',
|
||||
39: 'JPX digital signatures',
|
||||
40: 'JPX checksums',
|
||||
41: 'Desires Graphics Arts Reproduction specified',
|
||||
42: 'Deprecated - compositing layer uses palettized colour',
|
||||
43: 'Deprecated - compositing layer uses restricted ICC profile',
|
||||
44: 'Compositing layer uses Any ICC profile',
|
||||
45: 'Deprecated - compositing layer uses sRGB enumerated colourspace',
|
||||
46: 'Deprecated - compositing layer uses sRGB-grey enumerated colourspace',
|
||||
47: 'BiLevel 1 enumerated colourspace',
|
||||
48: 'BiLevel 2 enumerated colourspace',
|
||||
49: 'YCbCr 1 enumerated colourspace',
|
||||
50: 'YCbCr 2 enumerated colourspace',
|
||||
51: 'YCbCr 3 enumerated colourspace',
|
||||
52: 'PhotoYCC enumerated colourspace',
|
||||
53: 'YCCK enumerated colourspace',
|
||||
54: 'CMY enumerated colourspace',
|
||||
55: 'CMYK enumerated colorspace',
|
||||
56: 'CIELab enumerated colourspace with default parameters',
|
||||
57: 'CIELab enumerated colourspace with non-default parameters',
|
||||
58: 'CIEJab enumerated colourspace with default parameters',
|
||||
59: 'CIEJab enumerated colourspace with non-default parameters',
|
||||
60: 'e-sRGB enumerated colorspace',
|
||||
61: 'ROMM_RGB enumerated colorspace',
|
||||
62: 'Non-square samples',
|
||||
63: 'Deprecated - compositing layers have labels',
|
||||
64: 'Deprecated - codestreams have labels',
|
||||
65: 'Deprecated - compositing layers have different colour spaces',
|
||||
66: 'Deprecated - compositing layers have different metadata',
|
||||
67: 'GIS metadata XML box',
|
||||
68: 'JPSEC extensions in codestream as specified by ISO/IEC 15444-8',
|
||||
69: 'JP3D extensions in codestream as specified by ISO/IEC 15444-10',
|
||||
70: 'Deprecated - compositing layer uses sYCC enumerated colour space',
|
||||
71: 'e-sYCC enumerated colourspace',
|
||||
72: ('JPEG 2000 Part 2 codestream as restricted by baseline conformance '
|
||||
'requirements in M.9.2.3'),
|
||||
73: 'YPbPr(1125/60) enumerated colourspace',
|
||||
74: 'YPbPr(1250/50) enumerated colourspace'}
|
||||
|
||||
|
||||
class ReaderRequirementsBox(Jp2kBox):
|
||||
|
|
@ -2209,7 +2212,8 @@ class ReaderRequirementsBox(Jp2kBox):
|
|||
if _printoptions['short'] is True:
|
||||
return msg
|
||||
|
||||
msg += '\n Fully Understands Aspect Mask: 0x{0:x}'.format(self.fuam)
|
||||
msg += '\n Fully Understands Aspect Mask: 0x{0:x}'
|
||||
msg = msg.format(self.fuam)
|
||||
msg += '\n Display Completely Mask: 0x{0:x}'.format(self.dcm)
|
||||
|
||||
msg += '\n Standard Features and Masks:'
|
||||
|
|
@ -2265,8 +2269,8 @@ class ReaderRequirementsBox(Jp2kBox):
|
|||
standard_flag, standard_mask = data
|
||||
|
||||
nflags = len(standard_flag)
|
||||
vendor_offset = 1 + 2 * mask_length + 2 \
|
||||
+ (2 + mask_length) * nflags
|
||||
vendor_offset = (1 + 2 * mask_length + 2
|
||||
+ (2 + mask_length) * nflags)
|
||||
data = _parse_vendor_features(read_buffer[vendor_offset:],
|
||||
mask_length)
|
||||
vendor_feature, vendor_mask = data
|
||||
|
|
@ -2323,8 +2327,8 @@ def _parse_rreq3(read_buffer, length, offset):
|
|||
read_buffer = read_buffer[9 + num_standard_features * 10:]
|
||||
for j in range(num_vendor_features):
|
||||
uslice = slice(j * entry_length, (j + 1) * entry_length)
|
||||
ubuffer = read_buffer[slice]
|
||||
vendor_feature.append(uuid.UUID(bytes=ubuffer[0:16]))
|
||||
ubuffer = read_buffer[uslice]
|
||||
vendor_feature.append(UUID(bytes=ubuffer[0:16]))
|
||||
|
||||
lst = struct.unpack('>BBB', ubuffer[16:])
|
||||
vmask = lst[0] << 16 | lst[1] << 8 | lst[2]
|
||||
|
|
@ -2392,7 +2396,7 @@ def _parse_vendor_features(read_buffer, mask_length):
|
|||
for j in range(num_vendor_features):
|
||||
uslice = slice(2 + j * entry_length, 2 + (j + 1) * entry_length)
|
||||
ubuffer = read_buffer[uslice]
|
||||
vendor_feature.append(uuid.UUID(bytes=ubuffer[0:16]))
|
||||
vendor_feature.append(UUID(bytes=ubuffer[0:16]))
|
||||
|
||||
vmask = struct.unpack('>' + mask_format, ubuffer[16:])
|
||||
vendor_mask.append(vmask)
|
||||
|
|
@ -2944,7 +2948,7 @@ class UUIDListBox(Jp2kBox):
|
|||
ulst = []
|
||||
for j in range(num_uuids):
|
||||
uuid_buffer = read_buffer[2 + j * 16:2 + (j + 1) * 16]
|
||||
ulst.append(uuid.UUID(bytes=uuid_buffer))
|
||||
ulst.append(UUID(bytes=uuid_buffer))
|
||||
|
||||
return cls(ulst, length=length, offset=offset)
|
||||
|
||||
|
|
@ -3202,7 +3206,7 @@ class UUIDBox(Jp2kBox):
|
|||
"""
|
||||
Private function for parsing UUID payloads if possible.
|
||||
"""
|
||||
if self.uuid == uuid.UUID('be7acfcb-97a9-42e8-9c71-999491e3afac'):
|
||||
if self.uuid == UUID('be7acfcb-97a9-42e8-9c71-999491e3afac'):
|
||||
self.data = _uuid_io.xml(self.raw_data)
|
||||
elif self.uuid.bytes == b'JpgTiffExif->JP2':
|
||||
self.data = _uuid_io.tiff_header(self.raw_data)
|
||||
|
|
@ -3220,7 +3224,7 @@ class UUIDBox(Jp2kBox):
|
|||
return msg
|
||||
|
||||
msg = '{0}\n UUID: {1}'.format(msg, self.uuid)
|
||||
if self.uuid == uuid.UUID('be7acfcb-97a9-42e8-9c71-999491e3afac'):
|
||||
if self.uuid == UUID('be7acfcb-97a9-42e8-9c71-999491e3afac'):
|
||||
msg += ' (XMP)'
|
||||
elif self.uuid.bytes == b'JpgTiffExif->JP2':
|
||||
msg += ' (EXIF)'
|
||||
|
|
@ -3228,11 +3232,11 @@ class UUIDBox(Jp2kBox):
|
|||
msg += ' (unknown)'
|
||||
|
||||
if (((_printoptions['xml'] is False) and
|
||||
(self.uuid == uuid.UUID('be7acfcb-97a9-42e8-9c71-999491e3afac')))):
|
||||
(self.uuid == UUID('be7acfcb-97a9-42e8-9c71-999491e3afac')))):
|
||||
# If it's an XMP UUID, don't print the XML contents.
|
||||
return msg
|
||||
|
||||
if self.uuid == uuid.UUID('be7acfcb-97a9-42e8-9c71-999491e3afac'):
|
||||
if self.uuid == UUID('be7acfcb-97a9-42e8-9c71-999491e3afac'):
|
||||
line = '\n UUID Data:\n{0}'
|
||||
xmlstring = ET.tostring(self.data,
|
||||
encoding='utf-8',
|
||||
|
|
@ -3275,7 +3279,7 @@ class UUIDBox(Jp2kBox):
|
|||
"""
|
||||
num_bytes = offset + length - fptr.tell()
|
||||
read_buffer = fptr.read(num_bytes)
|
||||
the_uuid = uuid.UUID(bytes=read_buffer[0:16])
|
||||
the_uuid = UUID(bytes=read_buffer[0:16])
|
||||
return cls(the_uuid, read_buffer[16:], length=length, offset=offset)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -10,13 +10,12 @@ License: MIT
|
|||
import sys
|
||||
|
||||
# Exitstack not found in contextlib in 2.7
|
||||
# pylint: disable=E0611
|
||||
if sys.hexversion >= 0x03030000:
|
||||
from contextlib import ExitStack
|
||||
from itertools import compress, filterfalse
|
||||
from itertools import filterfalse
|
||||
else:
|
||||
from contextlib2 import ExitStack
|
||||
from itertools import compress, ifilterfalse as filterfalse
|
||||
from itertools import ifilterfalse as filterfalse
|
||||
|
||||
from collections import Counter
|
||||
import ctypes
|
||||
|
|
@ -61,6 +60,8 @@ class Jp2k(Jp2kBox):
|
|||
verbose : bool
|
||||
whether or not to print informational messages produced by the
|
||||
OpenJPEG library, defaults to false
|
||||
codestream : object
|
||||
JP2 or J2K codestream object
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
|
@ -146,6 +147,7 @@ class Jp2k(Jp2kBox):
|
|||
self._codec_format = None
|
||||
self._colorspace = None
|
||||
self._layer = 0
|
||||
self._codestream = None
|
||||
if data is not None:
|
||||
self._shape = data.shape
|
||||
else:
|
||||
|
|
@ -180,6 +182,16 @@ class Jp2k(Jp2kBox):
|
|||
raise RuntimeError(msg)
|
||||
self._layer = layer
|
||||
|
||||
@property
|
||||
def codestream(self):
|
||||
if self._codestream is None:
|
||||
self._codestream = self.get_codestream(header_only=True)
|
||||
return self._codestream
|
||||
|
||||
@codestream.setter
|
||||
def codestream(self, the_codestream):
|
||||
self._codestream = the_codestream
|
||||
|
||||
@property
|
||||
def verbose(self):
|
||||
return self._verbose
|
||||
|
|
@ -193,7 +205,7 @@ class Jp2k(Jp2kBox):
|
|||
if self._shape is not None:
|
||||
return self._shape
|
||||
|
||||
cstr = self.get_codestream(header_only=True)
|
||||
cstr = self.codestream
|
||||
height = cstr.segment[1].ysiz
|
||||
width = cstr.segment[1].xsiz
|
||||
num_components = len(cstr.segment[1].xrsiz)
|
||||
|
|
@ -234,8 +246,7 @@ class Jp2k(Jp2kBox):
|
|||
for box in self.box:
|
||||
metadata.append(str(box))
|
||||
else:
|
||||
codestream = self.get_codestream()
|
||||
metadata.append(str(codestream))
|
||||
metadata.append(str(self.codestream))
|
||||
return '\n'.join(metadata)
|
||||
|
||||
def parse(self):
|
||||
|
|
@ -517,12 +528,12 @@ class Jp2k(Jp2kBox):
|
|||
# set image offset and reference grid
|
||||
image.contents.x0 = self._cparams.image_offset_x0
|
||||
image.contents.y0 = self._cparams.image_offset_y0
|
||||
image.contents.x1 = image.contents.x0 \
|
||||
+ (numcols - 1) * self._cparams.subsampling_dx \
|
||||
+ 1
|
||||
image.contents.y1 = image.contents.y0 \
|
||||
+ (numrows - 1) * self._cparams.subsampling_dy \
|
||||
+ 1
|
||||
image.contents.x1 = (image.contents.x0
|
||||
+ (numcols - 1) * self._cparams.subsampling_dx
|
||||
+ 1)
|
||||
image.contents.y1 = (image.contents.y0
|
||||
+ (numrows - 1) * self._cparams.subsampling_dy
|
||||
+ 1)
|
||||
|
||||
# Stage the image data to the openjpeg data structure.
|
||||
for k in range(0, numlayers):
|
||||
|
|
@ -832,7 +843,7 @@ class Jp2k(Jp2kBox):
|
|||
raise IOError(msg)
|
||||
|
||||
# Find the first codestream in the file.
|
||||
jp2c = [box for box in self.box if box.box_id == 'jp2c']
|
||||
jp2c = [_box for _box in self.box if _box.box_id == 'jp2c']
|
||||
offset = jp2c[0].offset
|
||||
|
||||
# Ready to write the codestream.
|
||||
|
|
@ -866,10 +877,9 @@ class Jp2k(Jp2kBox):
|
|||
FileTypeBox(),
|
||||
JP2HeaderBox(),
|
||||
ContiguousCodestreamBox()]
|
||||
codestream = self.get_codestream()
|
||||
height = codestream.segment[1].ysiz
|
||||
width = codestream.segment[1].xsiz
|
||||
num_components = len(codestream.segment[1].xrsiz)
|
||||
height = self.codestream.segment[1].ysiz
|
||||
width = self.codestream.segment[1].xsiz
|
||||
num_components = len(self.codestream.segment[1].xrsiz)
|
||||
if num_components < 3:
|
||||
colorspace = core.GREYSCALE
|
||||
else:
|
||||
|
|
@ -908,10 +918,9 @@ class Jp2k(Jp2kBox):
|
|||
"""
|
||||
Slicing protocol.
|
||||
"""
|
||||
codestream = self.get_codestream(header_only=True)
|
||||
numrows = codestream.segment[1].ysiz
|
||||
numcols = codestream.segment[1].xsiz
|
||||
numbands = codestream.segment[1].Csiz
|
||||
numrows = self.codestream.segment[1].ysiz
|
||||
numcols = self.codestream.segment[1].xsiz
|
||||
numbands = self.codestream.segment[1].Csiz
|
||||
|
||||
if isinstance(pargs, int):
|
||||
# Not a very good use of this protocol, but technically legal.
|
||||
|
|
@ -1073,9 +1082,8 @@ class Jp2k(Jp2kBox):
|
|||
def _subsampling_sanity_check(self):
|
||||
"""Check for differing subsample factors.
|
||||
"""
|
||||
codestream = self.get_codestream(header_only=True)
|
||||
dxs = np.array(codestream.segment[1].xrsiz)
|
||||
dys = np.array(codestream.segment[1].yrsiz)
|
||||
dxs = np.array(self.codestream.segment[1].xrsiz)
|
||||
dys = np.array(self.codestream.segment[1].yrsiz)
|
||||
if np.any(dxs - dxs[0]) or np.any(dys - dys[0]):
|
||||
msg = "Components must all have the same subsampling factors "
|
||||
msg += "to use this method. Please consider using OPENJP2 and "
|
||||
|
|
@ -1278,8 +1286,7 @@ class Jp2k(Jp2kBox):
|
|||
# Must check the specified rlevel against the maximum.
|
||||
if rlevel != 0:
|
||||
# Must check the specified rlevel against the maximum.
|
||||
codestream = self.get_codestream()
|
||||
max_rlevel = codestream.segment[2].spcod[4]
|
||||
max_rlevel = self.codestream.segment[2].spcod[4]
|
||||
if rlevel == -1:
|
||||
# -1 is shorthand for the largest rlevel
|
||||
rlevel = max_rlevel
|
||||
|
|
@ -1435,7 +1442,6 @@ class Jp2k(Jp2kBox):
|
|||
codestream = Codestream(fptr, self.length,
|
||||
header_only=header_only)
|
||||
else:
|
||||
ftyp = self.box[1]
|
||||
box = [x for x in self.box if x.box_id == 'jp2c']
|
||||
fptr.seek(box[0].offset)
|
||||
read_buffer = fptr.read(8)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
"""
|
||||
Configure glymur to use installed libraries if possible.
|
||||
"""
|
||||
# configparser is new in python3 (pylint/python-2.7)
|
||||
# pylint: disable=F0401
|
||||
|
||||
import ctypes
|
||||
from ctypes.util import find_library
|
||||
import os
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Wraps individual functions in openjp2 library.
|
||||
"""
|
||||
|
||||
# pylint: disable=C0302,R0903,W0201
|
||||
|
||||
import ctypes
|
||||
import re
|
||||
import sys
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
"""Wraps library calls to openjpeg.
|
||||
"""
|
||||
|
||||
# pylint: disable=R0903
|
||||
|
||||
import ctypes
|
||||
import sys
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,8 @@
|
|||
"""
|
||||
Tests for libopenjp2 wrapping functions.
|
||||
"""
|
||||
# R0904: Seems like pylint is fooled in this situation
|
||||
# W0142: using kwargs is ok in this context
|
||||
# pylint: disable=R0904,W0142
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
|
|
@ -21,8 +16,8 @@ from glymur.lib import openjp2
|
|||
@unittest.skipIf(openjp2.OPENJP2 is None,
|
||||
"Missing openjp2 library.")
|
||||
@unittest.skipIf(re.match(r'''(1|2.0)''',
|
||||
glymur.version.openjpeg_version) is not None,
|
||||
"Not to be run until 2.1.0")
|
||||
glymur.version.openjpeg_version) is not None,
|
||||
"Not to be run until 2.1.0")
|
||||
class TestOpenJP2(unittest.TestCase):
|
||||
"""Test openjp2 library functionality.
|
||||
|
||||
|
|
@ -152,6 +147,7 @@ class TestOpenJP2(unittest.TestCase):
|
|||
xtx5_setup(tfile.name)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def tile_encoder(**kwargs):
|
||||
"""Fixture used by many tests."""
|
||||
num_tiles = ((kwargs['image_width'] / kwargs['tile_width']) *
|
||||
|
|
@ -215,7 +211,7 @@ def tile_encoder(**kwargs):
|
|||
openjp2.setup_encoder(codec, l_param, l_image)
|
||||
|
||||
stream = openjp2.stream_create_default_file_stream(kwargs['filename'],
|
||||
False)
|
||||
False)
|
||||
openjp2.start_compress(codec, l_image, stream)
|
||||
|
||||
for j in np.arange(num_tiles):
|
||||
|
|
@ -226,13 +222,14 @@ def tile_encoder(**kwargs):
|
|||
openjp2.destroy_codec(codec)
|
||||
openjp2.image_destroy(l_image)
|
||||
|
||||
|
||||
def tile_decoder(**kwargs):
|
||||
"""Fixture called with various configurations by many tests.
|
||||
|
||||
Reads a tile. That's all it does.
|
||||
"""
|
||||
stream = openjp2.stream_create_default_file_stream(kwargs['filename'],
|
||||
True)
|
||||
True)
|
||||
dparam = openjp2.set_default_decoder_parameters()
|
||||
|
||||
dparam.decod_format = kwargs['codec_format']
|
||||
|
|
@ -270,6 +267,7 @@ def tile_decoder(**kwargs):
|
|||
openjp2.stream_destroy(stream)
|
||||
openjp2.image_destroy(image)
|
||||
|
||||
|
||||
def ttx0_setup(filename):
|
||||
"""Runs tests tte0, tte0."""
|
||||
kwargs = {'filename': filename,
|
||||
|
|
@ -283,6 +281,7 @@ def ttx0_setup(filename):
|
|||
'tile_width': 100}
|
||||
tile_encoder(**kwargs)
|
||||
|
||||
|
||||
def xtx2_setup(filename):
|
||||
"""Runs tests rta2, tte2, ttd2."""
|
||||
kwargs = {'filename': filename,
|
||||
|
|
@ -296,6 +295,7 @@ def xtx2_setup(filename):
|
|||
'tile_width': 128}
|
||||
tile_encoder(**kwargs)
|
||||
|
||||
|
||||
def xtx3_setup(filename):
|
||||
"""Runs tests tte3, rta3."""
|
||||
kwargs = {'filename': filename,
|
||||
|
|
@ -309,6 +309,7 @@ def xtx3_setup(filename):
|
|||
'tile_width': 128}
|
||||
tile_encoder(**kwargs)
|
||||
|
||||
|
||||
def xtx4_setup(filename):
|
||||
"""Runs tests rta4, tte4."""
|
||||
kwargs = {'filename': filename,
|
||||
|
|
@ -322,6 +323,7 @@ def xtx4_setup(filename):
|
|||
'tile_width': 128}
|
||||
tile_encoder(**kwargs)
|
||||
|
||||
|
||||
def xtx5_setup(filename):
|
||||
"""Runs tests rta5, tte5."""
|
||||
kwargs = {'filename': filename,
|
||||
|
|
@ -334,6 +336,3 @@ def xtx5_setup(filename):
|
|||
'tile_height': 256,
|
||||
'tile_width': 256}
|
||||
tile_encoder(**kwargs)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
"""
|
||||
Tests for OpenJPEG module.
|
||||
"""
|
||||
# pylint: disable=E1101,R0904
|
||||
|
||||
import ctypes
|
||||
import re
|
||||
import sys
|
||||
|
|
@ -10,6 +8,7 @@ import unittest
|
|||
|
||||
import glymur
|
||||
|
||||
|
||||
@unittest.skipIf(glymur.lib.openjpeg.OPENJPEG is None,
|
||||
"Missing openjpeg library.")
|
||||
class TestOpenJPEG(unittest.TestCase):
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ else:
|
|||
import glymur
|
||||
from . import fixtures
|
||||
|
||||
|
||||
@unittest.skipIf(sys.hexversion < 0x03000000, "do not care about 2.7 here")
|
||||
@unittest.skipIf(re.match('0|1|2.0', glymur.version.openjpeg_version),
|
||||
"Requires openjpeg 2.1.0 or higher")
|
||||
|
|
@ -72,6 +73,3 @@ class TestPrintingOpenjp2(unittest.TestCase):
|
|||
|
||||
expected = fixtures.default_image_type
|
||||
self.assertRegex(actual, expected)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -236,7 +236,6 @@ try:
|
|||
|
||||
# The whole point of trying to import PIL is to determine if it's there
|
||||
# or not. We won't use it directly.
|
||||
# pylint: disable=F0401,W0611
|
||||
import PIL
|
||||
|
||||
NO_READ_BACKEND = False
|
||||
|
|
|
|||
|
|
@ -1,12 +1,6 @@
|
|||
"""
|
||||
Test suite for openjpeg's callback functions.
|
||||
"""
|
||||
# R0904: Seems like pylint is fooled in this situation
|
||||
# pylint: disable=R0904
|
||||
|
||||
# 'mock' most certainly is in unittest (Python 3.3)
|
||||
# pylint: disable=E0611,F0401
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
|
@ -99,8 +93,6 @@ class TestCallbacks(unittest.TestCase):
|
|||
[0-9]+\.[0-9]+\ss""",
|
||||
re.VERBOSE)
|
||||
|
||||
# assertRegex in Python 3.3 (python2.7/pylint issue)
|
||||
# pylint: disable=E1101
|
||||
if sys.hexversion <= 0x03020000:
|
||||
self.assertRegexpMatches(actual, regex)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -1,15 +1,6 @@
|
|||
"""These tests are for edge cases where OPENJPEG does not exist, but
|
||||
OPENJP2 may be present in some form or other.
|
||||
"""
|
||||
# unittest doesn't work well with R0904.
|
||||
# pylint: disable=R0904
|
||||
|
||||
# tempfile.TemporaryDirectory, unittest.assertWarns introduced in 3.2
|
||||
# pylint: disable=E1101
|
||||
|
||||
# unittest.mock only in Python 3.3 (python2.7/pylint import issue)
|
||||
# pylint: disable=E0611,F0401
|
||||
|
||||
import contextlib
|
||||
import ctypes
|
||||
import imp
|
||||
|
|
@ -98,7 +89,6 @@ class TestSuite(unittest.TestCase):
|
|||
|
||||
# Need to reliably recover the location of the openjp2 library,
|
||||
# so using '_name' appears to be the only way to do it.
|
||||
# pylint: disable=W0212
|
||||
libloc = glymur.lib.openjp2.OPENJP2._name
|
||||
line = 'openjp2: {0}\n'.format(libloc)
|
||||
tfile.write(line)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
"""
|
||||
Test suite for warnings issued by glymur.
|
||||
"""
|
||||
|
||||
# unittest doesn't work well with R0904.
|
||||
# pylint: disable=R0904
|
||||
|
||||
import os
|
||||
import re
|
||||
import struct
|
||||
|
|
@ -106,28 +102,6 @@ class TestWarnings(unittest.TestCase):
|
|||
with self.assertWarnsRegex(UserWarning, regex):
|
||||
Jp2k(jfile)
|
||||
|
||||
def test_NR_broken_jp2_dump(self):
|
||||
"""
|
||||
The colr box has a ridiculously incorrect box length.
|
||||
"""
|
||||
jfile = opj_data_file('input/nonregression/broken.jp2')
|
||||
regex = re.compile(r'''b'colr'\sbox\shas\sincorrect\sbox\slength\s
|
||||
\(\d+\)''',
|
||||
re.VERBOSE)
|
||||
with self.assertWarnsRegex(UserWarning, regex):
|
||||
Jp2k(jfile)
|
||||
|
||||
def test_NR_broken2_jp2_dump(self):
|
||||
"""
|
||||
Invalid marker ID on codestream.
|
||||
"""
|
||||
jfile = opj_data_file('input/nonregression/broken2.jp2')
|
||||
regex = re.compile(r'''Invalid\smarker\sid\sencountered\sat\sbyte\s
|
||||
\d+\sin\scodestream:\s*"0x[a-fA-F0-9]{4}"''',
|
||||
re.VERBOSE)
|
||||
with self.assertWarnsRegex(UserWarning, regex):
|
||||
Jp2k(jfile)
|
||||
|
||||
def test_bad_rsiz(self):
|
||||
"""Should warn if RSIZ is bad. Issue196"""
|
||||
filename = opj_data_file('input/nonregression/edf_c2_1002767.jp2')
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
"""
|
||||
ICC profile tests.
|
||||
"""
|
||||
|
||||
# unittest doesn't work well with R0904.
|
||||
# pylint: disable=R0904
|
||||
|
||||
import datetime
|
||||
import unittest
|
||||
|
||||
|
|
@ -64,11 +60,6 @@ class TestICC(unittest.TestCase):
|
|||
"""invalid ICC header data should cause UserWarning"""
|
||||
jfile = opj_data_file('input/nonregression/orb-blue10-lin-jp2.jp2')
|
||||
|
||||
# assertWarns in Python 3.3 (python2.7/pylint issue)
|
||||
# pylint: disable=E1101
|
||||
regex = 'ICC profile header is corrupt'
|
||||
with self.assertWarnsRegex(UserWarning, regex):
|
||||
Jp2k(jfile)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
|
|
@ -1,18 +1,6 @@
|
|||
"""
|
||||
Test suite specifically targeting JP2 box layout.
|
||||
"""
|
||||
# E1103: return value from read may be list or np array
|
||||
# pylint: disable=E1103
|
||||
|
||||
# R0902: More than 7 instance attributes are just fine for testing.
|
||||
# pylint: disable=R0902
|
||||
|
||||
# R0904: Seems like pylint is fooled in this situation
|
||||
# pylint: disable=R0904
|
||||
|
||||
# W0613: load_tests doesn't need to use ignore or loader arguments.
|
||||
# pylint: disable=W0613
|
||||
|
||||
import doctest
|
||||
import os
|
||||
import re
|
||||
|
|
@ -20,7 +8,6 @@ import shutil
|
|||
import struct
|
||||
import sys
|
||||
import tempfile
|
||||
import uuid
|
||||
from uuid import UUID
|
||||
import unittest
|
||||
|
||||
|
|
@ -642,7 +629,7 @@ class TestAppend(unittest.TestCase):
|
|||
jp2 = Jp2k(tfile.name)
|
||||
|
||||
# Make a UUID box. Only XMP UUID boxes can currently be appended.
|
||||
uuid_instance = uuid.UUID('00000000-0000-0000-0000-000000000000')
|
||||
uuid_instance = UUID('00000000-0000-0000-0000-000000000000')
|
||||
data = b'0123456789'
|
||||
uuidbox = glymur.jp2box.UUIDBox(uuid_instance, data)
|
||||
with self.assertRaises(IOError):
|
||||
|
|
@ -1234,8 +1221,8 @@ class TestRepr(MetadataBase):
|
|||
|
||||
def test_uuidlist_box(self):
|
||||
"""Verify __repr__ method on ulst box."""
|
||||
uuid1 = uuid.UUID('00000000-0000-0000-0000-000000000001')
|
||||
uuid2 = uuid.UUID('00000000-0000-0000-0000-000000000002')
|
||||
uuid1 = UUID('00000000-0000-0000-0000-000000000001')
|
||||
uuid2 = UUID('00000000-0000-0000-0000-000000000002')
|
||||
uuids = [uuid1, uuid2]
|
||||
ulst = glymur.jp2box.UUIDListBox(ulst=uuids)
|
||||
newbox = eval(repr(ulst))
|
||||
|
|
@ -1289,7 +1276,7 @@ class TestRepr(MetadataBase):
|
|||
|
||||
def test_uuid_box_generic(self):
|
||||
"""Verify uuid repr method."""
|
||||
uuid_instance = uuid.UUID('00000000-0000-0000-0000-000000000000')
|
||||
uuid_instance = UUID('00000000-0000-0000-0000-000000000000')
|
||||
data = b'0123456789'
|
||||
box = glymur.jp2box.UUIDBox(the_uuid=uuid_instance, raw_data=data)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Test suite for printing.
|
||||
"""
|
||||
# C0302: don't care too much about having too many lines in a test module
|
||||
# pylint: disable=C0302
|
||||
|
||||
# E061: unittest.mock introduced in 3.3 (python-2.7/pylint issue)
|
||||
# pylint: disable=E0611,F0401
|
||||
|
||||
# R0904: Not too many methods in unittest.
|
||||
# pylint: disable=R0904
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import struct
|
||||
|
|
|
|||
|
|
@ -2,18 +2,6 @@
|
|||
"""
|
||||
Test suite specifically targeting JP2 box layout.
|
||||
"""
|
||||
# E1103: return value from read may be list or np array
|
||||
# pylint: disable=E1103
|
||||
|
||||
# R0902: More than 7 instance attributes are just fine for testing.
|
||||
# pylint: disable=R0902
|
||||
|
||||
# R0904: Seems like pylint is fooled in this situation
|
||||
# pylint: disable=R0904
|
||||
|
||||
# W0613: load_tests doesn't need to use ignore or loader arguments.
|
||||
# pylint: disable=W0613
|
||||
|
||||
import os
|
||||
import re
|
||||
import struct
|
||||
|
|
|
|||
|
|
@ -1,15 +1,6 @@
|
|||
"""
|
||||
Tests for general glymur functionality.
|
||||
"""
|
||||
# E1101: assertWarns introduced in python 3.2
|
||||
# pylint: disable=E1101
|
||||
|
||||
# R0904: Not too many methods in unittest.
|
||||
# pylint: disable=R0904
|
||||
|
||||
# E0611: unittest.mock is unknown to python2.7/pylint
|
||||
# pylint: disable=E0611,F0401
|
||||
|
||||
import doctest
|
||||
import os
|
||||
import re
|
||||
|
|
@ -47,10 +38,6 @@ from . import fixtures
|
|||
|
||||
# Doc tests should be run as well.
|
||||
def load_tests(loader, tests, ignore):
|
||||
# W0613: "loader" and "ignore" are necessary for the protocol
|
||||
# They are unused here, however.
|
||||
# pylint: disable=W0613
|
||||
|
||||
"""Should run doc tests as well"""
|
||||
if os.name == "nt":
|
||||
# Can't do it on windows, temporary file issue.
|
||||
|
|
@ -285,6 +272,15 @@ class TestJp2k(unittest.TestCase):
|
|||
jp2 = Jp2k(jfile)
|
||||
self.assertEqual(jp2.shape, (128, 128))
|
||||
|
||||
@unittest.skipIf(OPJ_DATA_ROOT is None,
|
||||
"OPJ_DATA_ROOT environment variable not set")
|
||||
def test_invalid_compatibility_list_entry(self):
|
||||
"""should not error out with invalid compatibility list entry"""
|
||||
filename = opj_data_file('input/nonregression/issue397.jp2')
|
||||
with self.assertWarns(UserWarning):
|
||||
Jp2k(filename)
|
||||
self.assertTrue(True)
|
||||
|
||||
def test_shape_j2k(self):
|
||||
"""verify shape attribute for J2K file
|
||||
"""
|
||||
|
|
@ -1132,7 +1128,7 @@ class TestJp2kOpjDataRootWarnings(unittest.TestCase):
|
|||
@unittest.skipIf(OPJ_DATA_ROOT is None,
|
||||
"OPJ_DATA_ROOT environment variable not set")
|
||||
class TestJp2kOpjDataRoot(unittest.TestCase):
|
||||
"""These tests should be run by just about all configuration."""
|
||||
"""These tests should be run by just about all configurations."""
|
||||
|
||||
@unittest.skipIf(re.match("0|1.[0-4]", glymur.version.openjpeg_version),
|
||||
"Must have openjpeg 1.5 or higher to run")
|
||||
|
|
@ -1141,9 +1137,9 @@ class TestJp2kOpjDataRoot(unittest.TestCase):
|
|||
"""Irreversible"""
|
||||
filename = opj_data_file('input/nonregression/issue141.rawl')
|
||||
expdata = np.fromfile(filename, dtype=np.uint16)
|
||||
expdata.resize((2816, 2048))
|
||||
expdata.resize((32, 2048))
|
||||
with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile:
|
||||
j = Jp2k(tfile.name, data=expdata, irreversible=True)
|
||||
j = Jp2k(tfile.name, data=expdata, irreversible=True, numres=5)
|
||||
|
||||
codestream = j.get_codestream()
|
||||
self.assertEqual(codestream.segment[2].spcod[8],
|
||||
|
|
|
|||
|
|
@ -2,31 +2,6 @@
|
|||
The tests defined here roughly correspond to what is in the OpenJPEG test
|
||||
suite.
|
||||
"""
|
||||
|
||||
# Some test names correspond with openjpeg tests. Long names are ok in this
|
||||
# case.
|
||||
# pylint: disable=C0103
|
||||
|
||||
# All of these tests correspond to tests in openjpeg, so no docstring is really
|
||||
# needed.
|
||||
# pylint: disable=C0111
|
||||
|
||||
# This module is very long, cannot be helped.
|
||||
# pylint: disable=C0302
|
||||
|
||||
# unittest fools pylint with "too many public methods"
|
||||
# pylint: disable=R0904
|
||||
|
||||
# Some tests use numpy test infrastructure, which means the tests never
|
||||
# reference "self", so pylint claims it should be a function. No, no, no.
|
||||
# pylint: disable=R0201
|
||||
|
||||
# Many tests are pretty long and that can't be helped.
|
||||
# pylint: disable=R0915
|
||||
|
||||
# asserWarns introduced in python 3.2 (python2.7/pylint issue)
|
||||
# pylint: disable=E1101
|
||||
|
||||
import re
|
||||
import sys
|
||||
import unittest
|
||||
|
|
@ -384,11 +359,14 @@ class TestSuiteWarns(MetadataBase):
|
|||
jpdata = jp2k[:]
|
||||
self.assertEqual(jpdata.shape, (512, 768, 3))
|
||||
|
||||
def test_NR_broken_jp2_dump(self):
|
||||
jfile = opj_data_file('input/nonregression/broken.jp2')
|
||||
def test_NR_broken1_jp2_dump(self):
|
||||
jfile = opj_data_file('input/nonregression/broken1.jp2')
|
||||
|
||||
with self.assertWarns(UserWarning):
|
||||
# colr box has bad length.
|
||||
# The colr box has a ridiculously incorrect box length.
|
||||
regex = re.compile(r'''b'colr'\sbox\shas\sincorrect\sbox\slength\s
|
||||
\(\d+\)''',
|
||||
re.VERBOSE)
|
||||
with self.assertWarnsRegex(UserWarning, regex):
|
||||
jp2 = Jp2k(jfile)
|
||||
|
||||
ids = [box.box_id for box in jp2.box]
|
||||
|
|
@ -609,13 +587,16 @@ class TestSuite2point0(unittest.TestCase):
|
|||
|
||||
@unittest.skipIf(WARNING_INFRASTRUCTURE_ISSUE, WARNING_INFRASTRUCTURE_MSG)
|
||||
def test_NR_DEC_broken2_jp2_5_decode(self):
|
||||
# Null pointer access
|
||||
"""
|
||||
Invalid marker ID on codestream, Null pointer access upon read.
|
||||
"""
|
||||
jfile = opj_data_file('input/nonregression/broken2.jp2')
|
||||
regex = re.compile(r'''Invalid\smarker\sid\sencountered\sat\sbyte\s
|
||||
\d+\sin\scodestream:\s*"0x[a-fA-F0-9]{4}"''',
|
||||
re.VERBOSE)
|
||||
with self.assertRaises(IOError):
|
||||
with self.assertWarns(UserWarning):
|
||||
# Invalid marker ID.
|
||||
with self.assertWarnsRegex(UserWarning, regex):
|
||||
Jp2k(jfile)[:]
|
||||
self.assertTrue(True)
|
||||
|
||||
@unittest.skipIf(WARNING_INFRASTRUCTURE_ISSUE, WARNING_INFRASTRUCTURE_MSG)
|
||||
def test_NR_DEC_broken4_jp2_7_decode(self):
|
||||
|
|
|
|||
|
|
@ -2,33 +2,7 @@
|
|||
The tests defined here roughly correspond to what is in the OpenJPEG test
|
||||
suite.
|
||||
"""
|
||||
|
||||
# Some test names correspond with openjpeg tests. Long names are ok in this
|
||||
# case.
|
||||
# pylint: disable=C0103
|
||||
|
||||
# All of these tests correspond to tests in openjpeg, so no docstring is really
|
||||
# needed.
|
||||
# pylint: disable=C0111
|
||||
|
||||
# This module is very long, cannot be helped.
|
||||
# pylint: disable=C0302
|
||||
|
||||
# unittest fools pylint with "too many public methods"
|
||||
# pylint: disable=R0904
|
||||
|
||||
# Some tests use numpy test infrastructure, which means the tests never
|
||||
# reference "self", so pylint claims it should be a function. No, no, no.
|
||||
# pylint: disable=R0201
|
||||
|
||||
# Many tests are pretty long and that can't be helped.
|
||||
# pylint: disable=R0915
|
||||
|
||||
# asserWarns introduced in python 3.2 (python2.7/pylint issue)
|
||||
# pylint: disable=E1101
|
||||
|
||||
import re
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
|
|
@ -2944,93 +2918,6 @@ class TestSuiteWarns(MetadataBase):
|
|||
|
||||
self.assertEqual(jp2.box[-1].main_header.segment[-1].marker_id, 'QCC')
|
||||
|
||||
@unittest.skipIf(sys.maxsize < 2**32, 'Do not run on 32-bit platforms')
|
||||
def test_NR_broken3_jp2_dump(self):
|
||||
"""
|
||||
NR_broken3_jp2_dump
|
||||
|
||||
The file in question here has a colr box with an erroneous box
|
||||
length of over 1GB. Don't run it on 32-bit platforms.
|
||||
"""
|
||||
jfile = opj_data_file('input/nonregression/broken3.jp2')
|
||||
with self.assertWarns(UserWarning):
|
||||
# Bad box length.
|
||||
jp2 = Jp2k(jfile)
|
||||
|
||||
ids = [box.box_id for box in jp2.box]
|
||||
self.assertEqual(ids, ['jP ', 'ftyp', 'jp2h', 'jp2c'])
|
||||
|
||||
ids = [box.box_id for box in jp2.box[2].box]
|
||||
self.assertEqual(ids, ['ihdr', 'colr'])
|
||||
|
||||
self.verifySignatureBox(jp2.box[0])
|
||||
self.verify_filetype_box(jp2.box[1], FileTypeBox())
|
||||
|
||||
ihdr = glymur.jp2box.ImageHeaderBox(152, 203, num_components=3)
|
||||
self.verifyImageHeaderBox(jp2.box[2].box[0], ihdr)
|
||||
|
||||
colr = glymur.jp2box.ColourSpecificationBox(colorspace=SRGB)
|
||||
self.verifyColourSpecificationBox(jp2.box[2].box[1], colr)
|
||||
|
||||
c = jp2.box[3].main_header
|
||||
|
||||
ids = [x.marker_id for x in c.segment]
|
||||
expected = ['SOC', 'SIZ', 'CME', 'COD', 'QCD', 'QCC', 'QCC']
|
||||
self.assertEqual(ids, expected)
|
||||
|
||||
kwargs = {'rsiz': 0, 'xysiz': (203, 152), 'xyosiz': (0, 0),
|
||||
'xytsiz': (203, 152), 'xytosiz': (0, 0),
|
||||
'bitdepth': (8, 8, 8),
|
||||
'signed': (False, False, False),
|
||||
'xyrsiz': [(1, 1, 1), (1, 1, 1)]}
|
||||
self.verifySizSegment(c.segment[1],
|
||||
glymur.codestream.SIZsegment(**kwargs))
|
||||
|
||||
pargs = RCME_ISO_8859_1, "Creator: JasPer Vers)on 1.701.0".encode()
|
||||
self.verifyCMEsegment(c.segment[2], CMEsegment(*pargs))
|
||||
|
||||
# COD: Coding style default
|
||||
self.assertFalse(c.segment[3].scod & 2) # no sop
|
||||
self.assertFalse(c.segment[3].scod & 4) # no eph
|
||||
self.assertEqual(c.segment[3].spcod[0], glymur.core.LRCP)
|
||||
self.assertEqual(c.segment[3].layers, 1) # layers = 1
|
||||
self.assertEqual(c.segment[3].spcod[3], 1) # mct
|
||||
self.assertEqual(c.segment[3].spcod[4], 5) # level
|
||||
self.assertEqual(tuple(c.segment[3].code_block_size),
|
||||
(64, 64)) # cblk
|
||||
self.verify_codeblock_style(c.segment[3].spcod[7],
|
||||
[False, False, False, False, False, False])
|
||||
self.assertEqual(c.segment[3].spcod[8],
|
||||
glymur.core.WAVELET_XFORM_5X3_REVERSIBLE)
|
||||
self.assertEqual(len(c.segment[3].spcod), 9)
|
||||
|
||||
# QCD: Quantization default
|
||||
self.assertEqual(c.segment[4].sqcd & 0x1f, 0)
|
||||
self.assertEqual(c.segment[4].guard_bits, 2)
|
||||
self.assertEqual(c.segment[4].mantissa, [0] * 16)
|
||||
self.assertEqual(c.segment[4].exponent,
|
||||
[8] + [9, 9, 10] * 5)
|
||||
|
||||
# QCC: Quantization component
|
||||
# associated component
|
||||
self.assertEqual(c.segment[5].cqcc, 1)
|
||||
self.assertEqual(c.segment[5].guard_bits, 2)
|
||||
# quantization type
|
||||
self.assertEqual(c.segment[5].sqcc & 0x1f, 0) # none
|
||||
self.assertEqual(c.segment[5].mantissa, [0] * 16)
|
||||
self.assertEqual(c.segment[5].exponent,
|
||||
[8] + [9, 9, 10] * 5)
|
||||
|
||||
# QCC: Quantization component
|
||||
# associated component
|
||||
self.assertEqual(c.segment[6].cqcc, 2)
|
||||
self.assertEqual(c.segment[6].guard_bits, 2)
|
||||
# quantization type
|
||||
self.assertEqual(c.segment[6].sqcc & 0x1f, 0) # none
|
||||
self.assertEqual(c.segment[6].mantissa, [0] * 16)
|
||||
self.assertEqual(c.segment[6].exponent,
|
||||
[8] + [9, 9, 10] * 5)
|
||||
|
||||
def test_NR_broken2_jp2_dump(self):
|
||||
"""
|
||||
Invalid marker ID in the codestream.
|
||||
|
|
|
|||
|
|
@ -2,12 +2,6 @@
|
|||
The tests here do not correspond directly to the OpenJPEG test suite, but
|
||||
seem like logical negative tests to add.
|
||||
"""
|
||||
# E1101: assertWarns introduced in python 3.2
|
||||
# pylint: disable=E1101
|
||||
|
||||
# R0904: Not too many methods in unittest.
|
||||
# pylint: disable=R0904
|
||||
|
||||
import os
|
||||
import re
|
||||
import tempfile
|
||||
|
|
|
|||
|
|
@ -2,10 +2,6 @@
|
|||
The tests defined here roughly correspond to what is in the OpenJPEG test
|
||||
suite.
|
||||
"""
|
||||
# C0103: method names longer that 30 chars are ok in tests, IMHO
|
||||
# R0904: Seems like pylint is fooled in this situation
|
||||
# pylint: disable=R0904,C0103
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
|
|
|||
|
|
@ -1,15 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Test suite for printing.
|
||||
"""
|
||||
# C0302: don't care too much about having too many lines in a test module
|
||||
# pylint: disable=C0302
|
||||
|
||||
# E061: unittest.mock introduced in 3.3 (python-2.7/pylint issue)
|
||||
# pylint: disable=E0611,F0401
|
||||
|
||||
# R0904: Not too many methods in unittest.
|
||||
# pylint: disable=R0904
|
||||
|
||||
import os
|
||||
import re
|
||||
import struct
|
||||
|
|
@ -106,7 +97,7 @@ class TestPrinting(unittest.TestCase):
|
|||
data = glymur.Jp2k(self.jp2file)[::2, ::2]
|
||||
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile:
|
||||
with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile2:
|
||||
j = glymur.Jp2k(tfile.name, data=data)
|
||||
glymur.Jp2k(tfile.name, data=data)
|
||||
|
||||
# Offset of the codestream is where we start.
|
||||
wbuffer = tfile.read(77)
|
||||
|
|
@ -840,6 +831,17 @@ class TestPrintingOpjDataRootWarns(unittest.TestCase):
|
|||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_invalid_colour_specification_method(self):
|
||||
"""should not error out with invalid colour specification method"""
|
||||
# Don't care so much about what the output looks like, just that we
|
||||
# do not error out.
|
||||
filename = opj_data_file('input/nonregression/issue397.jp2')
|
||||
with self.assertWarns(UserWarning):
|
||||
jp2 = Jp2k(filename)
|
||||
with patch('sys.stdout', new=StringIO()):
|
||||
print(jp2)
|
||||
self.assertTrue(True)
|
||||
|
||||
def test_invalid_colorspace(self):
|
||||
"""An invalid colorspace shouldn't cause an error."""
|
||||
filename = opj_data_file('input/nonregression/edf_c2_1103421.jp2')
|
||||
|
|
@ -1062,7 +1064,8 @@ class TestJp2dump(unittest.TestCase):
|
|||
"""Verify dumping with -c 0, supressing all codestream details."""
|
||||
actual = self.run_jp2dump(['', '-c', '0', self.jp2file])
|
||||
|
||||
self.assertEqual(actual, fixtures.nemo_dump_no_codestream)
|
||||
expected = fixtures.nemo_dump_no_codestream
|
||||
self.assertEqual(actual, expected)
|
||||
|
||||
def test_codestream_1(self):
|
||||
"""Verify dumping with -c 1, print just the header."""
|
||||
|
|
|
|||
16
setup.py
16
setup.py
|
|
@ -1,4 +1,4 @@
|
|||
from setuptools import setup, find_packages
|
||||
from setuptools import setup
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
|
@ -11,18 +11,22 @@ kwargs = {'name': 'Glymur',
|
|||
'url': 'https://github.com/quintusdias/glymur',
|
||||
'packages': ['glymur', 'glymur.data', 'glymur.test', 'glymur.lib',
|
||||
'glymur.lib.test'],
|
||||
'package_data': {'glymur': ['data/*.jp2', 'data/*.j2k', 'data/*.jpx']},
|
||||
'package_data': {'glymur': ['data/*.jp2',
|
||||
'data/*.j2k',
|
||||
'data/*.jpx']},
|
||||
'entry_points': {
|
||||
'console_scripts': ['jp2dump=glymur.command_line:main'],
|
||||
},
|
||||
'license': 'MIT',
|
||||
'test_suite': 'glymur.test'}
|
||||
|
||||
instllrqrs = ['numpy>=1.4.1', 'lxml>=2.3.2']
|
||||
install_requires = ['numpy>=1.7.0', 'lxml>=3.0.0']
|
||||
test_requires = ['six>=1.7.0']
|
||||
if sys.hexversion < 0x03030000:
|
||||
instllrqrs.append('contextlib2>=0.4')
|
||||
instllrqrs.append('mock>=1.0.1')
|
||||
kwargs['install_requires'] = instllrqrs
|
||||
install_requires.append('contextlib2>=0.4')
|
||||
test_requires.append('mock>=1.0.1')
|
||||
kwargs['install_requires'] = install_requires
|
||||
kwargs['test_requires'] = test_requires
|
||||
|
||||
clssfrs = ["Programming Language :: Python",
|
||||
"Programming Language :: Python :: 2.7",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue