pyisyntax 0.1.1__tar.gz → 0.1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyisyntax-0.1.3/CHANGELOG.md +57 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/MANIFEST.in +1 -0
- {pyisyntax-0.1.1/pyisyntax.egg-info → pyisyntax-0.1.3}/PKG-INFO +12 -1
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/README.md +6 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax/lowlevel/io_management.py +1 -1
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax/lowlevel/libisyntax.py +9 -6
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax/wrapper.py +12 -14
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/builder.py +1 -1
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/examples/isyntax_example.c +1 -3
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/examples/isyntax_to_tiff.c +2 -2
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/isyntax/isyntax.c +11 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/isyntax/isyntax_reader.c +1 -1
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/isyntax/isyntax_streamer.c +0 -15
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/libisyntax.c +10 -6
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/libisyntax.h +3 -2
- {pyisyntax-0.1.1 → pyisyntax-0.1.3/pyisyntax.egg-info}/PKG-INFO +12 -1
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/pyisyntax.egg-info/SOURCES.txt +1 -0
- pyisyntax-0.1.3/pyisyntax.egg-info/top_level.txt +1 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/pyproject.toml +12 -2
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/tests/test_lowlevel.py +2 -6
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/tests/test_wrapper.py +23 -4
- pyisyntax-0.1.1/pyisyntax.egg-info/top_level.txt +0 -2
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/LICENSE +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax/__init__.py +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax/lowlevel/__init__.py +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/__init__.py +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/pyisyntax.c +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/src/python_platform_utils.c +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/src/python_platform_utils.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/src/win32_utils.c +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/LICENSE.txt +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/README.md +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/isyntax/isyntax.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/isyntax/isyntax_dwt.c +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/isyntax/isyntax_reader.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/isyntax/isyntax_streamer.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/arena.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/common.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/intrinsics.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/linux_platform.c +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/linux_utils.c +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/platform.c +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/platform.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/win32_utils.c +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/win32_utils.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/work_queue.c +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/work_queue.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/third_party/ltalloc.cc +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/third_party/ltalloc.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/third_party/stb_ds.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/third_party/stb_image.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/third_party/stb_image_write.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/third_party/stb_sprintf.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/third_party/yxml.c +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/third_party/yxml.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/utils/benaphore.c +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/utils/benaphore.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/utils/block_allocator.c +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/utils/block_allocator.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/utils/libtiff_api.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/utils/mathutils.c +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/utils/mathutils.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/utils/memrw.c +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/utils/memrw.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/utils/stringutils.c +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/utils/stringutils.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/utils/timerutils.c +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/utils/timerutils.h +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/pyisyntax.egg-info/dependency_links.txt +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/pyisyntax.egg-info/not-zip-safe +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/pyisyntax.egg-info/requires.txt +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/setup.cfg +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/setup.py +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/tests/__init__.py +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/tests/conftest.py +0 -0
- {pyisyntax-0.1.1 → pyisyntax-0.1.3}/tests/data/DOWNLOAD.txt +0 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.3] - 2024-03-28
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- This CHANGELOG file.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Gracefully exit the contextmanager when an ISyntax file fails to open
|
|
19
|
+
([#8](https://github.com/anibali/pyisyntax/issues/8)).
|
|
20
|
+
- Release reference to the associated cache object when an ISyntax object is closed
|
|
21
|
+
so that it can be garbage collected and destroyed
|
|
22
|
+
([#9](https://github.com/anibali/pyisyntax/issues/9)).
|
|
23
|
+
|
|
24
|
+
## [0.1.2] - 2024-03-25
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- Configuration option to set the cache size
|
|
29
|
+
([#5](https://github.com/anibali/pyisyntax/issues/5)).
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- Nest the `_pyisyntax` binary library file under the `isyntax` top-level
|
|
34
|
+
namespace.
|
|
35
|
+
- Bump the `libisyntax` submodule commit and match their API changes
|
|
36
|
+
(thanks @erikogabrielsson).
|
|
37
|
+
|
|
38
|
+
## [0.1.1] - 2024-03-02
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- Return `None` when an associated image/colour profile is not present.
|
|
43
|
+
- Reduce the number of provided wheels by using `py_limited_api`.
|
|
44
|
+
Multiple Python versions will continue being tested during CI through
|
|
45
|
+
the use of `tox`.
|
|
46
|
+
|
|
47
|
+
## [0.1.0] - 2024-02-26
|
|
48
|
+
|
|
49
|
+
### Added
|
|
50
|
+
|
|
51
|
+
- This is the initial release.
|
|
52
|
+
|
|
53
|
+
[unreleased]: https://github.com/anibali/pyisyntax/compare/v0.1.3...HEAD
|
|
54
|
+
[0.1.3]: https://github.com/anibali/pyisyntax/compare/v0.1.2...v0.1.3
|
|
55
|
+
[0.1.2]: https://github.com/anibali/pyisyntax/compare/v0.1.1...v0.1.2
|
|
56
|
+
[0.1.1]: https://github.com/anibali/pyisyntax/compare/v0.1.0...v0.1.1
|
|
57
|
+
[0.1.0]: https://github.com/anibali/pyisyntax/releases/tag/v0.1.0
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyisyntax
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: Python bindings for libisyntax
|
|
5
5
|
Author-email: Aiden Nibali <dismaldenizen@gmail.com>
|
|
6
6
|
License: MIT
|
|
7
|
+
Project-URL: homepage, https://github.com/anibali/pyisyntax
|
|
8
|
+
Project-URL: source, https://github.com/anibali/pyisyntax
|
|
9
|
+
Project-URL: download, https://pypi.org/project/pyisyntax/#files
|
|
10
|
+
Project-URL: tracker, https://github.com/anibali/pyisyntax/issues
|
|
11
|
+
Project-URL: release notes, https://github.com/anibali/pyisyntax/blob/master/CHANGELOG.md
|
|
7
12
|
Requires-Python: >=3.10
|
|
8
13
|
Description-Content-Type: text/markdown
|
|
9
14
|
License-File: LICENSE
|
|
@@ -23,6 +28,12 @@ Requires-Dist: typing_extensions; extra == "dev"
|
|
|
23
28
|
A Python library for working with pathology images in the iSyntax file format,
|
|
24
29
|
powered by [libisyntax](https://github.com/amspath/libisyntax).
|
|
25
30
|
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```console
|
|
34
|
+
$ pip install pyisyntax
|
|
35
|
+
```
|
|
36
|
+
|
|
26
37
|
## Usage
|
|
27
38
|
|
|
28
39
|
Read and display a region of the WSI via
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
A Python library for working with pathology images in the iSyntax file format,
|
|
4
4
|
powered by [libisyntax](https://github.com/amspath/libisyntax).
|
|
5
5
|
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
```console
|
|
9
|
+
$ pip install pyisyntax
|
|
10
|
+
```
|
|
11
|
+
|
|
6
12
|
## Usage
|
|
7
13
|
|
|
8
14
|
Read and display a region of the WSI via
|
|
@@ -3,8 +3,7 @@ from enum import IntEnum
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from typing import TYPE_CHECKING, NewType
|
|
5
5
|
|
|
6
|
-
from _pyisyntax import ffi, lib
|
|
7
|
-
|
|
6
|
+
from isyntax._pyisyntax import ffi, lib
|
|
8
7
|
from isyntax.lowlevel.io_management import init_python_io_hooks, register_io
|
|
9
8
|
|
|
10
9
|
if TYPE_CHECKING:
|
|
@@ -108,12 +107,16 @@ def get_tile_height(isyntax: ISyntaxPtr) -> int:
|
|
|
108
107
|
return lib.libisyntax_get_tile_height(isyntax)
|
|
109
108
|
|
|
110
109
|
|
|
111
|
-
def
|
|
112
|
-
return lib.
|
|
110
|
+
def get_wsi_image(isyntax: ISyntaxPtr) -> ISyntaxImagePtr:
|
|
111
|
+
return lib.libisyntax_get_wsi_image(isyntax)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def get_label_image(isyntax: ISyntaxPtr) -> ISyntaxImagePtr:
|
|
115
|
+
return lib.libisyntax_get_label_image(isyntax)
|
|
113
116
|
|
|
114
117
|
|
|
115
|
-
def
|
|
116
|
-
return lib.
|
|
118
|
+
def get_macro_image(isyntax: ISyntaxPtr) -> ISyntaxImagePtr:
|
|
119
|
+
return lib.libisyntax_get_macro_image(isyntax)
|
|
117
120
|
|
|
118
121
|
|
|
119
122
|
def image_get_level_count(wsi_image: ISyntaxImagePtr) -> int:
|
|
@@ -78,23 +78,28 @@ class ISyntaxImage:
|
|
|
78
78
|
|
|
79
79
|
|
|
80
80
|
class ISyntax:
|
|
81
|
-
def __init__(self, f: RawIOBase | BufferedIOBase, n_bytes: int) -> None:
|
|
81
|
+
def __init__(self, f: RawIOBase | BufferedIOBase, n_bytes: int, cache_size: int = 2000) -> None:
|
|
82
|
+
# Start in the "closed" for a graceful contextmanager exit when the file
|
|
83
|
+
# fails to open.
|
|
84
|
+
self.closed = True
|
|
82
85
|
self.io_handle = register_io(f, n_bytes)
|
|
83
86
|
self.ptr = libisyntax.open_from_registered_handle(self.io_handle, is_init_allocators=False)
|
|
84
87
|
self.closed = False
|
|
88
|
+
self._cache_size = cache_size
|
|
85
89
|
self._cache = None
|
|
86
90
|
|
|
87
91
|
@classmethod
|
|
88
|
-
def open(cls: type["ISyntax"], filename: str | Path) -> "ISyntax":
|
|
92
|
+
def open(cls: type["ISyntax"], filename: str | Path, cache_size: int = 2000) -> "ISyntax":
|
|
89
93
|
filename = Path(filename)
|
|
90
94
|
f = filename.open("rb")
|
|
91
95
|
n_bytes = os.fstat(f.fileno()).st_size
|
|
92
|
-
return cls(f, n_bytes)
|
|
96
|
+
return cls(f, n_bytes, cache_size)
|
|
93
97
|
|
|
94
98
|
def close(self) -> None:
|
|
95
99
|
if self.closed:
|
|
96
100
|
return
|
|
97
101
|
libisyntax.close(self.ptr)
|
|
102
|
+
self._cache = None
|
|
98
103
|
self.closed = True
|
|
99
104
|
|
|
100
105
|
@property
|
|
@@ -105,20 +110,13 @@ class ISyntax:
|
|
|
105
110
|
def tile_height(self) -> int:
|
|
106
111
|
return libisyntax.get_tile_height(self.ptr)
|
|
107
112
|
|
|
108
|
-
@property
|
|
109
|
-
def wsi_index(self) -> int:
|
|
110
|
-
return libisyntax.get_wsi_image_index(self.ptr)
|
|
111
|
-
|
|
112
|
-
def get_image(self, image_index: int) -> ISyntaxImage:
|
|
113
|
-
return ISyntaxImage(libisyntax.get_image(self.ptr, image_index))
|
|
114
|
-
|
|
115
113
|
@property
|
|
116
114
|
def wsi(self) -> ISyntaxImage:
|
|
117
|
-
return
|
|
115
|
+
return ISyntaxImage(libisyntax.get_wsi_image(self.ptr))
|
|
118
116
|
|
|
119
117
|
def get_cache(self) -> ISyntaxCache:
|
|
120
118
|
if self._cache is None:
|
|
121
|
-
self._cache = ISyntaxCache(cache_size=
|
|
119
|
+
self._cache = ISyntaxCache(cache_size=self._cache_size)
|
|
122
120
|
self._cache.inject(self)
|
|
123
121
|
return self._cache
|
|
124
122
|
|
|
@@ -180,14 +178,14 @@ class ISyntax:
|
|
|
180
178
|
except libisyntax.LibISyntaxFatalError:
|
|
181
179
|
return None
|
|
182
180
|
|
|
183
|
-
def read_icc_profile(self
|
|
181
|
+
def read_icc_profile(self) -> memoryview | None:
|
|
184
182
|
"""Reads the ICC color profile for an image.
|
|
185
183
|
|
|
186
184
|
Returns:
|
|
187
185
|
The ICC color profile, or None if it can't be read.
|
|
188
186
|
"""
|
|
189
187
|
try:
|
|
190
|
-
return libisyntax.read_icc_profile(self.ptr, self.
|
|
188
|
+
return libisyntax.read_icc_profile(self.ptr, self.wsi.ptr)
|
|
191
189
|
except libisyntax.LibISyntaxFatalError:
|
|
192
190
|
return None
|
|
193
191
|
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/examples/isyntax_example.c
RENAMED
|
@@ -15,9 +15,7 @@
|
|
|
15
15
|
#define LOG_VAR(fmt, var) printf("%s: %s=" fmt "\n", __FUNCTION__, #var, var)
|
|
16
16
|
|
|
17
17
|
void print_isyntax_levels(isyntax_t* isyntax) {
|
|
18
|
-
|
|
19
|
-
LOG_VAR("%d", wsi_image_idx);
|
|
20
|
-
const isyntax_image_t* wsi_image = libisyntax_get_image(isyntax, wsi_image_idx);
|
|
18
|
+
const isyntax_image_t* wsi_image = libisyntax_get_wsi_image(isyntax);
|
|
21
19
|
|
|
22
20
|
for (int i = 0; i < libisyntax_image_get_level_count(wsi_image); ++i) {
|
|
23
21
|
const isyntax_level_t* level = libisyntax_image_get_level(wsi_image, i);
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/examples/isyntax_to_tiff.c
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
BSD 2-Clause License
|
|
3
3
|
|
|
4
|
-
Copyright (c) 2019-
|
|
4
|
+
Copyright (c) 2019-2024, Pieter Valkema, Alexandr Virodov, Jonas Teuwen
|
|
5
5
|
|
|
6
6
|
Redistribution and use in source and binary forms, with or without
|
|
7
7
|
modification, are permitted provided that the following conditions are met:
|
|
@@ -445,7 +445,7 @@ int main(int argc, char **argv) {
|
|
|
445
445
|
return -1;
|
|
446
446
|
}
|
|
447
447
|
|
|
448
|
-
const isyntax_image_t *image =
|
|
448
|
+
const isyntax_image_t *image = libisyntax_get_wsi_image(isyntax);
|
|
449
449
|
|
|
450
450
|
// Check if the page we selected actually exists.
|
|
451
451
|
int32_t level_count = libisyntax_image_get_level_count(image);
|
|
@@ -3327,6 +3327,17 @@ bool isyntax_open(isyntax_t* isyntax, const char* filename, bool init_allocators
|
|
|
3327
3327
|
isyntax->is_block_allocator_owned = false;
|
|
3328
3328
|
}
|
|
3329
3329
|
|
|
3330
|
+
// Initialize dummy blocks with 'background' coefficients, to use for filling in margins at the edges (in case the neighboring codeblock doesn't exist)
|
|
3331
|
+
if (!isyntax->black_dummy_coeff) {
|
|
3332
|
+
isyntax->black_dummy_coeff = (icoeff_t*)calloc(1, isyntax->block_width * isyntax->block_height * sizeof(icoeff_t));
|
|
3333
|
+
}
|
|
3334
|
+
if (!isyntax->white_dummy_coeff) {
|
|
3335
|
+
isyntax->white_dummy_coeff = (icoeff_t*)malloc(isyntax->block_width * isyntax->block_height * sizeof(icoeff_t));
|
|
3336
|
+
for (i32 i = 0; i < isyntax->block_width * isyntax->block_height; ++i) {
|
|
3337
|
+
isyntax->white_dummy_coeff[i] = 255;
|
|
3338
|
+
}
|
|
3339
|
+
}
|
|
3340
|
+
|
|
3330
3341
|
success = true;
|
|
3331
3342
|
|
|
3332
3343
|
free(read_buffer);
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/isyntax/isyntax_reader.c
RENAMED
|
@@ -128,7 +128,7 @@ static void isyntax_openslide_load_tile_coefficients_ll_or_h(isyntax_cache_t* ca
|
|
|
128
128
|
|
|
129
129
|
isyntax_hulsken_decompress(codeblock_data, codeblock->block_size,
|
|
130
130
|
isyntax->block_width, isyntax->block_height,
|
|
131
|
-
codeblock->coefficient,
|
|
131
|
+
codeblock->coefficient, wsi->compressor_version,
|
|
132
132
|
is_ll ? tile->color_channels[color].coeff_ll : tile->color_channels[color].coeff_h);
|
|
133
133
|
free(codeblock_data);
|
|
134
134
|
}
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/isyntax/isyntax_streamer.c
RENAMED
|
@@ -51,19 +51,6 @@ static void submit_tile_completed(isyntax_streamer_t* streamer, void* tile_pixel
|
|
|
51
51
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
static void isyntax_init_dummy_codeblocks(isyntax_t* isyntax) {
|
|
55
|
-
// Blocks with 'background' coefficients, to use for filling in margins at the edges (in case the neighboring codeblock doesn't exist)
|
|
56
|
-
if (!isyntax->black_dummy_coeff) {
|
|
57
|
-
isyntax->black_dummy_coeff = (icoeff_t*)calloc(1, isyntax->block_width * isyntax->block_height * sizeof(icoeff_t));
|
|
58
|
-
}
|
|
59
|
-
if (!isyntax->white_dummy_coeff) {
|
|
60
|
-
isyntax->white_dummy_coeff = (icoeff_t*)malloc(isyntax->block_width * isyntax->block_height * sizeof(icoeff_t));
|
|
61
|
-
for (i32 i = 0; i < isyntax->block_width * isyntax->block_height; ++i) {
|
|
62
|
-
isyntax->white_dummy_coeff[i] = 255;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
54
|
static i32 isyntax_load_all_tiles_in_level(isyntax_streamer_t* streamer, i32 scale) {
|
|
68
55
|
i32 tiles_loaded = 0;
|
|
69
56
|
i32 tile_index = 0;
|
|
@@ -125,8 +112,6 @@ static void isyntax_do_first_load(isyntax_streamer_t* streamer) {
|
|
|
125
112
|
i32 tiles_loaded = 0;
|
|
126
113
|
isyntax->total_rgb_transform_time = 0.0f;
|
|
127
114
|
|
|
128
|
-
isyntax_init_dummy_codeblocks(isyntax);
|
|
129
|
-
|
|
130
115
|
i32 scale = wsi->max_scale;
|
|
131
116
|
isyntax_level_t* current_level = wsi->levels + scale;
|
|
132
117
|
i32 codeblocks_per_color = isyntax_get_chunk_codeblocks_per_color_for_level(scale, true); // most often 1 + 4 + 16 (for scale n, n-1, n-2) + 1 (LL block)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
BSD 2-Clause License
|
|
3
3
|
|
|
4
|
-
Copyright (c) 2019-
|
|
4
|
+
Copyright (c) 2019-2024, Pieter Valkema
|
|
5
5
|
|
|
6
6
|
Redistribution and use in source and binary forms, with or without
|
|
7
7
|
modification, are permitted provided that the following conditions are met:
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
|
|
43
43
|
#define CHECK_LIBISYNTAX_OK(_libisyntax_call) do { \
|
|
44
44
|
isyntax_error_t result = _libisyntax_call; \
|
|
45
|
-
|
|
45
|
+
ASSERT(result == LIBISYNTAX_OK); \
|
|
46
46
|
} while(0);
|
|
47
47
|
|
|
48
48
|
static platform_thread_info_t thread_infos[MAX_THREAD_COUNT];
|
|
@@ -249,12 +249,16 @@ int32_t libisyntax_get_tile_height(const isyntax_t* isyntax) {
|
|
|
249
249
|
return isyntax->tile_height;
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
-
|
|
253
|
-
return isyntax->wsi_image_index;
|
|
252
|
+
const isyntax_image_t* libisyntax_get_wsi_image(const isyntax_t* isyntax) {
|
|
253
|
+
return isyntax->images + isyntax->wsi_image_index;
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
-
const isyntax_image_t*
|
|
257
|
-
|
|
256
|
+
const isyntax_image_t* libisyntax_get_label_image(const isyntax_t* isyntax) {
|
|
257
|
+
return isyntax->images + isyntax->label_image_index;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const isyntax_image_t* libisyntax_get_macro_image(const isyntax_t* isyntax) {
|
|
261
|
+
return isyntax->images + isyntax->label_image_index;
|
|
258
262
|
}
|
|
259
263
|
|
|
260
264
|
int32_t libisyntax_image_get_level_count(const isyntax_image_t* image) {
|
|
@@ -47,8 +47,9 @@ void libisyntax_close(isyntax_t* isyntax);
|
|
|
47
47
|
//== Getters API ==
|
|
48
48
|
int32_t libisyntax_get_tile_width(const isyntax_t* isyntax);
|
|
49
49
|
int32_t libisyntax_get_tile_height(const isyntax_t* isyntax);
|
|
50
|
-
|
|
51
|
-
const isyntax_image_t*
|
|
50
|
+
const isyntax_image_t* libisyntax_get_wsi_image(const isyntax_t* isyntax);
|
|
51
|
+
const isyntax_image_t* libisyntax_get_label_image(const isyntax_t* isyntax);
|
|
52
|
+
const isyntax_image_t* libisyntax_get_macro_image(const isyntax_t* isyntax);
|
|
52
53
|
int32_t libisyntax_image_get_level_count(const isyntax_image_t* image);
|
|
53
54
|
const isyntax_level_t* libisyntax_image_get_level(const isyntax_image_t* image, int32_t index);
|
|
54
55
|
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyisyntax
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: Python bindings for libisyntax
|
|
5
5
|
Author-email: Aiden Nibali <dismaldenizen@gmail.com>
|
|
6
6
|
License: MIT
|
|
7
|
+
Project-URL: homepage, https://github.com/anibali/pyisyntax
|
|
8
|
+
Project-URL: source, https://github.com/anibali/pyisyntax
|
|
9
|
+
Project-URL: download, https://pypi.org/project/pyisyntax/#files
|
|
10
|
+
Project-URL: tracker, https://github.com/anibali/pyisyntax/issues
|
|
11
|
+
Project-URL: release notes, https://github.com/anibali/pyisyntax/blob/master/CHANGELOG.md
|
|
7
12
|
Requires-Python: >=3.10
|
|
8
13
|
Description-Content-Type: text/markdown
|
|
9
14
|
License-File: LICENSE
|
|
@@ -23,6 +28,12 @@ Requires-Dist: typing_extensions; extra == "dev"
|
|
|
23
28
|
A Python library for working with pathology images in the iSyntax file format,
|
|
24
29
|
powered by [libisyntax](https://github.com/amspath/libisyntax).
|
|
25
30
|
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```console
|
|
34
|
+
$ pip install pyisyntax
|
|
35
|
+
```
|
|
36
|
+
|
|
26
37
|
## Usage
|
|
27
38
|
|
|
28
39
|
Read and display a region of the WSI via
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
isyntax
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pyisyntax"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.3"
|
|
4
4
|
description = "Python bindings for libisyntax"
|
|
5
5
|
readme = { content-type = "text/markdown", file = "README.md" }
|
|
6
6
|
authors = [{ name = "Aiden Nibali", email = "dismaldenizen@gmail.com" }]
|
|
@@ -11,6 +11,13 @@ dependencies = [
|
|
|
11
11
|
"numpy",
|
|
12
12
|
]
|
|
13
13
|
|
|
14
|
+
[project.urls]
|
|
15
|
+
homepage = "https://github.com/anibali/pyisyntax"
|
|
16
|
+
source = "https://github.com/anibali/pyisyntax"
|
|
17
|
+
download = "https://pypi.org/project/pyisyntax/#files"
|
|
18
|
+
tracker = "https://github.com/anibali/pyisyntax/issues"
|
|
19
|
+
"release notes" = "https://github.com/anibali/pyisyntax/blob/master/CHANGELOG.md"
|
|
20
|
+
|
|
14
21
|
[project.optional-dependencies]
|
|
15
22
|
dev = [
|
|
16
23
|
"conda-lock",
|
|
@@ -62,6 +69,9 @@ pydocstyle.convention = "google"
|
|
|
62
69
|
[tool.pyright]
|
|
63
70
|
typeCheckingMode = "standard"
|
|
64
71
|
|
|
72
|
+
[tool.pytest.ini_options]
|
|
73
|
+
addopts = "-Werror"
|
|
74
|
+
|
|
65
75
|
[tool.tox]
|
|
66
76
|
legacy_tox_ini = """
|
|
67
77
|
[tox]
|
|
@@ -72,7 +82,7 @@ env_list = lint, type, py{310,311,312}
|
|
|
72
82
|
deps =
|
|
73
83
|
pytest
|
|
74
84
|
pytest-mock
|
|
75
|
-
commands = pytest {posargs:tests}
|
|
85
|
+
commands = pytest --import-mode=importlib {posargs:tests}
|
|
76
86
|
|
|
77
87
|
[testenv:lint]
|
|
78
88
|
skip_install = true
|
|
@@ -23,7 +23,7 @@ def isyntax(sample_isyntax_file: Path) -> Iterator[ISyntaxPtr]:
|
|
|
23
23
|
|
|
24
24
|
@pytest.fixture()
|
|
25
25
|
def wsi_image(isyntax: ISyntaxPtr) -> ISyntaxImagePtr:
|
|
26
|
-
return libisyntax.
|
|
26
|
+
return libisyntax.get_wsi_image(isyntax)
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
@pytest.fixture()
|
|
@@ -59,10 +59,6 @@ def test_libisyntax_get_tile_height(isyntax: ISyntaxPtr) -> None:
|
|
|
59
59
|
assert libisyntax.get_tile_height(isyntax) == expected
|
|
60
60
|
|
|
61
61
|
|
|
62
|
-
def test_libisyntax_get_wsi_image_index(isyntax: ISyntaxPtr) -> None:
|
|
63
|
-
assert libisyntax.get_wsi_image_index(isyntax) == 0
|
|
64
|
-
|
|
65
|
-
|
|
66
62
|
def test_libisyntax_image_get_level_count(wsi_image: ISyntaxImagePtr) -> None:
|
|
67
63
|
expected = 8
|
|
68
64
|
assert libisyntax.image_get_level_count(wsi_image) == expected
|
|
@@ -159,7 +155,7 @@ def test_libisyntax_read_macro_image_jpeg(isyntax: ISyntaxPtr, mocker: MockerFix
|
|
|
159
155
|
|
|
160
156
|
def test_libisyntax_read_icc_profile(isyntax: ISyntaxPtr, mocker: MockerFixture) -> None:
|
|
161
157
|
free_spy = mocker.spy(libisyntax, "free")
|
|
162
|
-
wsi_image = libisyntax.
|
|
158
|
+
wsi_image = libisyntax.get_wsi_image(isyntax)
|
|
163
159
|
buf = libisyntax.read_icc_profile(isyntax, wsi_image)
|
|
164
160
|
version_major = buf[8]
|
|
165
161
|
version_minor = buf[9] >> 4
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import gc
|
|
2
|
+
import io
|
|
1
3
|
from collections.abc import Iterator
|
|
2
4
|
from pathlib import Path
|
|
3
5
|
|
|
@@ -22,10 +24,6 @@ class TestISyntax:
|
|
|
22
24
|
expected = 256
|
|
23
25
|
assert isyntax.tile_height == expected
|
|
24
26
|
|
|
25
|
-
def test_wsi_index(self, isyntax: ISyntax) -> None:
|
|
26
|
-
expected = 0
|
|
27
|
-
assert isyntax.wsi_index == expected
|
|
28
|
-
|
|
29
27
|
def test_level_count(self, isyntax: ISyntax) -> None:
|
|
30
28
|
expected = 8
|
|
31
29
|
assert isyntax.level_count == expected
|
|
@@ -89,6 +87,7 @@ class TestISyntax:
|
|
|
89
87
|
def test_read_label_image_jpeg(self, isyntax: ISyntax, mocker: MockerFixture) -> None:
|
|
90
88
|
free_spy = mocker.spy(libisyntax, "free")
|
|
91
89
|
jpeg_data = isyntax.read_label_image_jpeg()
|
|
90
|
+
assert jpeg_data is not None
|
|
92
91
|
jpeg_magic = b"\xff\xd8"
|
|
93
92
|
assert jpeg_data[:2] == jpeg_magic
|
|
94
93
|
expected_size = 60348
|
|
@@ -102,6 +101,7 @@ class TestISyntax:
|
|
|
102
101
|
def test_read_macro_image_jpeg(self, isyntax: ISyntax, mocker: MockerFixture) -> None:
|
|
103
102
|
free_spy = mocker.spy(libisyntax, "free")
|
|
104
103
|
jpeg_data = isyntax.read_macro_image_jpeg()
|
|
104
|
+
assert jpeg_data is not None
|
|
105
105
|
jpeg_magic = b"\xff\xd8"
|
|
106
106
|
assert jpeg_data[:2] == jpeg_magic
|
|
107
107
|
expected_size = 49625
|
|
@@ -111,3 +111,22 @@ class TestISyntax:
|
|
|
111
111
|
free_spy.assert_not_called()
|
|
112
112
|
del jpeg_data
|
|
113
113
|
free_spy.assert_called_once()
|
|
114
|
+
|
|
115
|
+
def test_close_is_idempotent(self, isyntax: ISyntax) -> None:
|
|
116
|
+
isyntax.close()
|
|
117
|
+
isyntax.close()
|
|
118
|
+
assert isyntax.closed
|
|
119
|
+
|
|
120
|
+
def test_cache_is_destroyed_on_close(self, isyntax: ISyntax, mocker: MockerFixture) -> None:
|
|
121
|
+
destroy_spy = mocker.spy(libisyntax, "cache_destroy")
|
|
122
|
+
# Reading image data causes the cache to be created.
|
|
123
|
+
isyntax.read_region(500, 500, 1, 1, level=4)
|
|
124
|
+
destroy_spy.assert_not_called()
|
|
125
|
+
isyntax.close()
|
|
126
|
+
gc.collect()
|
|
127
|
+
destroy_spy.assert_called_once()
|
|
128
|
+
|
|
129
|
+
def test_closes_after_error_from_contextmanager(self) -> None:
|
|
130
|
+
f = io.BytesIO()
|
|
131
|
+
with pytest.raises(libisyntax.LibISyntaxFatalError), ISyntax(f, 0):
|
|
132
|
+
pass
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/isyntax/isyntax_dwt.c
RENAMED
|
File without changes
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/isyntax/isyntax_reader.h
RENAMED
|
File without changes
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/isyntax/isyntax_streamer.h
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/intrinsics.h
RENAMED
|
File without changes
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/linux_platform.c
RENAMED
|
File without changes
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/linux_utils.c
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/win32_utils.c
RENAMED
|
File without changes
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/win32_utils.h
RENAMED
|
File without changes
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/work_queue.c
RENAMED
|
File without changes
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/platform/work_queue.h
RENAMED
|
File without changes
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/third_party/ltalloc.cc
RENAMED
|
File without changes
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/third_party/ltalloc.h
RENAMED
|
File without changes
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/third_party/stb_ds.h
RENAMED
|
File without changes
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/third_party/stb_image.h
RENAMED
|
File without changes
|
|
File without changes
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/third_party/stb_sprintf.h
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/utils/block_allocator.c
RENAMED
|
File without changes
|
{pyisyntax-0.1.1 → pyisyntax-0.1.3}/isyntax_build/vendor/libisyntax/src/utils/block_allocator.h
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|