1from _typeshed import SupportsRead, SupportsWrite
2from collections.abc import Iterable, Iterator, MutableMapping
3from pathlib import Path
4from typing import Any, Callable, Protocol, Sequence, SupportsBytes, Union
5from typing_extensions import Literal
6
7from ._imaging import (
8    DEFAULT_STRATEGY as DEFAULT_STRATEGY,
9    FILTERED as FILTERED,
10    FIXED as FIXED,
11    HUFFMAN_ONLY as HUFFMAN_ONLY,
12    RLE as RLE,
13)
14from .ImageFilter import Filter
15from .ImagePalette import ImagePalette
16
17_Mode = Literal["1", "CMYK", "F", "HSV", "I", "L", "LAB", "P", "RGB", "RGBA", "RGBX", "YCbCr"]
18_Resample = Literal[0, 1, 2, 3, 4, 5]
19_Size = tuple[int, int]
20_Box = tuple[int, int, int, int]
21
22_ConversionMatrix = Union[
23    tuple[float, float, float, float], tuple[float, float, float, float, float, float, float, float, float, float, float, float],
24]
25_Color = Union[float, tuple[float, ...]]
26
27class _Writeable(SupportsWrite[bytes], Protocol):
28    def seek(self, __offset: int) -> Any: ...
29
30# obsolete
31NORMAL: Literal[0]
32SEQUENCE: Literal[1]
33CONTAINER: Literal[2]
34
35class DecompressionBombWarning(RuntimeWarning): ...
36class DecompressionBombError(Exception): ...
37
38MAX_IMAGE_PIXELS: int
39
40NONE: Literal[0]
41
42FLIP_LEFT_RIGHT: Literal[0]
43FLIP_TOP_BOTTOM: Literal[1]
44ROTATE_90: Literal[2]
45ROTATE_180: Literal[3]
46ROTATE_270: Literal[4]
47TRANSPOSE: Literal[5]
48TRANSVERSE: Literal[6]
49
50AFFINE: Literal[0]
51EXTENT: Literal[1]
52PERSPECTIVE: Literal[2]
53QUAD: Literal[3]
54MESH: Literal[4]
55
56NEAREST: Literal[0]
57BOX: Literal[4]
58BILINEAR: Literal[2]
59LINEAR: Literal[2]
60HAMMING: Literal[5]
61BICUBIC: Literal[3]
62CUBIC: Literal[3]
63LANCZOS: Literal[1]
64ANTIALIAS: Literal[1]
65
66ORDERED: Literal[1]
67RASTERIZE: Literal[2]
68FLOYDSTEINBERG: Literal[3]
69
70WEB: Literal[0]
71ADAPTIVE: Literal[1]
72
73MEDIANCUT: Literal[0]
74MAXCOVERAGE: Literal[1]
75FASTOCTREE: Literal[2]
76LIBIMAGEQUANT: Literal[3]
77
78ID: list[str]
79OPEN: dict[str, Any]
80MIME: dict[str, str]
81SAVE: dict[str, Any]
82SAVE_ALL: dict[str, Any]
83EXTENSION: dict[str, str]
84DECODERS: dict[str, Any]
85ENCODERS: dict[str, Any]
86
87MODES: list[_Mode]
88
89def getmodebase(mode: _Mode) -> Literal["L", "RGB"]: ...
90def getmodetype(mode: _Mode) -> Literal["L", "I", "F"]: ...
91def getmodebandnames(mode: _Mode) -> tuple[str, ...]: ...
92def getmodebands(mode: _Mode) -> int: ...
93def preinit() -> None: ...
94def init() -> None: ...
95def coerce_e(value) -> _E: ...
96
97class _E:
98    def __init__(self, data) -> None: ...
99    def __add__(self, other) -> _E: ...
100    def __mul__(self, other) -> _E: ...
101
102_ImageState = tuple[dict[str, Any], str, tuple[int, int], Any, bytes]
103
104class Image:
105    format: Any
106    format_description: Any
107    im: Any
108    mode: str
109    palette: Any
110    info: dict[Any, Any]
111    readonly: int
112    pyaccess: Any
113    @property
114    def width(self) -> int: ...
115    @property
116    def height(self) -> int: ...
117    @property
118    def size(self) -> tuple[int, int]: ...
119    def __enter__(self) -> Image: ...
120    def __exit__(self, *args: Any) -> None: ...
121    def close(self) -> None: ...
122    def __eq__(self, other: object) -> bool: ...
123    def __array__(self, dtype=...) -> Any: ...  # returns numpy.array()
124    def __getstate__(self) -> _ImageState: ...
125    def __setstate__(self, state: _ImageState) -> None: ...
126    def tobytes(self, encoder_name: str = ..., *args) -> bytes: ...
127    def tobitmap(self, name: str = ...) -> bytes: ...
128    def frombytes(self, data: bytes, decoder_name: str = ..., *args) -> None: ...
129    def load(self) -> None: ...
130    def verify(self) -> None: ...
131    def convert(
132        self,
133        mode: str | None = ...,
134        matrix: _ConversionMatrix | None = ...,
135        dither: int | None = ...,
136        palette: Literal[0, 1] = ...,
137        colors: int = ...,
138    ) -> Image: ...
139    def quantize(
140        self,
141        colors: int = ...,
142        method: Literal[0, 1, 2, 3] | None = ...,
143        kmeans: int = ...,
144        palette: Image | None = ...,
145        dither: int = ...,
146    ) -> Image: ...
147    def copy(self) -> Image: ...
148    __copy__ = copy
149    def crop(self, box: _Box | None = ...) -> Image: ...
150    def draft(self, mode: str, size: _Size) -> None: ...
151    def filter(self, filter: Filter | Callable[[], Filter]) -> Image: ...
152    def getbands(self) -> tuple[str, ...]: ...
153    def getbbox(self) -> tuple[int, int, int, int] | None: ...
154    def getcolors(self, maxcolors: int = ...) -> list[tuple[int, int]]: ...
155    def getdata(self, band: int | None = ...): ...
156    def getextrema(self): ...
157    def getexif(self) -> Exif: ...
158    def getim(self): ...
159    def getpalette(self) -> list[int] | None: ...
160    def getpixel(self, xy: tuple[int, int]): ...
161    def getprojection(self) -> tuple[list[int], list[int]]: ...
162    def histogram(self, mask: Image | None = ..., extrema: tuple[int, int] | tuple[float, float] | None = ...) -> list[int]: ...
163    def entropy(self, mask: Image | None = ..., extrema: tuple[int, int] | tuple[float, float] | None = ...) -> float: ...
164    def paste(self, im: Image, box: tuple[float, float] | _Box | None = ..., mask: Image | None = ...) -> None: ...
165    def alpha_composite(self, im: Image, dest: tuple[int, int] = ..., source: tuple[int, int] = ...) -> None: ...
166    def point(self, lut, mode: str | None = ...) -> Image: ...
167    def putalpha(self, alpha: Image | int) -> None: ...
168    def putdata(self, data: Sequence[int], scale: float = ..., offset: float = ...) -> None: ...
169    def putpalette(self, data: ImagePalette | bytes | Iterable[int] | SupportsBytes, rawmode: str | None = ...) -> None: ...
170    def putpixel(self, xy: tuple[int, int], value: _Color | list[float]) -> None: ...
171    def remap_palette(self, dest_map: Iterable[int], source_palette: Sequence[int] | None = ...) -> Image: ...
172    def resize(
173        self,
174        size: tuple[int, int],
175        resample: _Resample | None = ...,
176        box: tuple[float, float, float, float] | None = ...,
177        reducing_gap: float | None = ...,
178    ) -> Image: ...
179    def reduce(self, factor: int | tuple[int, int] | list[int], box: _Box | None = ...) -> Image: ...
180    def rotate(
181        self,
182        angle: float,
183        resample: _Resample = ...,
184        expand: bool = ...,
185        center: tuple[float, float] | None = ...,
186        translate: tuple[float, float] | None = ...,
187        fillcolor: _Color | None = ...,
188    ) -> Image: ...
189    def save(
190        self,
191        fp: str | bytes | Path | _Writeable,
192        format: str | None = ...,
193        *,
194        save_all: bool = ...,
195        bitmap_format: Literal["bmp", "png"] = ...,  # for ICO files
196        **params: Any,
197    ) -> None: ...
198    def seek(self, frame: int) -> None: ...
199    def show(self, title: str | None = ..., command: str | None = ...) -> None: ...
200    def split(self) -> tuple[Image, ...]: ...
201    def getchannel(self, channel: int | str) -> Image: ...
202    def tell(self) -> int: ...
203    def thumbnail(self, size: tuple[int, int], resample: _Resample = ..., reducing_gap: float = ...) -> None: ...
204    def transform(
205        self,
206        size: _Size,
207        method: Literal[0, 1, 2, 3, 4],
208        data=...,
209        resample: _Resample = ...,
210        fill: int = ...,
211        fillcolor: _Color | int | None = ...,
212    ) -> None: ...
213    def transpose(self, method: Literal[0, 1, 2, 3, 4, 5, 6]) -> Image: ...
214    def effect_spread(self, distance: int) -> Image: ...
215    def toqimage(self): ...
216    def toqpixmap(self): ...
217
218class ImagePointHandler: ...
219class ImageTransformHandler: ...
220
221def new(mode: _Mode, size: tuple[int, int], color: float | tuple[float, ...] | str = ...) -> Image: ...
222def frombytes(mode: _Mode, size: tuple[int, int], data, decoder_name: str = ..., *args) -> Image: ...
223def frombuffer(mode: _Mode, size: tuple[int, int], data, decoder_name: str = ..., *args) -> Image: ...
224def fromarray(obj, mode: _Mode | None = ...) -> Image: ...
225def fromqimage(im) -> Image: ...
226def fromqpixmap(im) -> Image: ...
227def open(
228    fp: str | bytes | Path | SupportsRead[bytes], mode: Literal["r"] = ..., formats: list[str] | tuple[str] | None = ...
229) -> Image: ...
230def alpha_composite(im1: Image, im2: Image) -> Image: ...
231def blend(im1: Image, im2: Image, alpha: float) -> Image: ...
232def composite(image1: Image, image2: Image, mask: Image) -> Image: ...
233def eval(image: Image, *args) -> Image: ...
234def merge(mode: str, bands: Sequence[Image]) -> Image: ...
235def register_open(id: str, factory, accept=...) -> None: ...
236def register_mime(id: str, mimetype: str) -> None: ...
237def register_save(id: str, driver) -> None: ...
238def register_save_all(id: str, driver) -> None: ...
239def register_extension(id: str, extension: str) -> None: ...
240def register_extensions(id: str, extensions: Iterable[str]) -> None: ...
241def registered_extensions() -> dict[str, str]: ...
242def register_decoder(name: str, decoder) -> None: ...
243def register_encoder(name: str, encoder) -> None: ...
244def effect_mandelbrot(size: tuple[int, int], extent: tuple[float, float, float, float], quality: int) -> Image: ...
245def effect_noise(size: tuple[int, int], sigma: float) -> Image: ...
246def linear_gradient(mode: str) -> Image: ...
247def radial_gradient(mode: str) -> Image: ...
248
249class Exif(MutableMapping[int, Any]):
250    def load(self, data: bytes) -> None: ...
251    def tobytes(self, offset: int = ...) -> bytes: ...
252    def get_ifd(self, tag: int): ...
253    def __len__(self) -> int: ...
254    def __getitem__(self, tag: int) -> Any: ...
255    def __contains__(self, tag: object) -> bool: ...
256    def __setitem__(self, tag: int, value: Any) -> None: ...
257    def __delitem__(self, tag: int) -> None: ...
258    def __iter__(self) -> Iterator[int]: ...
259