async-tiff 0.2.0__cp310-cp310-musllinux_1_2_i686.whl → 0.5.0b3__cp310-cp310-musllinux_1_2_i686.whl
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.
- async_tiff/__init__.py +28 -7
- async_tiff/_array.pyi +45 -0
- async_tiff/_async_tiff.cpython-310-i386-linux-gnu.so +0 -0
- async_tiff/_async_tiff.pyi +19 -8
- async_tiff/_colormap.pyi +14 -0
- async_tiff/_decoder.pyi +3 -13
- async_tiff/_decoder_runtime.py +21 -0
- async_tiff/_geo.pyi +11 -0
- async_tiff/_ifd.pyi +47 -4
- async_tiff/_input.py +8 -0
- async_tiff/_tiff.pyi +28 -9
- async_tiff/_tile.pyi +30 -7
- async_tiff/enums.py +10 -2
- async_tiff-0.5.0b3.dist-info/METADATA +103 -0
- async_tiff-0.5.0b3.dist-info/RECORD +19 -0
- {async_tiff-0.2.0.dist-info → async_tiff-0.5.0b3.dist-info}/WHEEL +1 -1
- async_tiff.libs/libgcc_s-8c2f5de4.so.1 +0 -0
- async_tiff-0.2.0.dist-info/METADATA +0 -8
- async_tiff-0.2.0.dist-info/RECORD +0 -15
- async_tiff.libs/libgcc_s-27e5a392.so.1 +0 -0
async_tiff/__init__.py
CHANGED
|
@@ -1,9 +1,30 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
from . import enums
|
|
2
|
+
from ._async_tiff import (
|
|
3
|
+
TIFF,
|
|
4
|
+
Array,
|
|
5
|
+
Colormap,
|
|
6
|
+
DecoderRegistry,
|
|
7
|
+
GeoKeyDirectory,
|
|
8
|
+
ImageFileDirectory,
|
|
9
|
+
ThreadPool,
|
|
10
|
+
Tile,
|
|
11
|
+
___version, # noqa: F403 # pyright:ignore[reportAttributeAccessIssue]
|
|
12
|
+
)
|
|
13
|
+
from ._decoder_runtime import Decoder
|
|
14
|
+
from ._input import ObspecInput
|
|
8
15
|
|
|
9
16
|
__version__: str = ___version()
|
|
17
|
+
|
|
18
|
+
__all__ = [
|
|
19
|
+
"enums",
|
|
20
|
+
"Array",
|
|
21
|
+
"Colormap",
|
|
22
|
+
"Decoder",
|
|
23
|
+
"DecoderRegistry",
|
|
24
|
+
"GeoKeyDirectory",
|
|
25
|
+
"ImageFileDirectory",
|
|
26
|
+
"ThreadPool",
|
|
27
|
+
"TIFF",
|
|
28
|
+
"ObspecInput",
|
|
29
|
+
"Tile",
|
|
30
|
+
]
|
async_tiff/_array.pyi
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
if sys.version_info >= (3, 12):
|
|
4
|
+
from collections.abc import Buffer
|
|
5
|
+
else:
|
|
6
|
+
from typing_extensions import Buffer
|
|
7
|
+
|
|
8
|
+
class Array(Buffer):
|
|
9
|
+
"""A 3D array that implements Python's buffer protocol.
|
|
10
|
+
|
|
11
|
+
This allows zero-copy interoperability with numpy via `np.asarray(arr)`.
|
|
12
|
+
The array is immutable and exposes a read-only buffer.
|
|
13
|
+
|
|
14
|
+
Example:
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
import numpy as np
|
|
18
|
+
from async_tiff import Array
|
|
19
|
+
|
|
20
|
+
# Create from raw bytes
|
|
21
|
+
data = bytes([1, 2, 3, 4, 5, 6])
|
|
22
|
+
arr = Array(data, shape=(1, 2, 3), format="<B") # 1x2x3 uint8 array
|
|
23
|
+
|
|
24
|
+
# Convert to numpy (zero-copy view)
|
|
25
|
+
np_arr = np.asarray(arr)
|
|
26
|
+
assert np_arr.shape == (1, 2, 3)
|
|
27
|
+
assert np_arr.dtype == np.uint8
|
|
28
|
+
```
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
# This is intended only for tests
|
|
32
|
+
# def __init__(
|
|
33
|
+
# self, data: Buffer, shape: tuple[int, int, int], format: str
|
|
34
|
+
# ) -> None: ...
|
|
35
|
+
def __buffer__(self, flags: int) -> memoryview[int]: ...
|
|
36
|
+
@property
|
|
37
|
+
def shape(self) -> tuple[int, int, int]:
|
|
38
|
+
"""The shape of the array.
|
|
39
|
+
|
|
40
|
+
The interpretation depends on the PlanarConfiguration:
|
|
41
|
+
|
|
42
|
+
- PlanarConfiguration=1 (chunky): (height, width, bands)
|
|
43
|
+
- PlanarConfiguration=2 (planar): (bands, height, width)
|
|
44
|
+
"""
|
|
45
|
+
...
|
|
Binary file
|
async_tiff/_async_tiff.pyi
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
|
-
from .
|
|
2
|
-
from .
|
|
3
|
-
from .
|
|
4
|
-
from .
|
|
5
|
-
from .
|
|
6
|
-
from .
|
|
7
|
-
from ._tiff import TIFF
|
|
8
|
-
from ._tile import Tile
|
|
1
|
+
from ._array import Array
|
|
2
|
+
from ._colormap import Colormap
|
|
3
|
+
from ._decoder import DecoderRegistry
|
|
4
|
+
from ._geo import GeoKeyDirectory
|
|
5
|
+
from ._ifd import ImageFileDirectory
|
|
6
|
+
from ._thread_pool import ThreadPool
|
|
7
|
+
from ._tiff import TIFF
|
|
8
|
+
from ._tile import Tile
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"Array",
|
|
12
|
+
"Colormap",
|
|
13
|
+
"DecoderRegistry",
|
|
14
|
+
"GeoKeyDirectory",
|
|
15
|
+
"ImageFileDirectory",
|
|
16
|
+
"ThreadPool",
|
|
17
|
+
"TIFF",
|
|
18
|
+
"Tile",
|
|
19
|
+
]
|
async_tiff/_colormap.pyi
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
if sys.version_info >= (3, 12):
|
|
4
|
+
from collections.abc import Buffer
|
|
5
|
+
else:
|
|
6
|
+
from typing_extensions import Buffer
|
|
7
|
+
|
|
8
|
+
class Colormap(Buffer):
|
|
9
|
+
"""A 1D array of u16 values representing a TIFF colormap.
|
|
10
|
+
|
|
11
|
+
Implements Python's buffer protocol for zero-copy access via `np.asarray()`.
|
|
12
|
+
"""
|
|
13
|
+
def __buffer__(self, flags: int) -> memoryview[int]: ...
|
|
14
|
+
def __len__(self) -> int: ...
|
async_tiff/_decoder.pyi
CHANGED
|
@@ -1,20 +1,10 @@
|
|
|
1
|
-
from
|
|
2
|
-
from
|
|
3
|
-
|
|
4
|
-
from .enums import CompressionMethod
|
|
5
|
-
|
|
6
|
-
class Decoder(Protocol):
|
|
7
|
-
"""A custom Python-provided decompression algorithm."""
|
|
8
|
-
# In the future, we could pass in photometric interpretation and jpeg tables as
|
|
9
|
-
# well.
|
|
10
|
-
@staticmethod
|
|
11
|
-
def __call__(buffer: Buffer) -> Buffer:
|
|
12
|
-
"""A callback to decode compressed data."""
|
|
1
|
+
from ._decoder_runtime import Decoder
|
|
2
|
+
from .enums import Compression
|
|
13
3
|
|
|
14
4
|
class DecoderRegistry:
|
|
15
5
|
"""A registry holding multiple decoder methods."""
|
|
16
6
|
def __init__(
|
|
17
|
-
self, custom_decoders: dict[
|
|
7
|
+
self, custom_decoders: dict[Compression | int, Decoder] | None = None
|
|
18
8
|
) -> None:
|
|
19
9
|
"""Construct a new decoder registry.
|
|
20
10
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from typing import TYPE_CHECKING, Protocol
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
if sys.version_info >= (3, 12):
|
|
8
|
+
from collections.abc import Buffer
|
|
9
|
+
else:
|
|
10
|
+
from typing_extensions import Buffer
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Decoder(Protocol):
|
|
14
|
+
"""A custom Python-provided decompression algorithm."""
|
|
15
|
+
|
|
16
|
+
# In the future, we could pass in photometric interpretation and jpeg tables as
|
|
17
|
+
# well.
|
|
18
|
+
@staticmethod
|
|
19
|
+
def __call__(buffer: Buffer) -> Buffer:
|
|
20
|
+
"""A callback to decode compressed data."""
|
|
21
|
+
...
|
async_tiff/_geo.pyi
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
|
+
from collections.abc import Iterable
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
1
4
|
class GeoKeyDirectory:
|
|
5
|
+
def keys(self) -> list[str]:
|
|
6
|
+
"""A list of string keys representing the GeoKey fields."""
|
|
7
|
+
def __eq__(self, value: object) -> bool: ...
|
|
8
|
+
def __iter__(self) -> Iterable[str]:
|
|
9
|
+
"""An iterable of string keys representing the GeoKey fields."""
|
|
10
|
+
def __getitem__(self, key: str) -> Any:
|
|
11
|
+
"""Access GeoKey fields by string key."""
|
|
12
|
+
|
|
2
13
|
@property
|
|
3
14
|
def model_type(self) -> int | None: ...
|
|
4
15
|
@property
|
async_tiff/_ifd.pyi
CHANGED
|
@@ -1,16 +1,29 @@
|
|
|
1
|
+
from collections.abc import Iterable, Sequence
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from ._colormap import Colormap
|
|
5
|
+
from ._geo import GeoKeyDirectory
|
|
6
|
+
from ._tile import Tile
|
|
1
7
|
from .enums import (
|
|
2
|
-
|
|
8
|
+
Compression,
|
|
3
9
|
PhotometricInterpretation,
|
|
4
10
|
PlanarConfiguration,
|
|
5
11
|
Predictor,
|
|
6
12
|
ResolutionUnit,
|
|
7
13
|
SampleFormat,
|
|
8
14
|
)
|
|
9
|
-
from ._geo import GeoKeyDirectory
|
|
10
15
|
|
|
11
16
|
Value = int | float | str | tuple[int, int] | list[Value]
|
|
12
17
|
|
|
13
18
|
class ImageFileDirectory:
|
|
19
|
+
def keys(self) -> list[str]:
|
|
20
|
+
"""A list of string keys representing the IFD fields."""
|
|
21
|
+
def __eq__(self, value: object) -> bool: ...
|
|
22
|
+
def __iter__(self) -> Iterable[str]:
|
|
23
|
+
"""An iterable of string keys representing the IFD fields."""
|
|
24
|
+
def __getitem__(self, key: str) -> Any:
|
|
25
|
+
"""Access IFD fields by string key."""
|
|
26
|
+
|
|
14
27
|
@property
|
|
15
28
|
def new_subfile_type(self) -> int | None: ...
|
|
16
29
|
@property
|
|
@@ -24,11 +37,11 @@ class ImageFileDirectory:
|
|
|
24
37
|
@property
|
|
25
38
|
def bits_per_sample(self) -> list[int]: ...
|
|
26
39
|
@property
|
|
27
|
-
def compression(self) ->
|
|
40
|
+
def compression(self) -> Compression | int:
|
|
28
41
|
"""Access the compression tag.
|
|
29
42
|
|
|
30
43
|
An `int` will be returned if the compression is not one of the values in
|
|
31
|
-
`
|
|
44
|
+
`Compression`.
|
|
32
45
|
"""
|
|
33
46
|
@property
|
|
34
47
|
def photometric_interpretation(self) -> PhotometricInterpretation: ...
|
|
@@ -104,4 +117,34 @@ class ImageFileDirectory:
|
|
|
104
117
|
@property
|
|
105
118
|
def model_tiepoint(self) -> list[float] | None: ...
|
|
106
119
|
@property
|
|
120
|
+
def model_transformation(self) -> list[float] | None: ...
|
|
121
|
+
@property
|
|
122
|
+
def gdal_nodata(self) -> str | None: ...
|
|
123
|
+
@property
|
|
124
|
+
def gdal_metadata(self) -> str | None: ...
|
|
125
|
+
@property
|
|
107
126
|
def other_tags(self) -> dict[int, Value]: ...
|
|
127
|
+
@property
|
|
128
|
+
def colormap(self) -> Colormap | None:
|
|
129
|
+
"""The colormap for palette-color images."""
|
|
130
|
+
...
|
|
131
|
+
async def fetch_tile(self, x: int, y: int) -> Tile:
|
|
132
|
+
"""Fetch a single tile.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
x: The column index within the ifd to read from.
|
|
136
|
+
y: The row index within the ifd to read from.
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
Tile response.
|
|
140
|
+
"""
|
|
141
|
+
async def fetch_tiles(self, x: Sequence[int], y: Sequence[int]) -> list[Tile]:
|
|
142
|
+
"""Fetch multiple tiles concurrently.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
x: The column indexes within the ifd to read from.
|
|
146
|
+
y: The row indexes within the ifd to read from.
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
Tile responses.
|
|
150
|
+
"""
|
async_tiff/_input.py
ADDED
async_tiff/_tiff.pyi
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
from typing import
|
|
2
|
-
|
|
1
|
+
from typing import Sequence
|
|
2
|
+
|
|
3
3
|
from ._ifd import ImageFileDirectory
|
|
4
|
+
from ._input import ObspecInput
|
|
5
|
+
from ._tile import Tile
|
|
6
|
+
from .enums import Endianness
|
|
4
7
|
from .store import ObjectStore
|
|
5
8
|
|
|
6
|
-
# Fix exports
|
|
7
|
-
from obspec._get import GetRangeAsync, GetRangesAsync
|
|
8
|
-
|
|
9
|
-
class ObspecInput(GetRangeAsync, GetRangesAsync, Protocol):
|
|
10
|
-
"""Supported obspec input to reader."""
|
|
11
|
-
|
|
12
9
|
class TIFF:
|
|
13
10
|
@classmethod
|
|
14
11
|
async def open(
|
|
@@ -17,6 +14,7 @@ class TIFF:
|
|
|
17
14
|
*,
|
|
18
15
|
store: ObjectStore | ObspecInput,
|
|
19
16
|
prefetch: int = 32768,
|
|
17
|
+
multiplier: int | float = 2.0,
|
|
20
18
|
) -> TIFF:
|
|
21
19
|
"""Open a new TIFF.
|
|
22
20
|
|
|
@@ -24,10 +22,29 @@ class TIFF:
|
|
|
24
22
|
path: The path within the store to read from.
|
|
25
23
|
store: The backend to use for data fetching.
|
|
26
24
|
prefetch: The number of initial bytes to read up front.
|
|
25
|
+
multiplier: The multiplier to use for readahead size growth. Must be
|
|
26
|
+
greater than 1.0. For example, for a value of `2.0`, the first metadata
|
|
27
|
+
read will be of size `prefetch`, and then the next read will be of size
|
|
28
|
+
`prefetch * 2`.
|
|
27
29
|
|
|
28
30
|
Returns:
|
|
29
31
|
A TIFF instance.
|
|
30
32
|
"""
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def endianness(self) -> Endianness:
|
|
36
|
+
"""The endianness of this TIFF file."""
|
|
37
|
+
|
|
38
|
+
def ifd(self, index: int) -> ImageFileDirectory:
|
|
39
|
+
"""Access a specific IFD by index.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
index: The IFD index to access.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
The requested IFD.
|
|
46
|
+
"""
|
|
47
|
+
|
|
31
48
|
@property
|
|
32
49
|
def ifds(self) -> list[ImageFileDirectory]:
|
|
33
50
|
"""Access the underlying IFDs of this TIFF.
|
|
@@ -46,7 +63,9 @@ class TIFF:
|
|
|
46
63
|
Returns:
|
|
47
64
|
Tile response.
|
|
48
65
|
"""
|
|
49
|
-
async def fetch_tiles(
|
|
66
|
+
async def fetch_tiles(
|
|
67
|
+
self, x: Sequence[int], y: Sequence[int], z: int
|
|
68
|
+
) -> list[Tile]:
|
|
50
69
|
"""Fetch multiple tiles concurrently.
|
|
51
70
|
|
|
52
71
|
Args:
|
async_tiff/_tile.pyi
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from collections.abc import Buffer
|
|
2
2
|
|
|
3
|
-
from .
|
|
3
|
+
from ._array import Array
|
|
4
4
|
from ._decoder import DecoderRegistry
|
|
5
5
|
from ._thread_pool import ThreadPool
|
|
6
|
+
from .enums import Compression
|
|
6
7
|
|
|
7
8
|
class Tile:
|
|
8
9
|
"""A representation of a TIFF image tile."""
|
|
@@ -16,20 +17,42 @@ class Tile:
|
|
|
16
17
|
def compressed_bytes(self) -> Buffer:
|
|
17
18
|
"""The compressed bytes underlying this tile."""
|
|
18
19
|
@property
|
|
19
|
-
def compression_method(self) ->
|
|
20
|
+
def compression_method(self) -> Compression | int:
|
|
20
21
|
"""The compression method used by this tile."""
|
|
21
|
-
|
|
22
|
+
def decode_sync(
|
|
23
|
+
self,
|
|
24
|
+
*,
|
|
25
|
+
decoder_registry: DecoderRegistry | None = None,
|
|
26
|
+
) -> Array:
|
|
27
|
+
"""Decode this tile's data.
|
|
28
|
+
|
|
29
|
+
**Note**: This is a blocking function and will perform the tile decompression on
|
|
30
|
+
the current thread. Prefer using the asynchronous `decode` method, which will
|
|
31
|
+
offload decompression to a thread pool.
|
|
32
|
+
|
|
33
|
+
Keyword Args:
|
|
34
|
+
decoder_registry: the decoders to use for decompression. Defaults to None, in which case a default decoder registry is used.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
Decoded tile data as an Array instance.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
async def decode(
|
|
22
41
|
self,
|
|
23
42
|
*,
|
|
24
43
|
decoder_registry: DecoderRegistry | None = None,
|
|
25
44
|
pool: ThreadPool | None = None,
|
|
26
|
-
) ->
|
|
45
|
+
) -> Array:
|
|
27
46
|
"""Decode this tile's data.
|
|
28
47
|
|
|
48
|
+
This is an asynchronous function that will offload the tile decompression to a
|
|
49
|
+
thread pool.
|
|
50
|
+
|
|
29
51
|
Keyword Args:
|
|
30
|
-
decoder_registry: the decoders to use for decompression. Defaults to None.
|
|
31
|
-
pool: the thread pool on which to run decompression. Defaults to None
|
|
52
|
+
decoder_registry: the decoders to use for decompression. Defaults to None, in which case a default decoder registry is used.
|
|
53
|
+
pool: the thread pool on which to run decompression. Defaults to None, in
|
|
54
|
+
which case, a default thread pool is used.
|
|
32
55
|
|
|
33
56
|
Returns:
|
|
34
|
-
Decoded tile data as
|
|
57
|
+
Decoded tile data as an Array instance.
|
|
35
58
|
"""
|
async_tiff/enums.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from enum import IntEnum
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
class
|
|
4
|
+
class Compression(IntEnum):
|
|
5
5
|
"""
|
|
6
6
|
See [TIFF compression
|
|
7
7
|
tags](https://www.awaresystems.be/imaging/tiff/tifftags/compression.html) for
|
|
@@ -19,6 +19,14 @@ class CompressionMethod(IntEnum):
|
|
|
19
19
|
Deflate = 8
|
|
20
20
|
OldDeflate = 0x80B2
|
|
21
21
|
PackBits = 0x8005
|
|
22
|
+
WebP = 50001
|
|
23
|
+
JPEG2k = 34712
|
|
24
|
+
ZSTD = 0xC350
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Endianness(IntEnum):
|
|
28
|
+
LittleEndian = 0
|
|
29
|
+
BigEndian = 1
|
|
22
30
|
|
|
23
31
|
|
|
24
32
|
class PhotometricInterpretation(IntEnum):
|
|
@@ -52,5 +60,5 @@ class ResolutionUnit(IntEnum):
|
|
|
52
60
|
class SampleFormat(IntEnum):
|
|
53
61
|
Uint = 1
|
|
54
62
|
Int = 2
|
|
55
|
-
|
|
63
|
+
Float = 3
|
|
56
64
|
Void = 4
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: async-tiff
|
|
3
|
+
Version: 0.5.0b3
|
|
4
|
+
Classifier: Programming Language :: Rust
|
|
5
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
7
|
+
Requires-Dist: obspec>=0.1.0
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
10
|
+
|
|
11
|
+
# async-tiff
|
|
12
|
+
|
|
13
|
+
[![PyPI][pypi_badge]][pypi_link]
|
|
14
|
+
|
|
15
|
+
[pypi_badge]: https://badge.fury.io/py/async-tiff.svg
|
|
16
|
+
[pypi_link]: https://pypi.org/project/async-tiff/
|
|
17
|
+
|
|
18
|
+
Fast, low-level async TIFF reader for Python.
|
|
19
|
+
|
|
20
|
+
This documentation is for the Python bindings. [Refer here for the Rust crate documentation](https://docs.rs/async-tiff).
|
|
21
|
+
|
|
22
|
+
For a higher-level API to read GeoTIFF files, visit [`async-geotiff`][async-geotiff].
|
|
23
|
+
|
|
24
|
+
[async-geotiff]: https://developmentseed.org/async-geotiff
|
|
25
|
+
|
|
26
|
+
## Examples
|
|
27
|
+
|
|
28
|
+
### Reading NAIP
|
|
29
|
+
|
|
30
|
+
```py
|
|
31
|
+
from async_tiff import TIFF
|
|
32
|
+
from async_tiff.store import S3Store
|
|
33
|
+
|
|
34
|
+
# You'll also need to provide credentials to access a requester pays bucket
|
|
35
|
+
store = S3Store("naip-visualization", region="us-west-2", request_payer=True)
|
|
36
|
+
path = "ny/2022/60cm/rgb/40073/m_4007307_sw_18_060_20220803.tif"
|
|
37
|
+
|
|
38
|
+
tiff = await TIFF.open(path, store=store)
|
|
39
|
+
primary_ifd = tiff.ifds[0]
|
|
40
|
+
|
|
41
|
+
primary_ifd.geo_key_directory.citation
|
|
42
|
+
# 'NAD83 / UTM zone 18N'
|
|
43
|
+
|
|
44
|
+
primary_ifd.geo_key_directory.projected_type
|
|
45
|
+
# 26918
|
|
46
|
+
# (EPSG code)
|
|
47
|
+
|
|
48
|
+
primary_ifd.sample_format
|
|
49
|
+
# [<SampleFormat.Uint: 1>, <SampleFormat.Uint: 1>, <SampleFormat.Uint: 1>]
|
|
50
|
+
|
|
51
|
+
primary_ifd.bits_per_sample
|
|
52
|
+
# [8, 8, 8]
|
|
53
|
+
|
|
54
|
+
tile = await tiff.fetch_tile(0, 0, 4)
|
|
55
|
+
array = await tile.decode()
|
|
56
|
+
|
|
57
|
+
# Use rasterio and matplotlib for visualization
|
|
58
|
+
import numpy as np
|
|
59
|
+
from rasterio.plot import reshape_as_raster, show
|
|
60
|
+
|
|
61
|
+
# Zero-copy conversion of the rust array into a numpy array
|
|
62
|
+
np_array = np.asarray(array)
|
|
63
|
+
|
|
64
|
+
# Then we need to reshape the "image" axes into "raster" axes
|
|
65
|
+
# https://rasterio.readthedocs.io/en/stable/topics/image_processing.html
|
|
66
|
+
show(reshape_as_raster(np_array), adjust=True)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+

|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
### Reading Sentinel 2 L2A
|
|
73
|
+
|
|
74
|
+
```py
|
|
75
|
+
import numpy as np
|
|
76
|
+
from async_tiff import TIFF
|
|
77
|
+
from async_tiff.store import S3Store
|
|
78
|
+
|
|
79
|
+
store = S3Store("sentinel-cogs", region="us-west-2", skip_signature=True)
|
|
80
|
+
path = "sentinel-s2-l2a-cogs/12/S/UF/2022/6/S2B_12SUF_20220609_0_L2A/B04.tif"
|
|
81
|
+
|
|
82
|
+
tiff = await TIFF.open(path, store=store)
|
|
83
|
+
primary_ifd = tiff.ifds[0]
|
|
84
|
+
# Text readable citation
|
|
85
|
+
primary_ifd.geo_key_directory.citation
|
|
86
|
+
# EPSG code
|
|
87
|
+
primary_ifd.geo_key_directory.projected_type
|
|
88
|
+
|
|
89
|
+
primary_ifd.sample_format[0]
|
|
90
|
+
# <SampleFormat.Uint: 1>
|
|
91
|
+
primary_ifd.bits_per_sample[0]
|
|
92
|
+
# 16
|
|
93
|
+
|
|
94
|
+
tile = await tiff.fetch_tile(0, 0, 0)
|
|
95
|
+
array = await tile.decode()
|
|
96
|
+
|
|
97
|
+
# Zero-copy conversion of the rust array into a numpy array
|
|
98
|
+
np_array = np.asarray(array)
|
|
99
|
+
np_array.shape
|
|
100
|
+
# (1024, 1024, 1)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
async_tiff/__init__.py,sha256=gdLgfl7BLntXTceX9JdojgOwy_8sH7-YuEuQedBr3o4,559
|
|
2
|
+
async_tiff/_array.pyi,sha256=muitV2BmObMPBF1O1mgo9a89posx7-ubsl4XftG5WO4,1257
|
|
3
|
+
async_tiff/_async_tiff.cpython-310-i386-linux-gnu.so,sha256=NNmD9OkqrhuoGhiaU3VmAd8f1Hxej8mD7hIuW-oiQlU,8454693
|
|
4
|
+
async_tiff/_async_tiff.pyi,sha256=I0Z9ey5GYZYfjJB4ZEyPUzHTsw0GcA5KBrAbTiThMc8,410
|
|
5
|
+
async_tiff/_colormap.pyi,sha256=NrXLqUq3U81bI0zG8OLgQwv_JM0YS-MrVgx-1nD6j3g,402
|
|
6
|
+
async_tiff/_decoder.pyi,sha256=tRHzZbZj1V6lDireFpNQ-f2h2tPFqh2ExYu4L6v0Cqc,709
|
|
7
|
+
async_tiff/_decoder_runtime.py,sha256=N2IC7XTgC1TmGmB7ZXCJbrVVSbn6G85cWgJ6k87XpT8,553
|
|
8
|
+
async_tiff/_geo.pyi,sha256=h71Y9zZ5vYxXaXAR4QAYmBJ0FOhLfXMMJA85p474eTE,3451
|
|
9
|
+
async_tiff/_ifd.pyi,sha256=eKH2FAboDE3B5kK2U45j0RsN5MwD3cUeDVF5WTgu0as,4755
|
|
10
|
+
async_tiff/_input.py,sha256=f6FCam4uyKaWXy-npUQ-nePaXeOsWMdXt2WcyH5fhq0,203
|
|
11
|
+
async_tiff/_thread_pool.pyi,sha256=fbDu9kbo8RNlq7bBBxuuu_6ub20L5cAfXBM-J7Y0PC8,181
|
|
12
|
+
async_tiff/_tiff.pyi,sha256=8MtZcmOPjr72lo8ohNuSwRi9N8YRZBtcjZwwJxEAO0Q,2249
|
|
13
|
+
async_tiff/_tile.pyi,sha256=NBUciMH6nan6qQLt30p9msUiY4BKh4ZmW4r9CsqtYho,1961
|
|
14
|
+
async_tiff/enums.py,sha256=C1XnevNtV_Hp5gTU7pLZRsNAfNx-4nu_f1NpbE1dN0U,1030
|
|
15
|
+
async_tiff/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
+
async_tiff-0.5.0b3.dist-info/METADATA,sha256=QekvFwPmS9FbWFmE-OwnUqxY0TRNawZvV0PIhR3IC74,2741
|
|
17
|
+
async_tiff-0.5.0b3.dist-info/WHEEL,sha256=m4qwANspYwxg7X6tMFtZ2rjrXUcJmbOtzSNlXT6wT80,106
|
|
18
|
+
async_tiff.libs/libgcc_s-8c2f5de4.so.1,sha256=kSGru1K5a_vOr1EMn5GXfvaYMUTnHaCTddYVIrEEuao,552385
|
|
19
|
+
async_tiff-0.5.0b3.dist-info/RECORD,,
|
|
Binary file
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: async-tiff
|
|
3
|
-
Version: 0.2.0
|
|
4
|
-
Classifier: Programming Language :: Rust
|
|
5
|
-
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
|
-
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
7
|
-
Requires-Dist: obspec>=0.1.0b3
|
|
8
|
-
Requires-Python: >=3.10
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
async_tiff-0.2.0.dist-info/METADATA,sha256=MTZP5SVb2oiRdJSDFuOFo_K-kvggjtocqAV0dIh8P94,291
|
|
2
|
-
async_tiff-0.2.0.dist-info/WHEEL,sha256=KdxGmCT1vnjKz72Dgw1YCgFmGKnJ-vtE95WVoeIcDHc,105
|
|
3
|
-
async_tiff.libs/libgcc_s-27e5a392.so.1,sha256=x5sO63liVwXxrjGGP371wB0RyQe1KEnIynYm82T0G0M,449745
|
|
4
|
-
async_tiff/__init__.py,sha256=KTVCBLwRsYMz1f4fe0uVpKPhfymTMGNXe4WKxrqtjcQ,173
|
|
5
|
-
async_tiff/_async_tiff.cpython-310-i386-linux-gnu.so,sha256=SficjOTEe8z4DWklzyQqzKBsg06kbyw4Mx9SboXSBws,7545097
|
|
6
|
-
async_tiff/_async_tiff.pyi,sha256=FBpM_a-AvnhF-eA5_zpKDSLWbh4lEFBTz8FxxzpJBrU,371
|
|
7
|
-
async_tiff/_decoder.pyi,sha256=GezYsb_FpLOG8d7JN4FO3aC_itMwigBr6cF8qzg05M8,1043
|
|
8
|
-
async_tiff/_geo.pyi,sha256=AXmfvki0b04OnECD63PKkcPcxyHudbDRKQVZOCx6K7g,3031
|
|
9
|
-
async_tiff/_ifd.pyi,sha256=61WU6zvY8uxePTc4b2IK_zhRwr4fj3Cc5LpBdRO1QR4,3374
|
|
10
|
-
async_tiff/_thread_pool.pyi,sha256=fbDu9kbo8RNlq7bBBxuuu_6ub20L5cAfXBM-J7Y0PC8,181
|
|
11
|
-
async_tiff/_tiff.pyi,sha256=rCt3O3TYeMTI9-ydO1eepO7UNV1rsDrg1MmDMdVoFu4,1689
|
|
12
|
-
async_tiff/_tile.pyi,sha256=GzmAw-ysBx_s0JuQsY0AmF7UFDK_NIUMv3xubCATt2U,1102
|
|
13
|
-
async_tiff/enums.py,sha256=y6kPfRJX9I7J8AwBBuO0mFI3uWfMSY6hmKEGRXbpDSI,915
|
|
14
|
-
async_tiff/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
async_tiff-0.2.0.dist-info/RECORD,,
|
|
Binary file
|