Skip to content

Commit 698104f

Browse files
committed
Add HT-JP2K plugin
1 parent 33d3916 commit 698104f

9 files changed

Lines changed: 69 additions & 0 deletions

File tree

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "lib/h5z-htj2k"]
2+
path = lib/h5z-htj2k
3+
url = https://github.com/silx-kit/h5z-htj2k

CHANGELOG.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
Unreleased
2+
----------
3+
4+
This release add the new plugin `h5z-htj2k`.
5+
16
7.0.0: 25/06/2026
27
-----------------
38

doc/information.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ HDF5 compression filters and compression libraries sources were obtained from:
8484
* `HDF5-ZFP plugin <https://github.com/LLNL/H5Z-ZFP>`_ (v1.1.1) using ZFP.
8585
* `ZStd plugin <https://github.com/HDFGroup/hdf5_plugins/tree/master/ZSTD>`_
8686
(commit `5573db8 <https://github.com/HDFGroup/hdf5_plugins/tree/5573db8f9706e1df262752a9247e90a3d4bd57bd/ZSTD>`_) using ZStd.
87+
* `ZhtJ2k plugin <https://github.com/silx-kit/h5z-htj2k>` (v x.x.x) using `High-Trhoughput JPEG 2000 <https://jpeg.org/jpeg2000/htj2k.html>`
8788

8889
Sources of compression libraries shared accross multiple filters were obtained from:
8990

@@ -112,12 +113,14 @@ Please read the different licenses:
112113
* blosc: `lib/hdf5-blosc/LICENSES/ <https://github.com/silx-kit/hdf5plugin/blob/main/lib/hdf5-blosc/LICENSES/>`_, `lib/c-blosc/LICENSES/ <https://github.com/silx-kit/hdf5plugin/blob/main/lib/c-blosc/LICENSES/>`_
113114
* blosc2: `lib/PyTables/LICENSE.txt <https://github.com/silx-kit/hdf5plugin/blob/main/lib/PyTables/LICENSE.txt>`_ and `lib/c-blosc2/LICENSES/ <https://github.com/silx-kit/hdf5plugin/blob/main/lib/c-blosc2/LICENSES/>`_
114115
* bzip2: `lib/PyTables/LICENSE.txt <https://github.com/silx-kit/hdf5plugin/blob/main/lib/PyTables/LICENSE.txt>`_ and `lib/bzip2/LICENSE <https://github.com/silx-kit/hdf5plugin/blob/main/lib/bzip2/LICENSE>`_
116+
* ht-jp2k: `lib/ <https://jpeg.org/jpeg2000/htj2k.html>`
115117
* lz4: `lib/LZ4/COPYING <https://github.com/silx-kit/hdf5plugin/blob/main/lib/LZ4/COPYING>`_, `lib/LZ4/LICENSE <https://github.com/silx-kit/hdf5plugin/blob/main/lib/LZ4/LICENSE>`_
116118
* FCIDECOMP: `lib/fcidecomp/LICENSE <https://github.com/silx-kit/hdf5plugin/blob/main/lib/fcidecomp/LICENSE>`_ and `lib/charls/LICENSE.md <https://github.com/silx-kit/hdf5plugin/blob/main/lib/charls/LICENSE.md>`_
117119
* SPERR: `lib/H5Z-SPERR/LICENSE <https://github.com/silx-kit/hdf5plugin/blob/main/lib/H5Z-SPERR/LICENSE>`_ and `lib/SPERR/LICENSE <https://github.com/silx-kit/hdf5plugin/blob/main/lib/SPERR/LICENSE>`_
118120
* SZ: `lib/SZ/copyright-and-BSD-license.txt <https://github.com/silx-kit/hdf5plugin/blob/main/lib/SZ/copyright-and-BSD-license.txt>`_
119121
* SZ3: `lib/SZ3/copyright-and-BSD-license.txt <https://github.com/silx-kit/hdf5plugin/blob/main/lib/SZ3/copyright-and-BSD-license.txt>`_
120122
* zfp: `lib/H5Z-ZFP/LICENSE <https://github.com/silx-kit/hdf5plugin/blob/main/lib/H5Z-ZFP/LICENSE>`_
123+
* htj2k: `lib/h5z-htj2k/LICENSE <https://github.com/silx-kit/hdf5plugin/blob/main/lib/H5Z-HT-JP2K/LICENSE>`_
121124
* zstd: `lib/HDF5Plugin-Zstandard/LICENSE <https://github.com/silx-kit/hdf5plugin/blob/main/lib/HDF5Plugin-Zstandard/LICENSE>`_
122125

123126
* Shared compression libraries:

lib/h5z-htj2k

Submodule h5z-htj2k added at 4f91de9

setup.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,6 +1395,26 @@ def _get_h5zfp_plugin():
13951395
)
13961396

13971397

