from _typeshed import Incomplete
from collections.abc import MutableMapping
from numbers import Rational
from types import TracebackType
from typing import Any, ClassVar
from typing_extensions import Final, Literal

from ._imaging import _PixelAccessor
from .ImageFile import ImageFile

# These are meant to be overridable
READ_LIBTIFF: bool
WRITE_LIBTIFF: bool
IFD_LEGACY_API: bool
STRIP_SIZE: int

II: Final = b"II"
MM: Final = b"MM"
IMAGEWIDTH: Final = 256
IMAGELENGTH: Final = 257
BITSPERSAMPLE: Final = 258
COMPRESSION: Final = 259
PHOTOMETRIC_INTERPRETATION: Final = 262
FILLORDER: Final = 266
IMAGEDESCRIPTION: Final = 270
STRIPOFFSETS: Final = 273
SAMPLESPERPIXEL: Final = 277
ROWSPERSTRIP: Final = 278
STRIPBYTECOUNTS: Final = 279
X_RESOLUTION: Final = 282
Y_RESOLUTION: Final = 283
PLANAR_CONFIGURATION: Final = 284
RESOLUTION_UNIT: Final = 296
TRANSFERFUNCTION: Final = 301
SOFTWARE: Final = 305
DATE_TIME: Final = 306
ARTIST: Final = 315
PREDICTOR: Final = 317
COLORMAP: Final = 320
TILEWIDTH: Final = 322
TILELENGTH: Final = 323
TILEOFFSETS: Final = 324
TILEBYTECOUNTS: Final = 325
SUBIFD: Final = 330
EXTRASAMPLES: Final = 338
SAMPLEFORMAT: Final = 339
JPEGTABLES: Final = 347
YCBCRSUBSAMPLING: Final = 530
REFERENCEBLACKWHITE: Final = 532
COPYRIGHT: Final = 33432
IPTC_NAA_CHUNK: Final = 33723
PHOTOSHOP_CHUNK: Final = 34377
ICCPROFILE: Final = 34675
EXIFIFD: Final = 34665
XMP: Final = 700
JPEGQUALITY: Final = 65537
IMAGEJ_META_DATA_BYTE_COUNTS: Final = 50838
IMAGEJ_META_DATA: Final = 50839
COMPRESSION_INFO: Any
COMPRESSION_INFO_REV: Any
OPEN_INFO: Any
MAX_SAMPLESPERPIXEL: Final = 6
PREFIXES: Any

class IFDRational(Rational):
    def __init__(self, value, denominator: int = 1) -> None: ...
    @property
    def numerator(a): ...
    @property
    def denominator(a): ...
    def limit_rational(self, max_denominator): ...
    def __hash__(self) -> int: ...
    def __eq__(self, other): ...
    __add__: Any
    __radd__: Any
    __sub__: Any
    __rsub__: Any
    __mul__: Any
    __rmul__: Any
    __truediv__: Any
    __rtruediv__: Any
    __floordiv__: Any
    __rfloordiv__: Any
    __mod__: Any
    __rmod__: Any
    __pow__: Any
    __rpow__: Any
    __pos__: Any
    __neg__: Any
    __abs__: Any
    __trunc__: Any
    __lt__: Any
    __gt__: Any
    __le__: Any
    __ge__: Any
    __bool__: Any
    __ceil__: Any
    __floor__: Any
    __round__: Any

