Skip to content

Commit 883b388

Browse files
authored
Defne binding for ImageFileDirectory and GeoKeyDirectory (#16)
1 parent 52e1286 commit 883b388

File tree

9 files changed

+786
-26
lines changed

9 files changed

+786
-26
lines changed

python/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ bytes = "1.8"
2222
pyo3 = { version = "0.23.0", features = ["macros"] }
2323
pyo3-bytes = "0.1.2"
2424
thiserror = "1"
25+
tiff = "0.9.1"
2526

2627
[profile.release]
2728
lto = true

python/python/async_tiff/enums.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from enum import IntEnum
2+
3+
4+
class CompressionMethod(IntEnum):
5+
"""
6+
See [TIFF compression
7+
tags](https://www.awaresystems.be/imaging/tiff/tifftags/compression.html) for
8+
reference.
9+
"""
10+
11+
Uncompressed = 1
12+
Huffman = 2
13+
Fax3 = 3
14+
Fax4 = 4
15+
LZW = 5
16+
JPEG = 6
17+
# // "Extended JPEG" or "new JPEG" style
18+
ModernJPEG = 7
19+
Deflate = 8
20+
OldDeflate = 0x80B2
21+
PackBits = 0x8005
22+
23+
24+
class PhotometricInterpretation(IntEnum):
25+
WhiteIsZero = 0
26+
BlackIsZero = 1
27+
RGB = 2
28+
RGBPalette = 3
29+
TransparencyMask = 4
30+
CMYK = 5
31+
YCbCr = 6
32+
CIELab = 8
33+
34+
35+
class PlanarConfiguration(IntEnum):
36+
Chunky = 1
37+
Planar = 2
38+
39+
40+
class Predictor(IntEnum):
41+
Unknown = 1
42+
Horizontal = 2
43+
FloatingPoint = 3
44+
45+
46+
class ResolutionUnit(IntEnum):
47+
Unknown = 1
48+
Inch = 2
49+
Centimeter = 3
50+
51+
52+
class SampleFormat(IntEnum):
53+
Uint = 1
54+
Int = 2
55+
IEEEFP = 3
56+
Void = 4

python/src/enums.rs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
use pyo3::intern;
2+
use pyo3::prelude::*;
3+
use pyo3::types::{PyString, PyTuple};
4+
use tiff::tags::{
5+
CompressionMethod, PhotometricInterpretation, PlanarConfiguration, Predictor, ResolutionUnit,
6+
SampleFormat,
7+
};
8+
9+
pub(crate) struct PyCompressionMethod(CompressionMethod);
10+
11+
impl From<CompressionMethod> for PyCompressionMethod {
12+
fn from(value: CompressionMethod) -> Self {
13+
Self(value)
14+
}
15+
}
16+
17+
impl<'py> IntoPyObject<'py> for PyCompressionMethod {
18+
type Target = PyAny;
19+
type Output = Bound<'py, PyAny>;
20+
type Error = PyErr;
21+
22+
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
23+
to_py_enum_variant(py, intern!(py, "CompressionMethod"), self.0.to_u16())
24+
}
25+
}
26+
27+
pub(crate) struct PyPhotometricInterpretation(PhotometricInterpretation);
28+
29+
impl From<PhotometricInterpretation> for PyPhotometricInterpretation {
30+
fn from(value: PhotometricInterpretation) -> Self {
31+
Self(value)
32+
}
33+
}
34+
35+
impl<'py> IntoPyObject<'py> for PyPhotometricInterpretation {
36+
type Target = PyAny;
37+
type Output = Bound<'py, PyAny>;
38+
type Error = PyErr;
39+
40+
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
41+
to_py_enum_variant(
42+
py,
43+
intern!(py, "PhotometricInterpretation"),
44+
self.0.to_u16(),
45+
)
46+
}
47+
}
48+
49+
pub(crate) struct PyPlanarConfiguration(PlanarConfiguration);
50+
51+
impl From<PlanarConfiguration> for PyPlanarConfiguration {
52+
fn from(value: PlanarConfiguration) -> Self {
53+
Self(value)
54+
}
55+
}
56+
57+
impl<'py> IntoPyObject<'py> for PyPlanarConfiguration {
58+
type Target = PyAny;
59+
type Output = Bound<'py, PyAny>;
60+
type Error = PyErr;
61+
62+
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
63+
to_py_enum_variant(py, intern!(py, "PlanarConfiguration"), self.0.to_u16())
64+
}
65+
}
66+
67+
pub(crate) struct PyResolutionUnit(ResolutionUnit);
68+
69+
impl From<ResolutionUnit> for PyResolutionUnit {
70+
fn from(value: ResolutionUnit) -> Self {
71+
Self(value)
72+
}
73+
}
74+
75+
impl<'py> IntoPyObject<'py> for PyResolutionUnit {
76+
type Target = PyAny;
77+
type Output = Bound<'py, PyAny>;
78+
type Error = PyErr;
79+
80+
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
81+
to_py_enum_variant(py, intern!(py, "ResolutionUnit"), self.0.to_u16())
82+
}
83+
}
84+
85+
pub(crate) struct PyPredictor(Predictor);
86+
87+
impl From<Predictor> for PyPredictor {
88+
fn from(value: Predictor) -> Self {
89+
Self(value)
90+
}
91+
}
92+
93+
impl<'py> IntoPyObject<'py> for PyPredictor {
94+
type Target = PyAny;
95+
type Output = Bound<'py, PyAny>;
96+
type Error = PyErr;
97+
98+
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
99+
to_py_enum_variant(py, intern!(py, "Predictor"), self.0.to_u16())
100+
}
101+
}
102+
103+
pub(crate) struct PySampleFormat(SampleFormat);
104+
105+
impl From<SampleFormat> for PySampleFormat {
106+
fn from(value: SampleFormat) -> Self {
107+
Self(value)
108+
}
109+
}
110+
111+
impl<'py> IntoPyObject<'py> for PySampleFormat {
112+
type Target = PyAny;
113+
type Output = Bound<'py, PyAny>;
114+
type Error = PyErr;
115+
116+
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
117+
to_py_enum_variant(py, intern!(py, "SampleFormat"), self.0.to_u16())
118+
}
119+
}
120+
fn to_py_enum_variant<'py>(
121+
py: Python<'py>,
122+
enum_name: &Bound<'py, PyString>,
123+
value: u16,
124+
) -> PyResult<Bound<'py, PyAny>> {
125+
let enums_mod = py.import(intern!(py, "async_tiff.enums"))?;
126+
enums_mod.call_method1(enum_name, PyTuple::new(py, vec![value])?)
127+
}

