iccdev 0.1.0__cp313-cp313-win_amd64.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.
iccdev/__init__.py ADDED
@@ -0,0 +1,110 @@
1
+ # iccdev - Python bindings for RefIccMAX / iccDEV
2
+ #
3
+ # Copyright (c) International Color Consortium.
4
+ # BSD 3-Clause License. See LICENSE.md for details.
5
+
6
+ """
7
+ Python bindings for the RefIccMAX (iccDEV) ICC color profile library.
8
+
9
+ Provides Pythonic access to ICC profile reading, color management,
10
+ and color space transformations via Cython wrappers around IccProfLib.
11
+
12
+ Quick start::
13
+
14
+ import iccdev
15
+
16
+ # Read a profile
17
+ profile = iccdev.IccProfile("sRGB.icc")
18
+ header = profile.header
19
+ print(header.version_string)
20
+
21
+ # Apply a color transform
22
+ cmm = iccdev.IccCmm()
23
+ cmm.attach("input.icc", intent=iccdev.Intent.Perceptual)
24
+ cmm.attach("output.icc")
25
+ cmm.begin()
26
+ result = cmm.apply([0.5, 0.3, 0.1])
27
+ """
28
+
29
+ __version__ = "0.1.0"
30
+
31
+ from iccdev._iccdev import (
32
+ # Classes
33
+ IccProfile,
34
+ IccCmm,
35
+ IccApply,
36
+ IccProfileHeader,
37
+ ValidationResult,
38
+ # Exceptions
39
+ IccError,
40
+ IccProfileError,
41
+ IccCmmError,
42
+ # Enums
43
+ ColorSpace,
44
+ ProfileClass,
45
+ RenderingIntent,
46
+ Interpolation,
47
+ LutType,
48
+ CmmStatus,
49
+ ValidationStatus,
50
+ # Convenience functions
51
+ sig_to_str,
52
+ open_profile,
53
+ read_profile,
54
+ validate_profile,
55
+ validate_profile_file,
56
+ )
57
+ from iccdev.cli import (
58
+ IccToolError,
59
+ available_tools,
60
+ dump_profile,
61
+ find_tool,
62
+ heif_dump,
63
+ icc_from_json,
64
+ icc_from_xml,
65
+ icc_to_json,
66
+ icc_to_xml,
67
+ round_trip,
68
+ )
69
+
70
+ # Short alias for RenderingIntent
71
+ Intent = RenderingIntent
72
+
73
+ __all__ = [
74
+ # Classes
75
+ "IccProfile",
76
+ "IccCmm",
77
+ "IccApply",
78
+ "IccProfileHeader",
79
+ "ValidationResult",
80
+ # Exceptions
81
+ "IccError",
82
+ "IccProfileError",
83
+ "IccCmmError",
84
+ # Enums
85
+ "ColorSpace",
86
+ "ProfileClass",
87
+ "RenderingIntent",
88
+ "Intent",
89
+ "Interpolation",
90
+ "LutType",
91
+ "CmmStatus",
92
+ "ValidationStatus",
93
+ # Functions
94
+ "sig_to_str",
95
+ "open_profile",
96
+ "read_profile",
97
+ "validate_profile",
98
+ "validate_profile_file",
99
+ # CLI-backed helpers
100
+ "IccToolError",
101
+ "available_tools",
102
+ "find_tool",
103
+ "heif_dump",
104
+ "icc_to_xml",
105
+ "icc_from_xml",
106
+ "icc_to_json",
107
+ "icc_from_json",
108
+ "dump_profile",
109
+ "round_trip",
110
+ ]
Binary file
iccdev/_iccdev.pyi ADDED
@@ -0,0 +1,299 @@
1
+ """Type stubs for iccdev._iccdev (Cython extension)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import enum
6
+ import os
7
+ from collections.abc import Sequence
8
+ from typing import NamedTuple, Optional, Union
9
+
10
+ # NumPy is optional
11
+ try:
12
+ import numpy as np
13
+ import numpy.typing as npt
14
+ except ImportError:
15
+ np = None # type: ignore[assignment]
16
+ npt = None # type: ignore[assignment]
17
+
18
+
19
+ # ---------------------------------------------------------------------------
20
+ # Enums
21
+ # ---------------------------------------------------------------------------
22
+
23
+ class ColorSpace(enum.IntEnum):
24
+ XYZ = ...
25
+ Lab = ...
26
+ Luv = ...
27
+ YCbCr = ...
28
+ Yxy = ...
29
+ RGB = ...
30
+ Gray = ...
31
+ HSV = ...
32
+ HLS = ...
33
+ CMYK = ...
34
+ CMY = ...
35
+ CLR1 = ...
36
+ CLR2 = ...
37
+ CLR3 = ...
38
+ CLR4 = ...
39
+ CLR5 = ...
40
+ CLR6 = ...
41
+ CLR7 = ...
42
+ CLR8 = ...
43
+ CLR9 = ...
44
+ CLR10 = ...
45
+ CLR11 = ...
46
+ CLR12 = ...
47
+ CLR13 = ...
48
+ CLR14 = ...
49
+ CLR15 = ...
50
+ Named = ...
51
+ NChannel = ...
52
+ DevLab = ...
53
+ DevXYZ = ...
54
+ Gamut = ...
55
+ Unknown = ...
56
+
57
+ @classmethod
58
+ def from_sig(cls, sig: int) -> ColorSpace: ...
59
+
60
+ class ProfileClass(enum.IntEnum):
61
+ Input = ...
62
+ Display = ...
63
+ Output = ...
64
+ Link = ...
65
+ Abstract = ...
66
+ ColorSpace = ...
67
+ NamedColor = ...
68
+ ColorEncoding = ...
69
+ MaterialID = ...
70
+ MaterialLink = ...
71
+ MaterialVis = ...
72
+
73
+ class RenderingIntent(enum.IntEnum):
74
+ Perceptual = ...
75
+ RelativeColorimetric = ...
76
+ Saturation = ...
77
+ AbsoluteColorimetric = ...
78
+
79
+ Intent = RenderingIntent
80
+
81
+ class Interpolation(enum.IntEnum):
82
+ Linear = ...
83
+ Tetrahedral = ...
84
+
85
+ class LutType(enum.IntEnum):
86
+ Color = ...
87
+ NamedColor = ...
88
+ Preview = ...
89
+ Gamut = ...
90
+ BPC = ...
91
+ BRDFParam = ...
92
+ BRDFDirect = ...
93
+ BRDFMcsParam = ...
94
+ MCS = ...
95
+ Colorimetric = ...
96
+ Spectral = ...
97
+
98
+ class CmmStatus(enum.IntEnum):
99
+ Bad = ...
100
+ Ok = ...
101
+ CantOpenProfile = ...
102
+ BadSpaceLink = ...
103
+ InvalidProfile = ...
104
+ BadXform = ...
105
+ InvalidLut = ...
106
+ ProfileMissingTag = ...
107
+ ColorNotFound = ...
108
+ IncorrectApply = ...
109
+ BadColorEncoding = ...
110
+ AllocErr = ...
111
+ BadLutType = ...
112
+ IdentityXform = ...
113
+ UnsupportedPcsLink = ...
114
+ BadConnection = ...
115
+ BadTintXform = ...
116
+ TooManySamples = ...
117
+ BadMCSLink = ...
118
+ Unsupported = ...
119
+ UnsupportedProfileClass = ...
120
+ CantAdjustPcs = ...
121
+
122
+ class ValidationStatus(enum.IntEnum):
123
+ OK = ...
124
+ WARNING = ...
125
+ NON_COMPLIANT = ...
126
+ CRITICAL_ERROR = ...
127
+ INVALID_ARGUMENT = ...
128
+ INTERNAL_ERROR = ...
129
+
130
+ class ValidationResult(NamedTuple):
131
+ status: ValidationStatus
132
+ report: str
133
+
134
+
135
+ # ---------------------------------------------------------------------------
136
+ # Exceptions
137
+ # ---------------------------------------------------------------------------
138
+
139
+ class IccError(Exception):
140
+ status: int
141
+ status_code: int # backward compat alias
142
+ status_name: str
143
+ def __init__(self, message: str, status: int = -1) -> None: ...
144
+
145
+ class IccProfileError(IccError): ...
146
+ class IccCmmError(IccError): ...
147
+
148
+
149
+ # ---------------------------------------------------------------------------
150
+ # IccProfileHeader (named tuple)
151
+ # ---------------------------------------------------------------------------
152
+
153
+ class IccProfileHeader(NamedTuple):
154
+ size: int
155
+ cmm_id: int
156
+ version: int
157
+ device_class: int
158
+ color_space: int
159
+ pcs: int
160
+ date: dict[str, int]
161
+ magic: int
162
+ platform: int
163
+ flags: int
164
+ manufacturer: int
165
+ model: int
166
+ attributes: int
167
+ rendering_intent: int
168
+ illuminant: dict[str, float]
169
+ creator: int
170
+ profile_id: bytes
171
+ spectral_pcs: int
172
+ spectral_range: dict[str, int]
173
+ bi_spectral_range: dict[str, int]
174
+ mcs: int
175
+ device_sub_class: int
176
+
177
+ @property
178
+ def version_string(self) -> str: ...
179
+ @property
180
+ def color_space_name(self) -> str: ...
181
+ @property
182
+ def pcs_name(self) -> str: ...
183
+ @property
184
+ def device_class_name(self) -> str: ...
185
+ @property
186
+ def rendering_intent_name(self) -> str: ...
187
+ @property
188
+ def platform_name(self) -> str: ...
189
+
190
+
191
+ # ---------------------------------------------------------------------------
192
+ # IccProfile
193
+ # ---------------------------------------------------------------------------
194
+
195
+ class IccProfile:
196
+ def __init__(self, path: Optional[Union[str, bytes, os.PathLike[str], os.PathLike[bytes]]] = None, *, lazy: bool = True) -> None: ...
197
+ def close(self) -> None: ...
198
+ def __enter__(self) -> IccProfile: ...
199
+ def __exit__(self, exc_type: object, exc_val: object, exc_tb: object) -> bool: ...
200
+ def __bool__(self) -> bool: ...
201
+
202
+ @property
203
+ def is_valid(self) -> bool: ...
204
+ @property
205
+ def header(self) -> IccProfileHeader: ...
206
+ @property
207
+ def color_space(self) -> ColorSpace: ...
208
+ @property
209
+ def pcs(self) -> ColorSpace: ...
210
+ @property
211
+ def device_class(self) -> Union[ProfileClass, int]: ...
212
+ @property
213
+ def version_string(self) -> str: ...
214
+ @property
215
+ def is_v5(self) -> bool: ...
216
+
217
+
218
+ # ---------------------------------------------------------------------------
219
+ # IccApply
220
+ # ---------------------------------------------------------------------------
221
+
222
+ class IccApply:
223
+ def close(self) -> None: ...
224
+ def __enter__(self) -> IccApply: ...
225
+ def __exit__(self, exc_type: object, exc_val: object, exc_tb: object) -> bool: ...
226
+ def __bool__(self) -> bool: ...
227
+
228
+ def apply(self, pixel: Sequence[float]) -> list[float]: ...
229
+ def apply_multi(self, pixels: Sequence[Sequence[float]]) -> list[list[float]]: ...
230
+ def apply_ndarray(self, pixels: np.ndarray) -> np.ndarray: ...
231
+
232
+ @property
233
+ def src_channels(self) -> int: ...
234
+ @property
235
+ def dst_channels(self) -> int: ...
236
+
237
+
238
+ # ---------------------------------------------------------------------------
239
+ # IccCmm
240
+ # ---------------------------------------------------------------------------
241
+
242
+ class IccCmm:
243
+ def __init__(
244
+ self,
245
+ src_space: Union[ColorSpace, int] = ...,
246
+ dst_space: Union[ColorSpace, int] = ...,
247
+ first_is_input: bool = True,
248
+ ) -> None: ...
249
+
250
+ def close(self) -> None: ...
251
+ def __enter__(self) -> IccCmm: ...
252
+ def __exit__(self, exc_type: object, exc_val: object, exc_tb: object) -> bool: ...
253
+ def __bool__(self) -> bool: ...
254
+
255
+ def attach(
256
+ self,
257
+ path: Union[str, bytes, os.PathLike[str], os.PathLike[bytes]],
258
+ *,
259
+ intent: Union[RenderingIntent, int] = ...,
260
+ interp: Union[Interpolation, int] = ...,
261
+ lut_type: Union[LutType, int] = ...,
262
+ use_d2b: bool = True,
263
+ use_bpc: bool = False,
264
+ ) -> None: ...
265
+
266
+ def attach_profile(
267
+ self,
268
+ path: Union[str, bytes, os.PathLike[str], os.PathLike[bytes]],
269
+ **kwargs: object,
270
+ ) -> None: ...
271
+
272
+ def begin(self) -> None: ...
273
+ def get_apply(self) -> IccApply: ...
274
+
275
+ def apply(self, pixel: Sequence[float]) -> list[float]: ...
276
+ def apply_multi(self, pixels: Sequence[Sequence[float]]) -> list[list[float]]: ...
277
+ def apply_ndarray(self, pixels: np.ndarray) -> np.ndarray: ...
278
+
279
+ @property
280
+ def src_space(self) -> ColorSpace: ...
281
+ @property
282
+ def dst_space(self) -> ColorSpace: ...
283
+ @property
284
+ def src_channels(self) -> int: ...
285
+ @property
286
+ def dst_channels(self) -> int: ...
287
+ @property
288
+ def is_ready(self) -> bool: ...
289
+
290
+
291
+ # ---------------------------------------------------------------------------
292
+ # Module-level functions
293
+ # ---------------------------------------------------------------------------
294
+
295
+ def sig_to_str(sig: int) -> str: ...
296
+ def open_profile(path: Union[str, bytes, os.PathLike[str], os.PathLike[bytes]], *, lazy: bool = True) -> IccProfile: ...
297
+ def read_profile(path: Union[str, bytes, os.PathLike[str], os.PathLike[bytes]]) -> IccProfile: ...
298
+ def validate_profile(profile: Union[bytes, bytearray, memoryview]) -> ValidationResult: ...
299
+ def validate_profile_file(path: Union[str, bytes, os.PathLike[str], os.PathLike[bytes]]) -> ValidationResult: ...