Merge branch 'issue254' into devel
This commit is contained in:
commit
5c083a7f53
8 changed files with 205 additions and 143 deletions
34
bin/jp2dump
34
bin/jp2dump
|
|
@ -1,34 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import glymur
|
||||
|
||||
description='Print JPEG2000 metadata.'
|
||||
parser = argparse.ArgumentParser(description=description)
|
||||
parser.add_argument('-x', '--noxml', help='Suppress XML.',
|
||||
action='store_true')
|
||||
parser.add_argument('-s', '--short', help='Only print box id, offset, and length.',
|
||||
action='store_true')
|
||||
chelp='Level of codestream information. 0 suppressed all details, 1 prints headers, 2 prints the full codestream'
|
||||
parser.add_argument('-c', '--codestream',
|
||||
help=chelp,
|
||||
nargs=1,
|
||||
type=int,
|
||||
default=[0])
|
||||
parser.add_argument('filename')
|
||||
args = parser.parse_args()
|
||||
if args.noxml:
|
||||
glymur.set_printoptions(xml=False)
|
||||
if args.short:
|
||||
glymur.set_printoptions(short=True)
|
||||
if args.codestream[0] == 0:
|
||||
glymur.set_printoptions(codestream=False)
|
||||
print_full_codestream = False
|
||||
elif args.codestream[0] == 1:
|
||||
print_full_codestream = False
|
||||
else:
|
||||
print_full_codestream = True
|
||||
|
||||
filename = args.filename
|
||||
glymur.jp2dump(args.filename, codestream=print_full_codestream)
|
||||
|
|
@ -17,7 +17,7 @@ resolution level. ::
|
|||
|
||||
... display metadata?
|
||||
=====================
|
||||
There are two ways. From the unix command line, the script **jp2dump** is
|
||||
There are two ways. From the command line, the script **jp2dump** is
|
||||
available. ::
|
||||
|
||||
$ jp2dump /path/to/glymur/installation/data/nemo.jp2
|
||||
|
|
|
|||
|
|
@ -27,10 +27,5 @@ but you should also be able to install Glymur via pip ::
|
|||
|
||||
$ pip install glymur
|
||||
|
||||
This will install a script **jp2dump** that can be used from the unix command
|
||||
line for dumping JP2 metadata, so you should adjust your **$PATH**
|
||||
environment variable to take advantage of it. For example, if you install
|
||||
with pip's `--user` option on linux ::
|
||||
|
||||
$ export PATH=$HOME/.local/bin:$PATH
|
||||
|
||||
In addition to the package, this also gives you a script **jp2dump** that can
|
||||
be used from the command line line to print JPEG 2000 metadata.
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ __version__ = version.version
|
|||
from .jp2k import Jp2k
|
||||
from .jp2dump import jp2dump
|
||||
from .jp2box import get_printoptions, set_printoptions
|
||||
from .jp2box import get_parseoptions, set_parseoptions
|
||||
|
||||
from . import data
|
||||
|
||||
|
|
|
|||
49
glymur/command_line.py
Normal file
49
glymur/command_line.py
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from . import jp2dump, set_printoptions
|
||||
|
||||
def main():
|
||||
|
||||
description='Print JPEG2000 metadata.'
|
||||
parser = argparse.ArgumentParser(description=description)
|
||||
|
||||
parser.add_argument('-x', '--noxml',
|
||||
help='Suppress XML.',
|
||||
action='store_true')
|
||||
parser.add_argument('-s', '--short',
|
||||
help='Only print box id, offset, and length.',
|
||||
action='store_true')
|
||||
|
||||
chelp = 'Level of codestream information. 0 suppressed all details, '
|
||||
chelp += '1 prints headers, 2 prints the full codestream'
|
||||
parser.add_argument('-c', '--codestream',
|
||||
help=chelp,
|
||||
nargs=1,
|
||||
type=int,
|
||||
default=[0])
|
||||
|
||||
parser.add_argument('filename')
|
||||
|
||||
args = parser.parse_args()
|
||||
if args.noxml:
|
||||
set_printoptions(xml=False)
|
||||
if args.short:
|
||||
set_printoptions(short=True)
|
||||
|
||||
codestream_level = args.codestream[0]
|
||||
if codestream_level not in [0, 1, 2]:
|
||||
raise ValueError("Invalid level of codestream information specified.")
|
||||
|
||||
if codestream_level == 0:
|
||||
set_printoptions(codestream=False)
|
||||
print_full_codestream = False
|
||||
elif codestream_level == 1:
|
||||
print_full_codestream = False
|
||||
else:
|
||||
print_full_codestream = True
|
||||
|
||||
filename = args.filename
|
||||
jp2dump(args.filename, codestream=print_full_codestream)
|
||||
|
||||
|
|
@ -455,7 +455,9 @@ Contiguous Codestream Box (jp2c) @ (3223, 1132296)
|
|||
Step size: [(0, 8), (0, 9), (0, 9), (0, 10)]
|
||||
CME marker segment @ (3305, 37)
|
||||
"Created by OpenJPEG version 2.0.0"'''
|
||||
nemo_dump_full = dump.format(_indent(nemo_xmp))
|
||||
|
||||
nemo_with_codestream_header = dump.format(_indent(nemo_xmp))
|
||||
#nemo_dump_full = dump.format(_indent(nemo_xmp))
|
||||
|
||||
nemo_dump_short = r"""JPEG 2000 Signature Box (jP ) @ (0, 12)
|
||||
File Type Box (ftyp) @ (12, 20)
|
||||
|
|
@ -651,7 +653,7 @@ number_list_box = r"""Number List Box (nlst) @ (-1, 0)
|
|||
Association[2]: compositing layer 0"""
|
||||
|
||||
|
||||
goodstuff = r"""Codestream:
|
||||
goodstuff_codestream_header = r"""Codestream:
|
||||
SOC marker segment @ (0, 0)
|
||||
SIZ marker segment @ (2, 47)
|
||||
Profile: no profile
|
||||
|
|
@ -686,3 +688,80 @@ goodstuff = r"""Codestream:
|
|||
Quantization style: no quantization, 2 guard bits
|
||||
Step size: [(0, 8), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10)]"""
|
||||
|
||||
goodstuff_with_full_header = r"""Codestream:
|
||||
SOC marker segment @ (0, 0)
|
||||
SIZ marker segment @ (2, 47)
|
||||
Profile: no profile
|
||||
Reference Grid Height, Width: (800 x 480)
|
||||
Vertical, Horizontal Reference Grid Offset: (0 x 0)
|
||||
Reference Tile Height, Width: (800 x 480)
|
||||
Vertical, Horizontal Reference Tile Offset: (0 x 0)
|
||||
Bitdepth: (8, 8, 8)
|
||||
Signed: (False, False, False)
|
||||
Vertical, Horizontal Subsampling: ((1, 1), (1, 1), (1, 1))
|
||||
COD marker segment @ (51, 12)
|
||||
Coding style:
|
||||
Entropy coder, without partitions
|
||||
SOP marker segments: False
|
||||
EPH marker segments: False
|
||||
Coding style parameters:
|
||||
Progression order: LRCP
|
||||
Number of layers: 1
|
||||
Multiple component transformation usage: reversible
|
||||
Number of resolutions: 6
|
||||
Code block height, width: (64 x 64)
|
||||
Wavelet transform: 5-3 reversible
|
||||
Precinct size: default, 2^15 x 2^15
|
||||
Code block context:
|
||||
Selective arithmetic coding bypass: False
|
||||
Reset context probabilities on coding pass boundaries: False
|
||||
Termination on each coding pass: False
|
||||
Vertically stripe causal context: False
|
||||
Predictable termination: False
|
||||
Segmentation symbols: False
|
||||
QCD marker segment @ (65, 19)
|
||||
Quantization style: no quantization, 2 guard bits
|
||||
Step size: [(0, 8), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10)]
|
||||
SOT marker segment @ (86, 10)
|
||||
Tile part index: 0
|
||||
Tile part length: 115132
|
||||
Tile part instance: 0
|
||||
Number of tile parts: 1
|
||||
COC marker segment @ (98, 9)
|
||||
Associated component: 1
|
||||
Coding style for this component: Entropy coder, PARTITION = 0
|
||||
Coding style parameters:
|
||||
Number of resolutions: 6
|
||||
Code block height, width: (64 x 64)
|
||||
Wavelet transform: 5-3 reversible
|
||||
Code block context:
|
||||
Selective arithmetic coding bypass: False
|
||||
Reset context probabilities on coding pass boundaries: False
|
||||
Termination on each coding pass: False
|
||||
Vertically stripe causal context: False
|
||||
Predictable termination: False
|
||||
Segmentation symbols: False
|
||||
QCC marker segment @ (109, 20)
|
||||
Associated Component: 1
|
||||
Quantization style: no quantization, 2 guard bits
|
||||
Step size: [(0, 8), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10)]
|
||||
COC marker segment @ (131, 9)
|
||||
Associated component: 2
|
||||
Coding style for this component: Entropy coder, PARTITION = 0
|
||||
Coding style parameters:
|
||||
Number of resolutions: 6
|
||||
Code block height, width: (64 x 64)
|
||||
Wavelet transform: 5-3 reversible
|
||||
Code block context:
|
||||
Selective arithmetic coding bypass: False
|
||||
Reset context probabilities on coding pass boundaries: False
|
||||
Termination on each coding pass: False
|
||||
Vertically stripe causal context: False
|
||||
Predictable termination: False
|
||||
Segmentation symbols: False
|
||||
QCC marker segment @ (142, 20)
|
||||
Associated Component: 2
|
||||
Quantization style: no quantization, 2 guard bits
|
||||
Step size: [(0, 8), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), (0, 10)]
|
||||
SOD marker segment @ (164, 0)
|
||||
EOC marker segment @ (115218, 0)"""
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ else:
|
|||
import lxml.etree as ET
|
||||
|
||||
import glymur
|
||||
from glymur import Jp2k
|
||||
from glymur import Jp2k, command_line
|
||||
from . import fixtures
|
||||
from .fixtures import OPJ_DATA_ROOT, opj_data_file
|
||||
from .fixtures import text_gbr_27, text_gbr_33, text_gbr_34
|
||||
|
|
@ -107,74 +107,6 @@ class TestPrinting(unittest.TestCase):
|
|||
with self.assertRaises(TypeError):
|
||||
glymur.set_printoptions(hi='low')
|
||||
|
||||
def test_propts_no_codestream_then_no_xml(self):
|
||||
"""Verify printed output when codestream=False and xml=False, #162"""
|
||||
# The print options should be persistent across invocations.
|
||||
glymur.set_printoptions(codestream=False)
|
||||
glymur.set_printoptions(xml=False)
|
||||
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||
glymur.jp2dump(self.jp2file)
|
||||
actual = fake_out.getvalue().strip()
|
||||
|
||||
# Get rid of the filename line, as it is not set in stone.
|
||||
lst = actual.split('\n')
|
||||
lst = lst[1:]
|
||||
actual = '\n'.join(lst)
|
||||
self.assertEqual(actual, fixtures.nemo_dump_no_codestream_no_xml)
|
||||
|
||||
def test_printopt_no_codestr_or_xml(self):
|
||||
"""Verify printed output when codestream=False and xml=False"""
|
||||
glymur.set_printoptions(codestream=False, xml=False)
|
||||
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||
glymur.jp2dump(self.jp2file)
|
||||
actual = fake_out.getvalue().strip()
|
||||
|
||||
# Get rid of the filename line, as it is not set in stone.
|
||||
lst = actual.split('\n')
|
||||
lst = lst[1:]
|
||||
actual = '\n'.join(lst)
|
||||
self.assertEqual(actual, fixtures.nemo_dump_no_codestream_no_xml)
|
||||
|
||||
def test_printoptions_no_codestream(self):
|
||||
"""Verify printed output when codestream=False"""
|
||||
glymur.set_printoptions(codestream=False)
|
||||
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||
glymur.jp2dump(self.jp2file)
|
||||
actual = fake_out.getvalue().strip()
|
||||
|
||||
# Get rid of the filename line, as it is not set in stone.
|
||||
lst = actual.split('\n')
|
||||
lst = lst[1:]
|
||||
actual = '\n'.join(lst)
|
||||
self.assertEqual(actual, fixtures.nemo_dump_no_codestream)
|
||||
|
||||
def test_printoptions_no_xml(self):
|
||||
"""Verify printed output when xml=False"""
|
||||
glymur.set_printoptions(xml=False)
|
||||
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||
glymur.jp2dump(self.jp2file)
|
||||
actual = fake_out.getvalue().strip()
|
||||
|
||||
# Get rid of the filename line, as it is not set in stone.
|
||||
lst = actual.split('\n')
|
||||
lst = lst[1:]
|
||||
actual = '\n'.join(lst)
|
||||
expected = fixtures.nemo_dump_no_xml
|
||||
self.assertEqual(actual, expected)
|
||||
|
||||
def test_printoptions_short(self):
|
||||
"""Verify printed output when short=True"""
|
||||
glymur.set_printoptions(short=True)
|
||||
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||
glymur.jp2dump(self.jp2file)
|
||||
actual = fake_out.getvalue().strip()
|
||||
|
||||
# Get rid of the filename line, as it is not set in stone.
|
||||
lst = actual.split('\n')
|
||||
lst = lst[1:]
|
||||
actual = '\n'.join(lst)
|
||||
self.assertEqual(actual, fixtures.nemo_dump_short)
|
||||
|
||||
def test_asoc_label_box(self):
|
||||
"""verify printing of asoc, label boxes"""
|
||||
# Construct a fake file with an asoc and a label box, as
|
||||
|
|
@ -228,32 +160,6 @@ class TestPrinting(unittest.TestCase):
|
|||
expected = '\n'.join(lines)
|
||||
self.assertEqual(actual, expected)
|
||||
|
||||
def test_jp2dump(self):
|
||||
"""basic jp2dump test"""
|
||||
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||
glymur.jp2dump(self.jp2file)
|
||||
actual = fake_out.getvalue().strip()
|
||||
|
||||
# Get rid of the filename line, as it is not set in stone.
|
||||
lst = actual.split('\n')
|
||||
lst = lst[1:]
|
||||
actual = '\n'.join(lst)
|
||||
self.assertEqual(actual, fixtures.nemo_dump_full)
|
||||
|
||||
def test_entire_file(self):
|
||||
"""verify output from printing entire file"""
|
||||
j = glymur.Jp2k(self.jp2file)
|
||||
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||
print(j)
|
||||
actual = fake_out.getvalue().strip()
|
||||
|
||||
# Get rid of the filename line, as it is not set in stone.
|
||||
lst = actual.split('\n')
|
||||
lst = lst[1:]
|
||||
actual = '\n'.join(lst)
|
||||
|
||||
self.assertEqual(actual, fixtures.nemo_dump_full)
|
||||
|
||||
def test_coc_segment(self):
|
||||
"""verify printing of COC segment"""
|
||||
j = glymur.Jp2k(self.jp2file)
|
||||
|
|
@ -1113,5 +1019,71 @@ class TestPrintingOpjDataRoot(unittest.TestCase):
|
|||
|
||||
self.assertTrue(True)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
class TestJp2dump(unittest.TestCase):
|
||||
"""Tests for verifying how jp2dump console script works."""
|
||||
def setUp(self):
|
||||
self.jpxfile = glymur.data.jpxfile()
|
||||
self.jp2file = glymur.data.nemo()
|
||||
self.j2kfile = glymur.data.goodstuff()
|
||||
|
||||
# Reset printoptions for every test.
|
||||
glymur.set_printoptions(short=False, xml=True, codestream=True)
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def run_jp2dump(self, args):
|
||||
sys.argv = args
|
||||
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||
command_line.main()
|
||||
actual = fake_out.getvalue().strip()
|
||||
# Remove the file line, as that is filesystem-dependent.
|
||||
lines = actual.split('\n')
|
||||
actual = '\n'.join(lines[1:])
|
||||
return actual
|
||||
|
||||
def test_default_nemo(self):
|
||||
"""Should be able to dump a JP2 file's metadata with no codestream."""
|
||||
actual = self.run_jp2dump(['', self.jp2file])
|
||||
|
||||
self.assertEqual(actual, fixtures.nemo_dump_no_codestream)
|
||||
|
||||
def test_codestream_0(self):
|
||||
"""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)
|
||||
|
||||
def test_codestream_1(self):
|
||||
"""Verify dumping with -c 1, print just the header."""
|
||||
actual = self.run_jp2dump(['', '-c', '1', self.jp2file])
|
||||
|
||||
self.assertEqual(actual, fixtures.nemo_with_codestream_header)
|
||||
|
||||
def test_codestream_2(self):
|
||||
"""Verify dumping with -c 2, full details."""
|
||||
with patch('sys.stdout', new=StringIO()) as fake_out:
|
||||
sys.argv = ['', '-c', '2', self.j2kfile]
|
||||
command_line.main()
|
||||
actual = fake_out.getvalue().strip()
|
||||
|
||||
self.assertIn(fixtures.goodstuff_with_full_header, actual)
|
||||
|
||||
def test_codestream_invalid(self):
|
||||
"""Verify dumping with -c 3, not allowd."""
|
||||
with self.assertRaises(ValueError):
|
||||
sys.argv = ['', '-c', '3', self.jp2file]
|
||||
command_line.main()
|
||||
|
||||
def test_short(self):
|
||||
"""Verify dumping with -s, short option."""
|
||||
actual = self.run_jp2dump(['', '-s', self.jp2file])
|
||||
|
||||
self.assertEqual(actual, fixtures.nemo_dump_short)
|
||||
|
||||
def test_suppress_xml(self):
|
||||
"""Verify dumping with -x, suppress XML."""
|
||||
actual = self.run_jp2dump(['', '-x', self.jp2file])
|
||||
|
||||
self.assertEqual(actual, fixtures.nemo_dump_no_codestream_no_xml)
|
||||
|
|
|
|||
4
setup.py
4
setup.py
|
|
@ -12,7 +12,9 @@ kwargs = {'name': 'glymur',
|
|||
'packages': ['glymur', 'glymur.data', 'glymur.test', 'glymur.lib',
|
||||
'glymur.lib.test'],
|
||||
'package_data': {'glymur': ['data/*.jp2', 'data/*.j2k', 'data/*.jpx']},
|
||||
'scripts': ['bin/jp2dump'],
|
||||
'entry_points': {
|
||||
'console_scripts': ['jp2dump=glymur.command_line:main'],
|
||||
},
|
||||
'license': 'MIT',
|
||||
'test_suite': 'glymur.test'}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue