File imghdr.py of Package failed_python-mediafile

"""
A minimal replacement for the deprecated and removed stdlib `imghdr` module.

This provides the `what(filename, h=None)` function used by code that imports
`imghdr`. It performs basic image type detection from the file header bytes.

It is intentionally small and only implements the checks needed for common
formats (jpeg, png, gif, tiff, bmp, webp). If more formats are needed they
can be added following the same pattern.

This file is intended as the smallest necessary change to restore compatibility
with Python versions where the stdlib `imghdr` module is not available.
"""

from typing import Optional, Union


def _read_header_from_filename(filename: str, n: int = 32) -> Optional[bytes]:
    try:
        with open(filename, "rb") as f:
            return f.read(n)
    except Exception:
        return None


def what(filename: Union[str, bytes, bytearray, None], h: Optional[bytes] = None) -> Optional[str]:
    """
    Determine the image type based on file header.

    Arguments:
    - filename: path to the file (str) or raw bytes (bytes/bytearray) when h is None.
    - h: optional header bytes to examine (if provided, filename can be None).

    Returns a short string identifying the file type like 'jpeg', 'png', 'gif',
    'tiff', 'bmp', 'webp' or None if unknown.
    """
    header = h

    # If header not given, and filename is bytes/bytearray treat it as header.
    if header is None and isinstance(filename, (bytes, bytearray)):
        header = bytes(filename[:64])
        filename = None

    # If header still not given, try to read from filename.
    if header is None:
        if filename is None:
            return None
        header = _read_header_from_filename(filename, 64)
        if header is None:
            return None

    # Ensure we have a bytes object.
    if not isinstance(header, (bytes, bytearray)):
        try:
            header = bytes(header)
        except Exception:
            return None

    h = header

    # JPEG: starts with 0xFF 0xD8
    if h.startswith(b"\xff\xd8"):
        return "jpeg"

    # PNG: 89 50 4E 47 0D 0A 1A 0A
    if h.startswith(b"\x89PNG\r\n\x1a\n"):
        return "png"

    # GIF: GIF87a or GIF89a
    if h[:6] in (b"GIF87a", b"GIF89a"):
        return "gif"

    # TIFF: little endian II*\x00 or big-endian MM\x00*
    if h[:4] in (b"II*\x00", b"MM\x00*"):
        return "tiff"

    # BMP: 'BM' at start
    if h.startswith(b"BM"):
        return "bmp"

    # WEBP: 'RIFF'....'WEBP' (bytes 0-3 RIFF, bytes 8-11 WEBP)
    if h.startswith(b"RIFF") and len(h) >= 12 and h[8:12] == b"WEBP":
        return "webp"

    # XBM: starts with '#define ' (text-based X bitmap)
    # Check first few bytes as ASCII
    try:
        start = h.lstrip()[:8].lower()
        if start.startswith(b"#define") or start.startswith(b"/*"):
            # Not highly accurate, but helps identify xbm-like files
            return "xbm"
    except Exception:
        pass

    return None


# For compatibility: expose common names from the original imghdr module
tests = None  # placeholder, some code imports imghdr.tests; we don't provide it here.
what.__doc__ = what.__doc__  # keep docstring accessible.
openSUSE Build Service is sponsored by