| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | from __future__ import annotations |
| |
|
| | import re |
| | from io import BytesIO |
| |
|
| | TYPE_CHECKING = False |
| | if TYPE_CHECKING: |
| | from typing import IO |
| |
|
| |
|
| | class GimpPaletteFile: |
| | """File handler for GIMP's palette format.""" |
| |
|
| | rawmode = "RGB" |
| |
|
| | def _read(self, fp: IO[bytes], limit: bool = True) -> None: |
| | if not fp.readline().startswith(b"GIMP Palette"): |
| | msg = "not a GIMP palette file" |
| | raise SyntaxError(msg) |
| |
|
| | palette: list[int] = [] |
| | i = 0 |
| | while True: |
| | if limit and i == 256 + 3: |
| | break |
| |
|
| | i += 1 |
| | s = fp.readline() |
| | if not s: |
| | break |
| |
|
| | |
| | if re.match(rb"\w+:|#", s): |
| | continue |
| | if limit and len(s) > 100: |
| | msg = "bad palette file" |
| | raise SyntaxError(msg) |
| |
|
| | v = s.split(maxsplit=3) |
| | if len(v) < 3: |
| | msg = "bad palette entry" |
| | raise ValueError(msg) |
| |
|
| | palette += (int(v[i]) for i in range(3)) |
| | if limit and len(palette) == 768: |
| | break |
| |
|
| | self.palette = bytes(palette) |
| |
|
| | def __init__(self, fp: IO[bytes]) -> None: |
| | self._read(fp) |
| |
|
| | @classmethod |
| | def frombytes(cls, data: bytes) -> GimpPaletteFile: |
| | self = cls.__new__(cls) |
| | self._read(BytesIO(data), False) |
| | return self |
| |
|
| | def getpalette(self) -> tuple[bytes, str]: |
| | return self.palette, self.rawmode |
| |
|