Releasing 0.5.12.
Fix a few documentation warts. Added changelog into RST documentation. Restored glymur.lib.openjp2.*_v3 functions removed in 0.5.11
This commit is contained in:
parent
5936706f0e
commit
f37da173e3
11 changed files with 578 additions and 26 deletions
|
|
@ -1,3 +1,5 @@
|
|||
May 18, 2014 - v0.5.12 Restored _v3 functions removed in 0.5.11
|
||||
|
||||
May 09, 2014 - v0.5.11 Added support for Python 3.4, OpenJPEG 2.0.1, and
|
||||
OpenJPEG 2.1.0.
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ copyright = u'2013, John Evans'
|
|||
# The short X.Y version.
|
||||
version = '0.5'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.5.11'
|
||||
release = '0.5.12'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
|
|
|||
|
|
@ -1,20 +1,21 @@
|
|||
----------------------------------
|
||||
Advanced Installation Instructions
|
||||
----------------------------------
|
||||
Most users won't need to read this! You've been warned...
|
||||
|
||||
''''''''''''''''''''''
|
||||
Glymur Configuration
|
||||
''''''''''''''''''''''
|
||||
|
||||
The default glymur installation process relies upon OpenJPEG being
|
||||
properly installed on your system as a shared library. You need
|
||||
at least version 1.5 in order to read and write JPEG 2000 files.
|
||||
properly installed on your system as a shared library. If you have OpenJPEG
|
||||
installed through your system's package manager on linux or if you use MacPorts
|
||||
on the mac, you are probably already set to go. But if you have OpenJPEG
|
||||
installed into a non-standard place or if you use windows, then read on.
|
||||
|
||||
Glymur uses ctypes to access the openjp2/openjpeg libraries, and
|
||||
because ctypes accesses libraries in a platform-dependent manner,
|
||||
it is recommended that if you compile and install OpenJPEG into a
|
||||
non-standard location, you should create a configuration file to
|
||||
non-standard location, you should then create a configuration file to
|
||||
help Glymur properly find the openjpeg or openjp2 libraries (linux
|
||||
users or macports users don't need to bother with this if you are
|
||||
using OpenJPEG as provided by your package manager). The configuration
|
||||
|
|
|
|||
|
|
@ -68,10 +68,11 @@ The **append** method can add an XML box as shown below::
|
|||
|
||||
... add metadata in a more general fashion?
|
||||
===========================================
|
||||
An existing raw codestream (or JP2 file) can be wrapped (re-wrapped) in a
|
||||
user-defined set of JP2 boxes. To get just a minimal JP2 jacket on the
|
||||
codestream provided by `goodstuff.j2k` (a file consisting of a raw codestream),
|
||||
you can use the **wrap** method with no box argument: ::
|
||||
An existing raw codestream or JP2 file can be wrapped (re-wrapped in the case
|
||||
of JP2) in a user-defined set of JP2 boxes. To get just a minimal
|
||||
JP2 jacket on the codestream provided by `goodstuff.j2k` (a file
|
||||
consisting of just a raw codestream), you can use the **wrap** method
|
||||
with no box argument: ::
|
||||
|
||||
>>> import glymur
|
||||
>>> jfile = glymur.data.goodstuff()
|
||||
|
|
@ -106,10 +107,12 @@ layer (the signature, file type, JP2 header, and contiguous codestream), with
|
|||
two additional boxes (image header and color specification) contained in the
|
||||
JP2 header superbox.
|
||||
|
||||
XML boxes are not in the minimal set of box requirements for the JP2 format, so
|
||||
in order to add an XML box into the mix before the codestream box, we'll need to
|
||||
re-specify all of the boxes. If you already have a JP2 jacket in place, you can just reuse that,
|
||||
though. Take the following example content in an XML file `favorites.xml` : ::
|
||||
XML boxes are not in the minimal set of box requirements for the
|
||||
JP2 format, so in order to add an XML box into the mix before the
|
||||
codestream box, we'll need to re-specify all of the boxes. If you
|
||||
already have a JP2 jacket in place, you can just reuse that, though.
|
||||
Take the following example content in an XML file `favorites.xml`
|
||||
: ::
|
||||
|
||||
<?xml version="1.0"?>
|
||||
<favorite_things>
|
||||
|
|
@ -219,8 +222,8 @@ Here's how the Preview application on the mac shows the RGBA image.
|
|||
.. image:: goodstuff_alpha.png
|
||||
|
||||
|
||||
work with XMP UUIDs?
|
||||
====================
|
||||
... work with XMP UUIDs?
|
||||
========================
|
||||
The example JP2 file shipped with glymur has an XMP UUID. ::
|
||||
|
||||
>>> import glymur
|
||||
|
|
|
|||
|
|
@ -15,8 +15,10 @@ Contents:
|
|||
introduction
|
||||
detailed_installation
|
||||
how_do_i
|
||||
roadmap
|
||||
api
|
||||
roadmap
|
||||
whatsnew/index
|
||||
|
||||
|
||||
------------------
|
||||
Indices and tables
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ Glymur: a Python interface for JPEG 2000
|
|||
----------------------------------------
|
||||
|
||||
**Glymur** is an interface to the OpenJPEG library
|
||||
which allows one to read and write JPEG 2000 files from within Python.
|
||||
which allows one to read and write JPEG 2000 files from Python.
|
||||
Glymur supports both reading and writing of JPEG 2000 images, but writing
|
||||
JPEG 2000 images is currently limited to images that can fit in memory
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ Glymur works on Python 2.6, 2.7, 3.3, and 3.4.
|
|||
OpenJPEG Installation
|
||||
=====================
|
||||
Glymur will read JPEG 2000 images with versions 1.3, 1.4, 1.5, 2.0, and 2.1 of
|
||||
OpenJPEG. Writing images is only supported with the 1.5 or better, however,
|
||||
OpenJPEG. Writing images is only supported with OpenJPEG 1.5 or better, however,
|
||||
and version 2.1 is strongly recommended. For more information about OpenJPEG,
|
||||
please consult http://www.openjpeg.org.
|
||||
|
||||
|
|
|
|||
50
docs/source/whatsnew/0.5.rst
Normal file
50
docs/source/whatsnew/0.5.rst
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
=====================
|
||||
Changes in glymur 0.5
|
||||
=====================
|
||||
|
||||
Changes in 0.5.12
|
||||
=================
|
||||
|
||||
* Minor documentation fixes for grammar and style.
|
||||
* The functions removed in 0.5.11 due to API changes in OpenJPEG 2.1.0 were
|
||||
restored for backwards compatibility. They are deprecated, though, and will
|
||||
be removed in 0.6.0.
|
||||
|
||||
* ``glymur.lib.openjp2.stream_create_default_file_stream_v3``
|
||||
* ``glymur.lib.openjp2.opj.stream_destroy_v3``
|
||||
|
||||
|
||||
Changes in 0.5.11
|
||||
=================
|
||||
|
||||
* Added support for Python 3.4.
|
||||
* OpenJPEG 1.5.2 and 2.0.1 are officially supported.
|
||||
* OpenJPEG 2.1.0 is officially supported, but the ABI changes introduced by
|
||||
OpenJPEG 2.1.0 required corresponding changes to glymur's ctypes interface.
|
||||
The functions
|
||||
|
||||
* ``glymur.lib.openjp2.stream_create_default_file_stream_v3``
|
||||
* ``glymur.lib.openjp2.opj.stream_destroy_v3``
|
||||
|
||||
functions were renamed to
|
||||
|
||||
* ``glymur.lib.openjp2.stream_create_default_file_stream``
|
||||
* ``glymur.lib.openjp2.opj.stream_destroy``
|
||||
|
||||
in order to follow OpenJPEG's upstream changes. Unless you were using the
|
||||
svn version of OpenJPEG, you should not be affected by this.
|
||||
|
||||
|
||||
Changes in 0.5.10
|
||||
=================
|
||||
|
||||
* Fixed bad warning issued when an unsupported reader requirement box mask
|
||||
length was encountered.
|
||||
|
||||
Changes in 0.5.9
|
||||
================
|
||||
|
||||
* Fixed bad library load on linux as a result of botched 0.5.8 release.
|
||||
This release was primarily aimed at supporting SunPy.
|
||||
|
||||
|
||||
11
docs/source/whatsnew/index.rst
Normal file
11
docs/source/whatsnew/index.rst
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
.. _whatsnew:
|
||||
|
||||
**********************
|
||||
"What's new" documents
|
||||
**********************
|
||||
|
||||
These document the changes between minor (or major) versions of glymur.
|
||||
|
||||
.. toctree::
|
||||
|
||||
0.5
|
||||
|
|
@ -1293,7 +1293,7 @@ def start_compress(codec, image, stream):
|
|||
|
||||
|
||||
def _stream_create_default_file_stream_2p0(fptr, isa_read_stream):
|
||||
"""Wraps openjp2 library function opj_stream_create_default_vile_stream.
|
||||
"""Wraps openjp2 library function opj_stream_create_default_file_stream.
|
||||
|
||||
Sets the stream to be a file stream.
|
||||
|
||||
|
|
@ -1318,7 +1318,7 @@ def _stream_create_default_file_stream_2p0(fptr, isa_read_stream):
|
|||
|
||||
|
||||
def _stream_create_default_file_stream_2p1(fname, isa_read_stream):
|
||||
"""Wraps openjp2 library function opj_stream_create_default_vile_stream.
|
||||
"""Wraps openjp2 library function opj_stream_create_default_file_stream.
|
||||
|
||||
Sets the stream to be a file stream.
|
||||
|
||||
|
|
@ -1343,11 +1343,6 @@ def _stream_create_default_file_stream_2p1(fname, isa_read_stream):
|
|||
read_stream)
|
||||
return stream
|
||||
|
||||
if re.match(r'''2.0''', version()):
|
||||
stream_create_default_file_stream = _stream_create_default_file_stream_2p0
|
||||
else:
|
||||
stream_create_default_file_stream = _stream_create_default_file_stream_2p1
|
||||
|
||||
def stream_destroy(stream):
|
||||
"""Wraps openjp2 library function opj_stream_destroy.
|
||||
|
||||
|
|
@ -1362,6 +1357,51 @@ def stream_destroy(stream):
|
|||
OPENJP2.opj_stream_destroy.restype = ctypes.c_void_p
|
||||
OPENJP2.opj_stream_destroy(stream)
|
||||
|
||||
if re.match(r'''2.0''', version()):
|
||||
# We must have the 2.0.x
|
||||
stream_create_default_file_stream = _stream_create_default_file_stream_2p0
|
||||
else:
|
||||
# We must have version 2.1.
|
||||
stream_create_default_file_stream = _stream_create_default_file_stream_2p1
|
||||
|
||||
# The _v3 functions existed only in the SVN version of OpenJPEG, before 2.1.0
|
||||
# was released
|
||||
stream_create_default_file_stream_v3 = _stream_create_default_file_stream_2p1
|
||||
stream_create_default_file_stream_v3.__doc__ = r"""
|
||||
Wraps openjp2 library function opj_stream_create_default_file_stream_v3.
|
||||
|
||||
Sets the stream to be a file stream.
|
||||
|
||||
This function is deprecated and will be removed in the 0.6.0 version of
|
||||
glymur. Please use stream_create_default_file_stream instead.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
fname : str
|
||||
Specifies a file.
|
||||
isa_read_stream: bool
|
||||
True (read) or False (write)
|
||||
|
||||
Returns
|
||||
-------
|
||||
stream : stream_t
|
||||
An OpenJPEG file stream.
|
||||
"""
|
||||
|
||||
stream_destroy_v3 = stream_destroy
|
||||
stream_destroy_v3.__doc__ = r"""
|
||||
Wraps openjp2 library function opj_stream_destroy.
|
||||
|
||||
Destroys the stream created by create_stream.
|
||||
|
||||
This function is deprecated and wil be removed in the 0.6.0 version of
|
||||
glymur. Please use stream_destroy instead.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
stream : STREAM_TYPE_P
|
||||
The file stream.
|
||||
"""
|
||||
|
||||
def write_tile(codec, tile_index, data, data_size, stream):
|
||||
"""Wraps openjp2 library function opj_write_tile.
|
||||
|
|
|
|||
443
glymur/lib/test/test_openjp2_svn.py
Normal file
443
glymur/lib/test/test_openjp2_svn.py
Normal file
|
|
@ -0,0 +1,443 @@
|
|||
"""
|
||||
Tests for functions that wrap SVN version of libopenjp2 (before release of
|
||||
2.1.0)
|
||||
"""
|
||||
# R0904: Seems like pylint is fooled in this situation
|
||||
# W0142: using kwargs is ok in this context
|
||||
# pylint: disable=R0904,W0142
|
||||
|
||||
# unittest2 is python-2.6 only (pylint/python-2.7)
|
||||
# pylint: disable=F0401
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
if sys.hexversion < 0x02070000:
|
||||
import unittest2 as unittest
|
||||
else:
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
|
||||
import glymur
|
||||
from glymur.lib import openjp2
|
||||
|
||||
if re.match("2.0", glymur.version.openjpeg_version):
|
||||
OPENJP2_IS_V2_OFFICIAL = True
|
||||
else:
|
||||
OPENJP2_IS_V2_OFFICIAL = False
|
||||
|
||||
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
|
||||
@unittest.skipIf(openjp2.OPENJP2 is None,
|
||||
"Missing openjp2 library.")
|
||||
@unittest.skipIf(OPENJP2_IS_V2_OFFICIAL, "API followed here specific to V2.1")
|
||||
class TestOpenJP2(unittest.TestCase):
|
||||
"""Test openjp2 library functionality.
|
||||
|
||||
Some tests correspond to those in the openjpeg test suite.
|
||||
"""
|
||||
|
||||
def test_default_encoder_parameters(self):
|
||||
"""Ensure that the encoder structure is clean upon init."""
|
||||
cparams = openjp2.set_default_encoder_parameters()
|
||||
|
||||
self.assertEqual(cparams.res_spec, 0)
|
||||
self.assertEqual(cparams.cblockw_init, 64)
|
||||
self.assertEqual(cparams.cblockh_init, 64)
|
||||
self.assertEqual(cparams.numresolution, 6)
|
||||
self.assertEqual(cparams.subsampling_dx, 1)
|
||||
self.assertEqual(cparams.subsampling_dy, 1)
|
||||
self.assertEqual(cparams.mode, 0)
|
||||
self.assertEqual(cparams.prog_order, glymur.core.LRCP)
|
||||
self.assertEqual(cparams.roi_shift, 0)
|
||||
self.assertEqual(cparams.cp_tx0, 0)
|
||||
self.assertEqual(cparams.cp_ty0, 0)
|
||||
|
||||
self.assertEqual(cparams.irreversible, 0)
|
||||
|
||||
def test_default_decoder_parameters(self):
|
||||
"""Tests that the structure is clean upon initialization"""
|
||||
dparams = openjp2.set_default_decoder_parameters()
|
||||
|
||||
self.assertEqual(dparams.DA_x0, 0)
|
||||
self.assertEqual(dparams.DA_y0, 0)
|
||||
self.assertEqual(dparams.DA_x1, 0)
|
||||
self.assertEqual(dparams.DA_y1, 0)
|
||||
|
||||
def tile_macro(self, codec, stream, imagep, tidx):
|
||||
"""called only by j2k_random_tile_access"""
|
||||
openjp2.get_decoded_tile(codec, stream, imagep, tidx)
|
||||
for j in range(imagep.contents.numcomps):
|
||||
self.assertIsNotNone(imagep.contents.comps[j].data)
|
||||
|
||||
def j2k_random_tile_access(self, filename, codec_format=None):
|
||||
"""fixture called by the test_rtaX methods"""
|
||||
dparam = openjp2.set_default_decoder_parameters()
|
||||
|
||||
infile = filename.encode()
|
||||
nelts = openjp2.PATH_LEN - len(infile)
|
||||
infile += b'0' * nelts
|
||||
dparam.infile = infile
|
||||
|
||||
dparam.decod_format = codec_format
|
||||
|
||||
codec = openjp2.create_decompress(codec_format)
|
||||
|
||||
openjp2.set_info_handler(codec, None)
|
||||
openjp2.set_warning_handler(codec, None)
|
||||
openjp2.set_error_handler(codec, None)
|
||||
|
||||
stream = openjp2.stream_create_default_file_stream_v3(filename, True)
|
||||
|
||||
openjp2.setup_decoder(codec, dparam)
|
||||
image = openjp2.read_header(stream, codec)
|
||||
|
||||
cstr_info = openjp2.get_cstr_info(codec)
|
||||
|
||||
tile_ul = 0
|
||||
tile_ur = cstr_info.contents.tw - 1
|
||||
tile_lr = cstr_info.contents.tw * cstr_info.contents.th - 1
|
||||
tile_ll = tile_lr - cstr_info.contents.tw
|
||||
|
||||
self.tile_macro(codec, stream, image, tile_ul)
|
||||
self.tile_macro(codec, stream, image, tile_ur)
|
||||
self.tile_macro(codec, stream, image, tile_lr)
|
||||
self.tile_macro(codec, stream, image, tile_ll)
|
||||
|
||||
openjp2.destroy_cstr_info(cstr_info)
|
||||
|
||||
openjp2.end_decompress(codec, stream)
|
||||
openjp2.destroy_codec(codec)
|
||||
openjp2.stream_destroy_v3(stream)
|
||||
openjp2.image_destroy(image)
|
||||
|
||||
def test_tte0(self):
|
||||
"""Runs test designated tte0 in OpenJPEG test suite."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
||||
ttx0_setup(tfile.name)
|
||||
self.assertTrue(True)
|
||||
|
||||
def test_ttd0(self):
|
||||
"""Runs test designated ttd0 in OpenJPEG test suite."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
||||
|
||||
# Produce the tte0 output file for ttd0 input.
|
||||
ttx0_setup(tfile.name)
|
||||
|
||||
kwargs = {'x0': 0,
|
||||
'y0': 0,
|
||||
'x1': 1000,
|
||||
'y1': 1000,
|
||||
'filename': tfile.name,
|
||||
'codec_format': openjp2.CODEC_J2K}
|
||||
tile_decoder(**kwargs)
|
||||
self.assertTrue(True)
|
||||
|
||||
def xtx1_setup(self, filename):
|
||||
"""Runs tests tte1, rta1."""
|
||||
kwargs = {'filename': filename,
|
||||
'codec': openjp2.CODEC_J2K,
|
||||
'comp_prec': 8,
|
||||
'irreversible': 1,
|
||||
'num_comps': 3,
|
||||
'image_height': 256,
|
||||
'image_width': 256,
|
||||
'tile_height': 128,
|
||||
'tile_width': 128}
|
||||
tile_encoder(**kwargs)
|
||||
self.assertTrue(True)
|
||||
|
||||
def test_tte1(self):
|
||||
"""Runs test designated tte1 in OpenJPEG test suite."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
||||
self.xtx1_setup(tfile.name)
|
||||
|
||||
def test_ttd1(self):
|
||||
"""Runs test designated ttd1 in OpenJPEG test suite."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
||||
|
||||
# Produce the tte0 output file for ttd0 input.
|
||||
self.xtx1_setup(tfile.name)
|
||||
|
||||
kwargs = {'x0': 0,
|
||||
'y0': 0,
|
||||
'x1': 128,
|
||||
'y1': 128,
|
||||
'filename': tfile.name,
|
||||
'codec_format': openjp2.CODEC_J2K}
|
||||
tile_decoder(**kwargs)
|
||||
self.assertTrue(True)
|
||||
|
||||
def test_rta1(self):
|
||||
"""Runs test designated rta1 in OpenJPEG test suite."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
||||
self.xtx1_setup(tfile.name)
|
||||
|
||||
codec_format = openjp2.CODEC_J2K
|
||||
self.j2k_random_tile_access(tfile.name, codec_format)
|
||||
self.assertTrue(True)
|
||||
|
||||
def test_tte2(self):
|
||||
"""Runs test designated tte2 in OpenJPEG test suite."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
|
||||
xtx2_setup(tfile.name)
|
||||
self.assertTrue(True)
|
||||
|
||||
def test_ttd2(self):
|
||||
"""Runs test designated ttd2 in OpenJPEG test suite."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
|
||||
# Produce the tte0 output file for ttd0 input.
|
||||
xtx2_setup(tfile.name)
|
||||
|
||||
kwargs = {'x0': 0,
|
||||
'y0': 0,
|
||||
'x1': 128,
|
||||
'y1': 128,
|
||||
'filename': tfile.name,
|
||||
'codec_format': openjp2.CODEC_JP2}
|
||||
tile_decoder(**kwargs)
|
||||
self.assertTrue(True)
|
||||
|
||||
def test_rta2(self):
|
||||
"""Runs test designated rta2 in OpenJPEG test suite."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile:
|
||||
xtx2_setup(tfile.name)
|
||||
|
||||
codec_format = openjp2.CODEC_JP2
|
||||
self.j2k_random_tile_access(tfile.name, codec_format)
|
||||
|
||||
def test_tte3(self):
|
||||
"""Runs test designated tte3 in OpenJPEG test suite."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
||||
xtx3_setup(tfile.name)
|
||||
self.assertTrue(True)
|
||||
|
||||
def test_rta3(self):
|
||||
"""Runs test designated rta3 in OpenJPEG test suite."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
||||
xtx3_setup(tfile.name)
|
||||
|
||||
codec_format = openjp2.CODEC_J2K
|
||||
self.j2k_random_tile_access(tfile.name, codec_format)
|
||||
self.assertTrue(True)
|
||||
|
||||
def test_tte4(self):
|
||||
"""Runs test designated tte4 in OpenJPEG test suite."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
||||
xtx4_setup(tfile.name)
|
||||
self.assertTrue(True)
|
||||
|
||||
def test_rta4(self):
|
||||
"""Runs test designated rta4 in OpenJPEG test suite."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
||||
xtx4_setup(tfile.name)
|
||||
|
||||
codec_format = openjp2.CODEC_J2K
|
||||
self.j2k_random_tile_access(tfile.name, codec_format)
|
||||
|
||||
def test_tte5(self):
|
||||
"""Runs test designated tte5 in OpenJPEG test suite."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
||||
xtx5_setup(tfile.name)
|
||||
self.assertTrue(True)
|
||||
|
||||
def test_rta5(self):
|
||||
"""Runs test designated rta5 in OpenJPEG test suite."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
||||
xtx5_setup(tfile.name)
|
||||
|
||||
codec_format = openjp2.CODEC_J2K
|
||||
self.j2k_random_tile_access(tfile.name, codec_format)
|
||||
|
||||
|
||||
#def tile_encoder(num_comps=None, tile_width=None, tile_height=None,
|
||||
# filename=None, codec=None, comp_prec=None,
|
||||
# image_width=None, image_height=None,
|
||||
# irreversible=None):
|
||||
def tile_encoder(**kwargs):
|
||||
"""Fixture used by many tests."""
|
||||
num_tiles = ((kwargs['image_width'] / kwargs['tile_width']) *
|
||||
(kwargs['image_height'] / kwargs['tile_height']))
|
||||
tile_size = ((kwargs['tile_width'] * kwargs['tile_height']) *
|
||||
(kwargs['num_comps'] * kwargs['comp_prec'] / 8))
|
||||
|
||||
data = np.random.random((kwargs['tile_height'],
|
||||
kwargs['tile_width'],
|
||||
kwargs['num_comps']))
|
||||
data = (data * 255).astype(np.uint8)
|
||||
|
||||
l_param = openjp2.set_default_encoder_parameters()
|
||||
|
||||
l_param.tcp_numlayers = 1
|
||||
l_param.cp_fixed_quality = 1
|
||||
l_param.tcp_distoratio[0] = 20
|
||||
|
||||
# position of the tile grid aligned with the image
|
||||
l_param.cp_tx0 = 0
|
||||
l_param.cp_ty0 = 0
|
||||
|
||||
# tile size, we are using tile based encoding
|
||||
l_param.tile_size_on = 1
|
||||
l_param.cp_tdx = kwargs['tile_width']
|
||||
l_param.cp_tdy = kwargs['tile_height']
|
||||
|
||||
# use irreversible encoding
|
||||
l_param.irreversible = kwargs['irreversible']
|
||||
|
||||
l_param.numresolution = 6
|
||||
|
||||
l_param.prog_order = glymur.core.LRCP
|
||||
|
||||
l_params = (openjp2.ImageComptParmType * kwargs['num_comps'])()
|
||||
for j in range(kwargs['num_comps']):
|
||||
l_params[j].dx = 1
|
||||
l_params[j].dy = 1
|
||||
l_params[j].h = kwargs['image_height']
|
||||
l_params[j].w = kwargs['image_width']
|
||||
l_params[j].sgnd = 0
|
||||
l_params[j].prec = kwargs['comp_prec']
|
||||
l_params[j].x0 = 0
|
||||
l_params[j].y0 = 0
|
||||
|
||||
codec = openjp2.create_compress(kwargs['codec'])
|
||||
|
||||
openjp2.set_info_handler(codec, None)
|
||||
openjp2.set_warning_handler(codec, None)
|
||||
openjp2.set_error_handler(codec, None)
|
||||
|
||||
cspace = openjp2.CLRSPC_SRGB
|
||||
l_image = openjp2.image_tile_create(l_params, cspace)
|
||||
|
||||
l_image.contents.x0 = 0
|
||||
l_image.contents.y0 = 0
|
||||
l_image.contents.x1 = kwargs['image_width']
|
||||
l_image.contents.y1 = kwargs['image_height']
|
||||
l_image.contents.color_space = openjp2.CLRSPC_SRGB
|
||||
|
||||
openjp2.setup_encoder(codec, l_param, l_image)
|
||||
|
||||
stream = openjp2.stream_create_default_file_stream_v3(kwargs['filename'],
|
||||
False)
|
||||
openjp2.start_compress(codec, l_image, stream)
|
||||
|
||||
for j in np.arange(num_tiles):
|
||||
openjp2.write_tile(codec, j, data, tile_size, stream)
|
||||
|
||||
openjp2.end_compress(codec, stream)
|
||||
openjp2.stream_destroy_v3(stream)
|
||||
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_v3(kwargs['filename'],
|
||||
True)
|
||||
dparam = openjp2.set_default_decoder_parameters()
|
||||
|
||||
dparam.decod_format = kwargs['codec_format']
|
||||
|
||||
# Do not use layer decoding limitation.
|
||||
dparam.cp_layer = 0
|
||||
|
||||
# do not use resolution reductions.
|
||||
dparam.cp_reduce = 0
|
||||
|
||||
codec = openjp2.create_decompress(kwargs['codec_format'])
|
||||
|
||||
openjp2.set_info_handler(codec, None)
|
||||
openjp2.set_warning_handler(codec, None)
|
||||
openjp2.set_error_handler(codec, None)
|
||||
|
||||
openjp2.setup_decoder(codec, dparam)
|
||||
image = openjp2.read_header(stream, codec)
|
||||
openjp2.set_decode_area(codec, image,
|
||||
kwargs['x0'], kwargs['y0'],
|
||||
kwargs['x1'], kwargs['y1'])
|
||||
|
||||
data = np.zeros((1150, 2048, 3), dtype=np.uint8)
|
||||
while True:
|
||||
rargs = openjp2.read_tile_header(codec, stream)
|
||||
tidx = rargs[0]
|
||||
size = rargs[1]
|
||||
go_on = rargs[-1]
|
||||
if not go_on:
|
||||
break
|
||||
openjp2.decode_tile_data(codec, tidx, data, size, stream)
|
||||
|
||||
openjp2.end_decompress(codec, stream)
|
||||
openjp2.destroy_codec(codec)
|
||||
openjp2.stream_destroy_v3(stream)
|
||||
openjp2.image_destroy(image)
|
||||
|
||||
def ttx0_setup(filename):
|
||||
"""Runs tests tte0, tte0."""
|
||||
kwargs = {'filename': filename,
|
||||
'codec': openjp2.CODEC_J2K,
|
||||
'comp_prec': 8,
|
||||
'irreversible': 1,
|
||||
'num_comps': 3,
|
||||
'image_height': 200,
|
||||
'image_width': 200,
|
||||
'tile_height': 100,
|
||||
'tile_width': 100}
|
||||
tile_encoder(**kwargs)
|
||||
|
||||
def xtx2_setup(filename):
|
||||
"""Runs tests rta2, tte2, ttd2."""
|
||||
kwargs = {'filename': filename,
|
||||
'codec': openjp2.CODEC_JP2,
|
||||
'comp_prec': 8,
|
||||
'irreversible': 1,
|
||||
'num_comps': 3,
|
||||
'image_height': 256,
|
||||
'image_width': 256,
|
||||
'tile_height': 128,
|
||||
'tile_width': 128}
|
||||
tile_encoder(**kwargs)
|
||||
|
||||
def xtx3_setup(filename):
|
||||
"""Runs tests tte3, rta3."""
|
||||
kwargs = {'filename': filename,
|
||||
'codec': openjp2.CODEC_J2K,
|
||||
'comp_prec': 8,
|
||||
'irreversible': 1,
|
||||
'num_comps': 1,
|
||||
'image_height': 256,
|
||||
'image_width': 256,
|
||||
'tile_height': 128,
|
||||
'tile_width': 128}
|
||||
tile_encoder(**kwargs)
|
||||
|
||||
def xtx4_setup(filename):
|
||||
"""Runs tests rta4, tte4."""
|
||||
kwargs = {'filename': filename,
|
||||
'codec': openjp2.CODEC_J2K,
|
||||
'comp_prec': 8,
|
||||
'irreversible': 0,
|
||||
'num_comps': 1,
|
||||
'image_height': 256,
|
||||
'image_width': 256,
|
||||
'tile_height': 128,
|
||||
'tile_width': 128}
|
||||
tile_encoder(**kwargs)
|
||||
|
||||
def xtx5_setup(filename):
|
||||
"""Runs tests rta5, tte5."""
|
||||
kwargs = {'filename': filename,
|
||||
'codec': openjp2.CODEC_J2K,
|
||||
'comp_prec': 8,
|
||||
'irreversible': 0,
|
||||
'num_comps': 1,
|
||||
'image_height': 512,
|
||||
'image_width': 512,
|
||||
'tile_height': 256,
|
||||
'tile_width': 256}
|
||||
tile_encoder(**kwargs)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
@ -15,7 +15,7 @@ from .lib import openjp2 as opj2
|
|||
|
||||
# Do not change the format of this next line! Doing so risks breaking
|
||||
# setup.py
|
||||
version = "0.5.11"
|
||||
version = "0.5.12"
|
||||
_sv = LooseVersion(version)
|
||||
version_tuple = _sv.version
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue