1#
2# Python Imaging Library
3# $Id$
4#
5# stuff to read GIMP palette files
6#
7# History:
8# 1997-08-23 fl Created
9# 2004-09-07 fl Support GIMP 2.0 palette files.
10#
11# Copyright (c) Secret Labs AB 1997-2004. All rights reserved.
12# Copyright (c) Fredrik Lundh 1997-2004.
13#
14# See the README file for information on usage and redistribution.
15#
16from __future__ import annotations
17
18import re
19from io import BytesIO
20
21TYPE_CHECKING = False
22if TYPE_CHECKING:
23 from typing import IO
24
25
26class GimpPaletteFile:
27 """File handler for GIMP's palette format."""
28
29 rawmode = "RGB"
30
31 def _read(self, fp: IO[bytes], limit: bool = True) -> None:
32 if not fp.readline().startswith(b"GIMP Palette"):
33 msg = "not a GIMP palette file"
34 raise SyntaxError(msg)
35
36 palette: list[int] = []
37 i = 0
38 while True:
39 if limit and i == 256 + 3:
40 break
41
42 i += 1
43 s = fp.readline()
44 if not s:
45 break
46
47 # skip fields and comment lines
48 if re.match(rb"\w+:|#", s):
49 continue
50 if limit and len(s) > 100:
51 msg = "bad palette file"
52 raise SyntaxError(msg)
53
54 v = s.split(maxsplit=3)
55 if len(v) < 3:
56 msg = "bad palette entry"
57 raise ValueError(msg)
58
59 palette += (int(v[i]) for i in range(3))
60 if limit and len(palette) == 768:
61 break
62
63 self.palette = bytes(palette)
64
65 def __init__(self, fp: IO[bytes]) -> None:
66 self._read(fp)
67
68 @classmethod
69 def frombytes(cls, data: bytes) -> GimpPaletteFile:
70 self = cls.__new__(cls)
71 self._read(BytesIO(data), False)
72 return self
73
74 def getpalette(self) -> tuple[bytes, str]:
75 return self.palette, self.rawmode