class ImageFileDirectory_v2(MutableMapping[int, Any]):
    group: int | None
    tagtype: dict[int, int]
    def __init__(
        self, ifh: bytes = b"II*\x00\x00\x00\x00\x00", prefix: bytes | None = None, group: int | None = None
    ) -> None: ...
    @property
    def prefix(self) -> bytes: ...
    @property
    def offset(self) -> int | None: ...
    @property
    def legacy_api(self) -> bool: ...
    def reset(self) -> None: ...
    def named(self): ...
    def __len__(self) -> int: ...
    def __getitem__(self, tag): ...
    def __contains__(self, tag): ...
    def __setitem__(self, tag, value) -> None: ...
    def __delitem__(self, tag) -> None: ...
    def __iter__(self): ...
    def load_byte(self, data, legacy_api: bool = True): ...
    def write_byte(self, data): ...
    def load_string(self, data, legacy_api: bool = True): ...
    def write_string(self, value: int | str | bytes) -> bytes: ...
    def load_rational(self, data, legacy_api: bool = True): ...
    def write_rational(self, *values): ...
    def load_undefined(self, data, legacy_api: bool = True): ...
    def write_undefined(self, value): ...
    def load_signed_rational(self, data, legacy_api: bool = True): ...
    def write_signed_rational(self, *values): ...
    def load(self, fp) -> None: ...
    def tobytes(self, offset: int = 0): ...
    def save(self, fp): ...
    load_double: Incomplete
    load_float: Incomplete
    load_long: Incomplete
    load_long8: Incomplete
    load_short: Incomplete
    load_signed_byte: Incomplete
    load_signed_long: Incomplete
    load_signed_short: Incomplete
    write_double: Incomplete
    write_float: Incomplete
    write_long: Incomplete
    write_long8: Incomplete
    write_short: Incomplete
    write_signed_byte: Incomplete
    write_signed_long: Incomplete
    write_signed_short: Incomplete

class ImageFileDirectory_v1(ImageFileDirectory_v2):
    def __init__(self, *args, **kwargs) -> None: ...
    @property
    def tags(self): ...
    @property
    def tagdata(self): ...
    tagtype: dict[int, int]
    @classmethod
    def from_v2(cls, original): ...
    def to_v2(self): ...
    def __contains__(self, tag): ...
    def __len__(self) -> int: ...
    def __iter__(self): ...
    def __setitem__(self, tag, value) -> None: ...
    def __getitem__(self, tag): ...

ImageFileDirectory = ImageFileDirectory_v1

class TiffImageFile(ImageFile):
    format: ClassVar[Literal["TIFF", "MIC"]]
    format_description: ClassVar[str]
    tag_v2: Any
    tag: Any
    def __init__(self, fp: Incomplete | None = None, filename: Incomplete | None = None) -> None: ...
    @property
    def n_frames(self): ...
    im: Any
    def seek(self, frame) -> None: ...
    def tell(self): ...
    def getxmp(self): ...
    def get_photoshop_blocks(self): ...
    def load(self) -> _PixelAccessor: ...
    def load_end(self) -> None: ...

SAVE_INFO: Any

class AppendingTiffWriter:
    fieldSizes: Any
    Tags: Any
    f: Any
    close_fp: bool
    name: Any
    beginning: Any
    def __init__(self, fn, new: bool = False) -> None: ...
    whereToWriteNewIFDOffset: Any
    offsetOfNewPage: int
    IIMM: Any
    isFirst: bool
    def setup(self) -> None: ...
    def finalize(self) -> None: ...
    def newFrame(self) -> None: ...
    def __enter__(self): ...
    def __exit__(
        self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None
    ) -> Literal[False]: ...
    def tell(self): ...
    def seek(self, offset, whence=0): ...
    def goToEnd(self) -> None: ...
    endian: Any
    longFmt: Any
    shortFmt: Any
    tagFormat: Any
    def setEndian(self, endian) -> None: ...
    def skipIFDs(self) -> None: ...
    def write(self, data): ...
    def readShort(self): ...
    def readLong(self): ...
    def rewriteLastShortToLong(self, value) -> None: ...
    def rewriteLastShort(self, value) -> None: ...
    def rewriteLastLong(self, value) -> None: ...
    def writeShort(self, value) -> None: ...
    def writeLong(self, value) -> None: ...
    def close(self) -> None: ...
    def fixIFD(self) -> None: ...
    def fixOffsets(self, count, isShort: bool = False, isLong: bool = False) -> None: ...