python/src/geo.rs

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
use async_tiff::geo::GeoKeyDirectory;
2+
use pyo3::prelude::*;
3+
4+
#[pyclass(name = "GeoKeyDirectory")]
5+
pub(crate) struct PyGeoKeyDirectory {
6+
#[pyo3(get)]
7+
model_type: Option<u16>,
8+
#[pyo3(get)]
9+
raster_type: Option<u16>,
10+
#[pyo3(get)]
11+
citation: Option<String>,
12+
#[pyo3(get)]
13+
geographic_type: Option<u16>,
14+
#[pyo3(get)]
15+
geog_citation: Option<String>,
16+
#[pyo3(get)]
17+
geog_geodetic_datum: Option<u16>,
18+
#[pyo3(get)]
19+
geog_prime_meridian: Option<u16>,
20+
#[pyo3(get)]
21+
geog_linear_units: Option<u16>,
22+
#[pyo3(get)]
23+
geog_linear_unit_size: Option<f64>,
24+
#[pyo3(get)]
25+
geog_angular_units: Option<u16>,
26+
#[pyo3(get)]
27+
geog_angular_unit_size: Option<f64>,
28+
#[pyo3(get)]
29+
geog_ellipsoid: Option<u16>,
30+
#[pyo3(get)]
31+
geog_semi_major_axis: Option<f64>,
32+
#[pyo3(get)]
33+
geog_semi_minor_axis: Option<f64>,
34+
#[pyo3(get)]
35+
geog_inv_flattening: Option<f64>,
36+
#[pyo3(get)]
37+
geog_azimuth_units: Option<u16>,
38+
#[pyo3(get)]
39+
geog_prime_meridian_long: Option<f64>,
40+
41+
#[pyo3(get)]
42+
projected_type: Option<u16>,
43+
#[pyo3(get)]
44+
proj_citation: Option<String>,
45+
#[pyo3(get)]
46+
projection: Option<u16>,
47+
#[pyo3(get)]
48+
proj_coord_trans: Option<u16>,
49+
#[pyo3(get)]
50+
proj_linear_units: Option<u16>,
51+
#[pyo3(get)]
52+
proj_linear_unit_size: Option<f64>,
53+
#[pyo3(get)]
54+
proj_std_parallel1: Option<f64>,
55+
#[pyo3(get)]
56+
proj_std_parallel2: Option<f64>,
57+
#[pyo3(get)]
58+
proj_nat_origin_long: Option<f64>,
59+
#[pyo3(get)]
60+
proj_nat_origin_lat: Option<f64>,
61+
#[pyo3(get)]
62+
proj_false_easting: Option<f64>,
63+
#[pyo3(get)]
64+
proj_false_northing: Option<f64>,
65+
#[pyo3(get)]
66+
proj_false_origin_long: Option<f64>,
67+
#[pyo3(get)]
68+
proj_false_origin_lat: Option<f64>,
69+
#[pyo3(get)]
70+
proj_false_origin_easting: Option<f64>,
71+
#[pyo3(get)]
72+
proj_false_origin_northing: Option<f64>,
73+
#[pyo3(get)]
74+
proj_center_long: Option<f64>,
75+
#[pyo3(get)]
76+
proj_center_lat: Option<f64>,
77+
#[pyo3(get)]
78+
proj_center_easting: Option<f64>,
79+
#[pyo3(get)]
80+
proj_center_northing: Option<f64>,
81+
#[pyo3(get)]
82+
proj_scale_at_nat_origin: Option<f64>,
83+
#[pyo3(get)]
84+
proj_scale_at_center: Option<f64>,
85+
#[pyo3(get)]
86+
proj_azimuth_angle: Option<f64>,
87+
#[pyo3(get)]
88+
proj_straight_vert_pole_long: Option<f64>,
89+
90+
#[pyo3(get)]
91+
vertical: Option<u16>,
92+
#[pyo3(get)]
93+
vertical_citation: Option<String>,
94+
#[pyo3(get)]
95+
vertical_datum: Option<u16>,
96+
#[pyo3(get)]
97+
vertical_units: Option<u16>,
98+
}
99+
100+
impl From<PyGeoKeyDirectory> for GeoKeyDirectory {
101+
fn from(value: PyGeoKeyDirectory) -> Self {
102+
Self {
103+
model_type: value.model_type,
104+
raster_type: value.raster_type,
105+
citation: value.citation,
106+
geographic_type: value.geographic_type,
107+
geog_citation: value.geog_citation,
108+
geog_geodetic_datum: value.geog_geodetic_datum,
109+
geog_prime_meridian: value.geog_prime_meridian,
110+
geog_linear_units: value.geog_linear_units,
111+
geog_linear_unit_size: value.geog_linear_unit_size,
112+
geog_angular_units: value.geog_angular_units,
113+
geog_angular_unit_size: value.geog_angular_unit_size,
114+
geog_ellipsoid: value.geog_ellipsoid,
115+
geog_semi_major_axis: value.geog_semi_major_axis,
116+
geog_semi_minor_axis: value.geog_semi_minor_axis,
117+
geog_inv_flattening: value.geog_inv_flattening,
118+
geog_azimuth_units: value.geog_azimuth_units,
119+
geog_prime_meridian_long: value.geog_prime_meridian_long,
120+
projected_type: value.projected_type,
121+
proj_citation: value.proj_citation,
122+
projection: value.projection,
123+
proj_coord_trans: value.proj_coord_trans,
124+
proj_linear_units: value.proj_linear_units,
125+
proj_linear_unit_size: value.proj_linear_unit_size,
126+
proj_std_parallel1: value.proj_std_parallel1,
127+
proj_std_parallel2: value.proj_std_parallel2,
128+
proj_nat_origin_long: value.proj_nat_origin_long,
129+
proj_nat_origin_lat: value.proj_nat_origin_lat,
130+
proj_false_easting: value.proj_false_easting,
131+
proj_false_northing: value.proj_false_northing,
132+
proj_false_origin_long: value.proj_false_origin_long,
133+
proj_false_origin_lat: value.proj_false_origin_lat,
134+
proj_false_origin_easting: value.proj_false_origin_easting,
135+
proj_false_origin_northing: value.proj_false_origin_northing,
136+
proj_center_long: value.proj_center_long,
137+
proj_center_lat: value.proj_center_lat,
138+
proj_center_easting: value.proj_center_easting,
139+
proj_center_northing: value.proj_center_northing,
140+
proj_scale_at_nat_origin: value.proj_scale_at_nat_origin,
141+
proj_scale_at_center: value.proj_scale_at_center,
142+
proj_azimuth_angle: value.proj_azimuth_angle,
143+
proj_straight_vert_pole_long: value.proj_straight_vert_pole_long,
144+
vertical: value.vertical,
145+
vertical_citation: value.vertical_citation,
146+
vertical_datum: value.vertical_datum,
147+
vertical_units: value.vertical_units,
148+
}
149+
}
150+
}
151+
152+
impl From<GeoKeyDirectory> for PyGeoKeyDirectory {
153+
fn from(value: GeoKeyDirectory) -> Self {
154+
Self {
155+
model_type: value.model_type,
156+
raster_type: value.raster_type,
157+
citation: value.citation,
158+
geographic_type: value.geographic_type,
159+
geog_citation: value.geog_citation,
160+
geog_geodetic_datum: value.geog_geodetic_datum,
161+
geog_prime_meridian: value.geog_prime_meridian,
162+
geog_linear_units: value.geog_linear_units,
163+
geog_linear_unit_size: value.geog_linear_unit_size,
164+
geog_angular_units: value.geog_angular_units,
165+
geog_angular_unit_size: value.geog_angular_unit_size,
166+
geog_ellipsoid: value.geog_ellipsoid,
167+
geog_semi_major_axis: value.geog_semi_major_axis,
168+
geog_semi_minor_axis: value.geog_semi_minor_axis,
169+
geog_inv_flattening: value.geog_inv_flattening,
170+
geog_azimuth_units: value.geog_azimuth_units,
171+
geog_prime_meridian_long: value.geog_prime_meridian_long,
172+
projected_type: value.projected_type,
173+
proj_citation: value.proj_citation,
174+
projection: value.projection,
175+
proj_coord_trans: value.proj_coord_trans,
176+
proj_linear_units: value.proj_linear_units,
177+
proj_linear_unit_size: value.proj_linear_unit_size,
178+
proj_std_parallel1: value.proj_std_parallel1,
179+
proj_std_parallel2: value.proj_std_parallel2,
180+
proj_nat_origin_long: value.proj_nat_origin_long,
181+
proj_nat_origin_lat: value.proj_nat_origin_lat,
182+
proj_false_easting: value.proj_false_easting,
183+
proj_false_northing: value.proj_false_northing,
184+
proj_false_origin_long: value.proj_false_origin_long,
185+
proj_false_origin_lat: value.proj_false_origin_lat,
186+
proj_false_origin_easting: value.proj_false_origin_easting,
187+
proj_false_origin_northing: value.proj_false_origin_northing,
188+
proj_center_long: value.proj_center_long,
189+
proj_center_lat: value.proj_center_lat,
190+
proj_center_easting: value.proj_center_easting,
191+
proj_center_northing: value.proj_center_northing,
192+
proj_scale_at_nat_origin: value.proj_scale_at_nat_origin,
193+
proj_scale_at_center: value.proj_scale_at_center,
194+
proj_azimuth_angle: value.proj_azimuth_angle,
195+
proj_straight_vert_pole_long: value.proj_straight_vert_pole_long,
196+
vertical: value.vertical,
197+
vertical_citation: value.vertical_citation,
198+
vertical_datum: value.vertical_datum,
199+
vertical_units: value.vertical_units,
200+
}
201+
}
202+
}

0 commit comments

Comments
 (0)