1398+
PLUGIN_LIB_DEPENDENCIES["htj2k"] = ()
1399+
1400+
1401+
def _get_h5z_htj2k_plugin():
1402+
"""H5Z-htj2k plugin build config"""
1403+
h5z_htj2k_dir = "lib/h5z-htj2k"
1404+
openjph_include_dir = f"{h5z_htj2k_dir}/vendored/OpenJPH/src/core/openjph"
1405+
1406+
extra_compile_args = ["-O3", "-std=c++17"]
1407+
extra_compile_args += ["/Ox", "/std:c++17"]
1408+
1409+
return HDF5PluginExtension(
1410+
"hdf5plugin.plugins.libh5htj2k",
1411+
sources=glob(f"{h5z_htj2k_dir}/*.c") + glob(f"{h5z_htj2k_dir}/*.cpp"),
1412+
include_dirs=[h5z_htj2k_dir, openjph_include_dir],
1413+
extra_compile_args=extra_compile_args,
1414+
language="c++",
1415+
)
1416+
1417+
13981418
PLUGIN_LIB_DEPENDENCIES["zfp"] = ("zfp",)
13991419

14001420

@@ -1497,6 +1517,7 @@ def _get_sperr_plugin():
14971517
"bshuf": _get_bitshuffle_plugin,
14981518
"bzip2": _get_bzip2_plugin,
14991519
"fcidecomp": _get_fcidecomp_plugin,
1520+
"htj2k": _get_h5z_htj2k_plugin,
15001521
"lz4": _get_lz4_plugin,
15011522
"sperr": _get_sperr_plugin,
15021523
"sz": _get_sz_plugin,

src/hdf5plugin/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
SZ3_ID,
4343
SZ_ID,
4444
ZFP_ID,
45+
ZHT_JP2K_ID,
4546
ZSTD_ID,
4647
Bitshuffle,
4748
Blosc,
@@ -50,6 +51,7 @@
5051
FciDecomp,
5152
Sperr,
5253
Zfp,
54+
Zhtj2k,
5355
Zstd,
5456
)
5557
from ._utils import ( # noqa
@@ -73,6 +75,7 @@
7375
"SZ",
7476
"SZ3",
7577
"Zfp",
78+
"Zhtj2k",
7679
"Zstd",
7780
# Utilities
7881
"FILTERS",

src/hdf5plugin/_filters.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@
5555
ZFP_ID = 32013
5656
"""ZFP filter ID"""
5757

58+
ZHT_JP2K_ID = 32033
59+
"""High troughput JPEG 2000"""
60+
5861
ZSTD_ID = 32015
5962
"""Zstandard filter ID"""
6063

@@ -808,6 +811,15 @@ def _from_filter_options(cls, filter_options: tuple[int, ...]) -> Zfp:
808811
return cls(minbits=minbits, maxbits=maxbits, maxprec=maxprec, minexp=minexp)
809812

810813

814+
class Zhtj2k(FilterBase):
815+
"""
816+
At the moment this filter only allows **reading** of compressed dataset.
817+
"""
818+
819+
filter_name = "htj2k"
820+
filter_id = ZHT_JP2K_ID
821+
822+
811823
class Sperr(FilterBase):
812824
"""``h5py.Group.create_dataset``'s compression arguments for using SPERR filter.
813825
@@ -1337,6 +1349,7 @@ def _from_filter_options(cls, filter_options: tuple[int, ...]) -> Zstd:
13371349
SZ,
13381350
SZ3,
13391351
Zfp,
1352+
Zhtj2k,
13401353
Zstd,
13411354
)
13421355

src/hdf5plugin/test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ def should_test(filter_name: str) -> bool:
6969
"sz": hdf5plugin.SZ,
7070
"sz3": hdf5plugin.SZ3,
7171
"zfp": hdf5plugin.Zfp,
72+
"zht-jp2k": hdf5plugin.Zhtj2k,
7273
"zstd": hdf5plugin.Zstd,
7374
}
7475

test/test.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,25 @@ def testZfp(self):
144144
numpy.allclose(original, compressed), "Values should be close"
145145
)
146146

147+
@unittest.skipUnless(
148+
h5py.h5z.filter_avail(hdf5plugin.ZHT_JP2K_ID), "HT-JP2K filter not available"
149+
)
150+
def testHtJp2k(self):
151+
"""Test writing and reading back HT-JP2K compressed data (lossless)"""
152+
original = numpy.arange(100, dtype=numpy.uint16)
153+
with self.subTest(dtype=original.dtype, shape=original.shape):
154+
fname = os.path.join(self.tempdir, "ht_jp2k.h5")
155+
with h5py.File(fname, "w") as h5:
156+
h5.create_dataset(
157+
"data",
158+
data=original,
159+
chunks=original.shape,
160+
compression=hdf5plugin.Zhtj2k(),
161+
)
162+
with h5py.File(fname, "r") as h5:
163+
result = h5["data"][()]
164+
numpy.testing.assert_array_equal(result, original)
165+
147166
@unittest.skipUnless(
148167
h5py.h5z.filter_avail(hdf5plugin.SPERR_ID), "Sperr filter not available"
149168
)

0 commit comments

Comments
 (0)