We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Incorrect documentation for ImagePalette size parameter (and maybe not needed at all)
The documentation for the `ImagePalette` initializer in version 8.3.1 says the `palette` parameter must be "of length `size` times the number of colors in `mode`". Therefore, for an RGB image, I would expect `len(palette) == size * 3`. However, the code asserts that `len(palette) == size`, so I believe the code and documentation are inconsistent. (The same problem existed in 8.2.0 before some ImagePalette improvements were made, so this wasn't introduced with that change.)

Furthermore, it isn't clear to me that the `size` parameter is needed at all. It isn't stored on `self`, and the only place it's used in the initializer is to assert that its value is `0` or `len(palette)`, so it doesn't seem to provide any benefit. The only reason to keep it that I can think of is to maintain backwards compatibility with existing code that explicitly passes the parameter.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/PIL/ImagePalette.py`
Content:
```
1 #
2 # The Python Imaging Library.
3 # $Id$
4 #
5 # image palette object
6 #
7 # History:
8 # 1996-03-11 fl   Rewritten.
9 # 1997-01-03 fl   Up and running.
10 # 1997-08-23 fl   Added load hack
11 # 2001-04-16 fl   Fixed randint shadow bug in random()
12 #
13 # Copyright (c) 1997-2001 by Secret Labs AB
14 # Copyright (c) 1996-1997 by Fredrik Lundh
15 #
16 # See the README file for information on usage and redistribution.
17 #
18 
19 import array
20 
21 from . import GimpGradientFile, GimpPaletteFile, ImageColor, PaletteFile
22 
23 
24 class ImagePalette:
25     """
26     Color palette for palette mapped images
27 
28     :param mode: The mode to use for the Palette. See:
29         :ref:`concept-modes`. Defaults to "RGB"
30     :param palette: An optional palette. If given, it must be a bytearray,
31         an array or a list of ints between 0-255. The list must be aligned
32         by channel (All R values must be contiguous in the list before G
33         and B values.) Defaults to 0 through 255 per channel.
34     :param size: An optional palette size. If given, an error is raised
35         if ``palette`` is not of equal length.
36     """
37 
38     def __init__(self, mode="RGB", palette=None, size=0):
39         self.mode = mode
40         self.rawmode = None  # if set, palette contains raw data
41         self.palette = palette or bytearray()
42         self.dirty = None
43         if size != 0 and size != len(self.palette):
44             raise ValueError("wrong palette size")
45 
46     @property
47     def palette(self):
48         return self._palette
49 
50     @palette.setter
51     def palette(self, palette):
52         self._palette = palette
53 
54         mode_len = len(self.mode)
55         self.colors = {}
56         for i in range(0, len(self.palette), mode_len):
57             color = tuple(self.palette[i : i + mode_len])
58             if color in self.colors:
59                 continue
60             self.colors[color] = i // mode_len
61 
62     def copy(self):
63         new = ImagePalette()
64 
65         new.mode = self.mode
66         new.rawmode = self.rawmode
67         if self.palette is not None:
68             new.palette = self.palette[:]
69         new.dirty = self.dirty
70 
71         return new
72 
73     def getdata(self):
74         """
75         Get palette contents in format suitable for the low-level
76         ``im.putpalette`` primitive.
77 
78         .. warning:: This method is experimental.
79         """
80         if self.rawmode:
81             return self.rawmode, self.palette
82         return self.mode, self.tobytes()
83 
84     def tobytes(self):
85         """Convert palette to bytes.
86 
87         .. warning:: This method is experimental.
88         """
89         if self.rawmode:
90             raise ValueError("palette contains raw palette data")
91         if isinstance(self.palette, bytes):
92             return self.palette
93         arr = array.array("B", self.palette)
94         return arr.tobytes()
95 
96     # Declare tostring as an alias for tobytes
97     tostring = tobytes
98 
99     def getcolor(self, color, image=None):
100         """Given an rgb tuple, allocate palette entry.
101 
102         .. warning:: This method is experimental.
103         """
104         if self.rawmode:
105             raise ValueError("palette contains raw palette data")
106         if isinstance(color, tuple):
107             if self.mode == "RGB":
108                 if len(color) == 4 and color[3] == 255:
109                     color = color[:3]
110             elif self.mode == "RGBA":
111                 if len(color) == 3:
112                     color += (255,)
113             try:
114                 return self.colors[color]
115             except KeyError as e:
116                 # allocate new color slot
117                 if not isinstance(self.palette, bytearray):
118                     self._palette = bytearray(self.palette)
119                 index = len(self.palette) // 3
120                 special_colors = ()
121                 if image:
122                     special_colors = (
123                         image.info.get("background"),
124                         image.info.get("transparency"),
125                     )
126                 while index in special_colors:
127                     index += 1
128                 if index >= 256:
129                     if image:
130                         # Search for an unused index
131                         for i, count in reversed(list(enumerate(image.histogram()))):
132                             if count == 0 and i not in special_colors:
133                                 index = i
134                                 break
135                     if index >= 256:
136                         raise ValueError("cannot allocate more than 256 colors") from e
137                 self.colors[color] = index
138                 if index * 3 < len(self.palette):
139                     self._palette = (
140                         self.palette[: index * 3]
141                         + bytes(color)
142                         + self.palette[index * 3 + 3 :]
143                     )
144                 else:
145                     self._palette += bytes(color)
146                 self.dirty = 1
147                 return index
148         else:
149             raise ValueError(f"unknown color specifier: {repr(color)}")
150 
151     def save(self, fp):
152         """Save palette to text file.
153 
154         .. warning:: This method is experimental.
155         """
156         if self.rawmode:
157             raise ValueError("palette contains raw palette data")
158         if isinstance(fp, str):
159             fp = open(fp, "w")
160         fp.write("# Palette\n")
161         fp.write(f"# Mode: {self.mode}\n")
162         for i in range(256):
163             fp.write(f"{i}")
164             for j in range(i * len(self.mode), (i + 1) * len(self.mode)):
165                 try:
166                     fp.write(f" {self.palette[j]}")
167                 except IndexError:
168                     fp.write(" 0")
169             fp.write("\n")
170         fp.close()
171 
172 
173 # --------------------------------------------------------------------
174 # Internal
175 
176 
177 def raw(rawmode, data):
178     palette = ImagePalette()
179     palette.rawmode = rawmode
180     palette.palette = data
181     palette.dirty = 1
182     return palette
183 
184 
185 # --------------------------------------------------------------------
186 # Factories
187 
188 
189 def make_linear_lut(black, white):
190     lut = []
191     if black == 0:
192         for i in range(256):
193             lut.append(white * i // 255)
194     else:
195         raise NotImplementedError  # FIXME
196     return lut
197 
198 
199 def make_gamma_lut(exp):
200     lut = []
201     for i in range(256):
202         lut.append(int(((i / 255.0) ** exp) * 255.0 + 0.5))
203     return lut
204 
205 
206 def negative(mode="RGB"):
207     palette = list(range(256))
208     palette.reverse()
209     return ImagePalette(mode, palette * len(mode))
210 
211 
212 def random(mode="RGB"):
213     from random import randint
214 
215     palette = []
216     for i in range(256 * len(mode)):
217         palette.append(randint(0, 255))
218     return ImagePalette(mode, palette)
219 
220 
221 def sepia(white="#fff0c0"):
222     r, g, b = ImageColor.getrgb(white)
223     r = make_linear_lut(0, r)
224     g = make_linear_lut(0, g)
225     b = make_linear_lut(0, b)
226     return ImagePalette("RGB", r + g + b)
227 
228 
229 def wedge(mode="RGB"):
230     return ImagePalette(mode, list(range(256)) * len(mode))
231 
232 
233 def load(filename):
234 
235     # FIXME: supports GIMP gradients only
236 
237     with open(filename, "rb") as fp:
238 
239         for paletteHandler in [
240             GimpPaletteFile.GimpPaletteFile,
241             GimpGradientFile.GimpGradientFile,
242             PaletteFile.PaletteFile,
243         ]:
244             try:
245                 fp.seek(0)
246                 lut = paletteHandler(fp).getpalette()
247                 if lut:
248                     break
249             except (SyntaxError, ValueError):
250                 # import traceback
251                 # traceback.print_exc()
252                 pass
253         else:
254             raise OSError("cannot load palette")
255 
256     return lut  # data, rawmode
257
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/PIL/ImagePalette.py b/src/PIL/ImagePalette.py
--- a/src/PIL/ImagePalette.py
+++ b/src/PIL/ImagePalette.py
@@ -17,6 +17,7 @@
 #
 
 import array
+import warnings
 
 from . import GimpGradientFile, GimpPaletteFile, ImageColor, PaletteFile
 
@@ -40,8 +41,14 @@
         self.rawmode = None  # if set, palette contains raw data
         self.palette = palette or bytearray()
         self.dirty = None
-        if size != 0 and size != len(self.palette):
-            raise ValueError("wrong palette size")
+        if size != 0:
+            warnings.warn(
+                "The size parameter is deprecated and will be removed in Pillow 10 "
+                "(2023-01-02).",
+                DeprecationWarning,
+            )
+            if size != len(self.palette):
+                raise ValueError("wrong palette size")
 
     @property
     def palette(self):

{"golden_diff": "diff --git a/src/PIL/ImagePalette.py b/src/PIL/ImagePalette.py\n--- a/src/PIL/ImagePalette.py\n+++ b/src/PIL/ImagePalette.py\n@@ -17,6 +17,7 @@\n #\n \n import array\n+import warnings\n \n from . import GimpGradientFile, GimpPaletteFile, ImageColor, PaletteFile\n \n@@ -40,8 +41,14 @@\n         self.rawmode = None  # if set, palette contains raw data\n         self.palette = palette or bytearray()\n         self.dirty = None\n-        if size != 0 and size != len(self.palette):\n-            raise ValueError(\"wrong palette size\")\n+        if size != 0:\n+            warnings.warn(\n+                \"The size parameter is deprecated and will be removed in Pillow 10 \"\n+                \"(2023-01-02).\",\n+                DeprecationWarning,\n+            )\n+            if size != len(self.palette):\n+                raise ValueError(\"wrong palette size\")\n \n     @property\n     def palette(self):\n", "issue": "Incorrect documentation for ImagePalette size parameter (and maybe not needed at all)\nThe documentation for the `ImagePalette` initializer in version 8.3.1 says the `palette` parameter must be \"of length `size` times the number of colors in `mode`\". Therefore, for an RGB image, I would expect `len(palette) == size * 3`. However, the code asserts that `len(palette) == size`, so I believe the code and documentation are inconsistent. (The same problem existed in 8.2.0 before some ImagePalette improvements were made, so this wasn't introduced with that change.)\r\n\r\nFurthermore, it isn't clear to me that the `size` parameter is needed at all. It isn't stored on `self`, and the only place it's used in the initializer is to assert that its value is `0` or `len(palette)`, so it doesn't seem to provide any benefit. The only reason to keep it that I can think of is to maintain backwards compatibility with existing code that explicitly passes the parameter.\n", "before_files": [{"content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# image palette object\n#\n# History:\n# 1996-03-11 fl   Rewritten.\n# 1997-01-03 fl   Up and running.\n# 1997-08-23 fl   Added load hack\n# 2001-04-16 fl   Fixed randint shadow bug in random()\n#\n# Copyright (c) 1997-2001 by Secret Labs AB\n# Copyright (c) 1996-1997 by Fredrik Lundh\n#\n# See the README file for information on usage and redistribution.\n#\n\nimport array\n\nfrom . import GimpGradientFile, GimpPaletteFile, ImageColor, PaletteFile\n\n\nclass ImagePalette:\n    \"\"\"\n    Color palette for palette mapped images\n\n    :param mode: The mode to use for the Palette. See:\n        :ref:`concept-modes`. Defaults to \"RGB\"\n    :param palette: An optional palette. If given, it must be a bytearray,\n        an array or a list of ints between 0-255. The list must be aligned\n        by channel (All R values must be contiguous in the list before G\n        and B values.) Defaults to 0 through 255 per channel.\n    :param size: An optional palette size. If given, an error is raised\n        if ``palette`` is not of equal length.\n    \"\"\"\n\n    def __init__(self, mode=\"RGB\", palette=None, size=0):\n        self.mode = mode\n        self.rawmode = None  # if set, palette contains raw data\n        self.palette = palette or bytearray()\n        self.dirty = None\n        if size != 0 and size != len(self.palette):\n            raise ValueError(\"wrong palette size\")\n\n    @property\n    def palette(self):\n        return self._palette\n\n    @palette.setter\n    def palette(self, palette):\n        self._palette = palette\n\n        mode_len = len(self.mode)\n        self.colors = {}\n        for i in range(0, len(self.palette), mode_len):\n            color = tuple(self.palette[i : i + mode_len])\n            if color in self.colors:\n                continue\n            self.colors[color] = i // mode_len\n\n    def copy(self):\n        new = ImagePalette()\n\n        new.mode = self.mode\n        new.rawmode = self.rawmode\n        if self.palette is not None:\n            new.palette = self.palette[:]\n        new.dirty = self.dirty\n\n        return new\n\n    def getdata(self):\n        \"\"\"\n        Get palette contents in format suitable for the low-level\n        ``im.putpalette`` primitive.\n\n        .. warning:: This method is experimental.\n        \"\"\"\n        if self.rawmode:\n            return self.rawmode, self.palette\n        return self.mode, self.tobytes()\n\n    def tobytes(self):\n        \"\"\"Convert palette to bytes.\n\n        .. warning:: This method is experimental.\n        \"\"\"\n        if self.rawmode:\n            raise ValueError(\"palette contains raw palette data\")\n        if isinstance(self.palette, bytes):\n            return self.palette\n        arr = array.array(\"B\", self.palette)\n        return arr.tobytes()\n\n    # Declare tostring as an alias for tobytes\n    tostring = tobytes\n\n    def getcolor(self, color, image=None):\n        \"\"\"Given an rgb tuple, allocate palette entry.\n\n        .. warning:: This method is experimental.\n        \"\"\"\n        if self.rawmode:\n            raise ValueError(\"palette contains raw palette data\")\n        if isinstance(color, tuple):\n            if self.mode == \"RGB\":\n                if len(color) == 4 and color[3] == 255:\n                    color = color[:3]\n            elif self.mode == \"RGBA\":\n                if len(color) == 3:\n                    color += (255,)\n            try:\n                return self.colors[color]\n            except KeyError as e:\n                # allocate new color slot\n                if not isinstance(self.palette, bytearray):\n                    self._palette = bytearray(self.palette)\n                index = len(self.palette) // 3\n                special_colors = ()\n                if image:\n                    special_colors = (\n                        image.info.get(\"background\"),\n                        image.info.get(\"transparency\"),\n                    )\n                while index in special_colors:\n                    index += 1\n                if index >= 256:\n                    if image:\n                        # Search for an unused index\n                        for i, count in reversed(list(enumerate(image.histogram()))):\n                            if count == 0 and i not in special_colors:\n                                index = i\n                                break\n                    if index >= 256:\n                        raise ValueError(\"cannot allocate more than 256 colors\") from e\n                self.colors[color] = index\n                if index * 3 < len(self.palette):\n                    self._palette = (\n                        self.palette[: index * 3]\n                        + bytes(color)\n                        + self.palette[index * 3 + 3 :]\n                    )\n                else:\n                    self._palette += bytes(color)\n                self.dirty = 1\n                return index\n        else:\n            raise ValueError(f\"unknown color specifier: {repr(color)}\")\n\n    def save(self, fp):\n        \"\"\"Save palette to text file.\n\n        .. warning:: This method is experimental.\n        \"\"\"\n        if self.rawmode:\n            raise ValueError(\"palette contains raw palette data\")\n        if isinstance(fp, str):\n            fp = open(fp, \"w\")\n        fp.write(\"# Palette\\n\")\n        fp.write(f\"# Mode: {self.mode}\\n\")\n        for i in range(256):\n            fp.write(f\"{i}\")\n            for j in range(i * len(self.mode), (i + 1) * len(self.mode)):\n                try:\n                    fp.write(f\" {self.palette[j]}\")\n                except IndexError:\n                    fp.write(\" 0\")\n            fp.write(\"\\n\")\n        fp.close()\n\n\n# --------------------------------------------------------------------\n# Internal\n\n\ndef raw(rawmode, data):\n    palette = ImagePalette()\n    palette.rawmode = rawmode\n    palette.palette = data\n    palette.dirty = 1\n    return palette\n\n\n# --------------------------------------------------------------------\n# Factories\n\n\ndef make_linear_lut(black, white):\n    lut = []\n    if black == 0:\n        for i in range(256):\n            lut.append(white * i // 255)\n    else:\n        raise NotImplementedError  # FIXME\n    return lut\n\n\ndef make_gamma_lut(exp):\n    lut = []\n    for i in range(256):\n        lut.append(int(((i / 255.0) ** exp) * 255.0 + 0.5))\n    return lut\n\n\ndef negative(mode=\"RGB\"):\n    palette = list(range(256))\n    palette.reverse()\n    return ImagePalette(mode, palette * len(mode))\n\n\ndef random(mode=\"RGB\"):\n    from random import randint\n\n    palette = []\n    for i in range(256 * len(mode)):\n        palette.append(randint(0, 255))\n    return ImagePalette(mode, palette)\n\n\ndef sepia(white=\"#fff0c0\"):\n    r, g, b = ImageColor.getrgb(white)\n    r = make_linear_lut(0, r)\n    g = make_linear_lut(0, g)\n    b = make_linear_lut(0, b)\n    return ImagePalette(\"RGB\", r + g + b)\n\n\ndef wedge(mode=\"RGB\"):\n    return ImagePalette(mode, list(range(256)) * len(mode))\n\n\ndef load(filename):\n\n    # FIXME: supports GIMP gradients only\n\n    with open(filename, \"rb\") as fp:\n\n        for paletteHandler in [\n            GimpPaletteFile.GimpPaletteFile,\n            GimpGradientFile.GimpGradientFile,\n            PaletteFile.PaletteFile,\n        ]:\n            try:\n                fp.seek(0)\n                lut = paletteHandler(fp).getpalette()\n                if lut:\n                    break\n            except (SyntaxError, ValueError):\n                # import traceback\n                # traceback.print_exc()\n                pass\n        else:\n            raise OSError(\"cannot load palette\")\n\n    return lut  # data, rawmode\n", "path": "src/PIL/ImagePalette.py"}], "after_files": [{"content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# image palette object\n#\n# History:\n# 1996-03-11 fl   Rewritten.\n# 1997-01-03 fl   Up and running.\n# 1997-08-23 fl   Added load hack\n# 2001-04-16 fl   Fixed randint shadow bug in random()\n#\n# Copyright (c) 1997-2001 by Secret Labs AB\n# Copyright (c) 1996-1997 by Fredrik Lundh\n#\n# See the README file for information on usage and redistribution.\n#\n\nimport array\nimport warnings\n\nfrom . import GimpGradientFile, GimpPaletteFile, ImageColor, PaletteFile\n\n\nclass ImagePalette:\n    \"\"\"\n    Color palette for palette mapped images\n\n    :param mode: The mode to use for the Palette. See:\n        :ref:`concept-modes`. Defaults to \"RGB\"\n    :param palette: An optional palette. If given, it must be a bytearray,\n        an array or a list of ints between 0-255. The list must be aligned\n        by channel (All R values must be contiguous in the list before G\n        and B values.) Defaults to 0 through 255 per channel.\n    :param size: An optional palette size. If given, an error is raised\n        if ``palette`` is not of equal length.\n    \"\"\"\n\n    def __init__(self, mode=\"RGB\", palette=None, size=0):\n        self.mode = mode\n        self.rawmode = None  # if set, palette contains raw data\n        self.palette = palette or bytearray()\n        self.dirty = None\n        if size != 0:\n            warnings.warn(\n                \"The size parameter is deprecated and will be removed in Pillow 10 \"\n                \"(2023-01-02).\",\n                DeprecationWarning,\n            )\n            if size != len(self.palette):\n                raise ValueError(\"wrong palette size\")\n\n    @property\n    def palette(self):\n        return self._palette\n\n    @palette.setter\n    def palette(self, palette):\n        self._palette = palette\n\n        mode_len = len(self.mode)\n        self.colors = {}\n        for i in range(0, len(self.palette), mode_len):\n            color = tuple(self.palette[i : i + mode_len])\n            if color in self.colors:\n                continue\n            self.colors[color] = i // mode_len\n\n    def copy(self):\n        new = ImagePalette()\n\n        new.mode = self.mode\n        new.rawmode = self.rawmode\n        if self.palette is not None:\n            new.palette = self.palette[:]\n        new.dirty = self.dirty\n\n        return new\n\n    def getdata(self):\n        \"\"\"\n        Get palette contents in format suitable for the low-level\n        ``im.putpalette`` primitive.\n\n        .. warning:: This method is experimental.\n        \"\"\"\n        if self.rawmode:\n            return self.rawmode, self.palette\n        return self.mode, self.tobytes()\n\n    def tobytes(self):\n        \"\"\"Convert palette to bytes.\n\n        .. warning:: This method is experimental.\n        \"\"\"\n        if self.rawmode:\n            raise ValueError(\"palette contains raw palette data\")\n        if isinstance(self.palette, bytes):\n            return self.palette\n        arr = array.array(\"B\", self.palette)\n        return arr.tobytes()\n\n    # Declare tostring as an alias for tobytes\n    tostring = tobytes\n\n    def getcolor(self, color, image=None):\n        \"\"\"Given an rgb tuple, allocate palette entry.\n\n        .. warning:: This method is experimental.\n        \"\"\"\n        if self.rawmode:\n            raise ValueError(\"palette contains raw palette data\")\n        if isinstance(color, tuple):\n            if self.mode == \"RGB\":\n                if len(color) == 4 and color[3] == 255:\n                    color = color[:3]\n            elif self.mode == \"RGBA\":\n                if len(color) == 3:\n                    color += (255,)\n            try:\n                return self.colors[color]\n            except KeyError as e:\n                # allocate new color slot\n                if not isinstance(self.palette, bytearray):\n                    self._palette = bytearray(self.palette)\n                index = len(self.palette) // 3\n                special_colors = ()\n                if image:\n                    special_colors = (\n                        image.info.get(\"background\"),\n                        image.info.get(\"transparency\"),\n                    )\n                while index in special_colors:\n                    index += 1\n                if index >= 256:\n                    if image:\n                        # Search for an unused index\n                        for i, count in reversed(list(enumerate(image.histogram()))):\n                            if count == 0 and i not in special_colors:\n                                index = i\n                                break\n                    if index >= 256:\n                        raise ValueError(\"cannot allocate more than 256 colors\") from e\n                self.colors[color] = index\n                if index * 3 < len(self.palette):\n                    self._palette = (\n                        self.palette[: index * 3]\n                        + bytes(color)\n                        + self.palette[index * 3 + 3 :]\n                    )\n                else:\n                    self._palette += bytes(color)\n                self.dirty = 1\n                return index\n        else:\n            raise ValueError(f\"unknown color specifier: {repr(color)}\")\n\n    def save(self, fp):\n        \"\"\"Save palette to text file.\n\n        .. warning:: This method is experimental.\n        \"\"\"\n        if self.rawmode:\n            raise ValueError(\"palette contains raw palette data\")\n        if isinstance(fp, str):\n            fp = open(fp, \"w\")\n        fp.write(\"# Palette\\n\")\n        fp.write(f\"# Mode: {self.mode}\\n\")\n        for i in range(256):\n            fp.write(f\"{i}\")\n            for j in range(i * len(self.mode), (i + 1) * len(self.mode)):\n                try:\n                    fp.write(f\" {self.palette[j]}\")\n                except IndexError:\n                    fp.write(\" 0\")\n            fp.write(\"\\n\")\n        fp.close()\n\n\n# --------------------------------------------------------------------\n# Internal\n\n\ndef raw(rawmode, data):\n    palette = ImagePalette()\n    palette.rawmode = rawmode\n    palette.palette = data\n    palette.dirty = 1\n    return palette\n\n\n# --------------------------------------------------------------------\n# Factories\n\n\ndef make_linear_lut(black, white):\n    lut = []\n    if black == 0:\n        for i in range(256):\n            lut.append(white * i // 255)\n    else:\n        raise NotImplementedError  # FIXME\n    return lut\n\n\ndef make_gamma_lut(exp):\n    lut = []\n    for i in range(256):\n        lut.append(int(((i / 255.0) ** exp) * 255.0 + 0.5))\n    return lut\n\n\ndef negative(mode=\"RGB\"):\n    palette = list(range(256))\n    palette.reverse()\n    return ImagePalette(mode, palette * len(mode))\n\n\ndef random(mode=\"RGB\"):\n    from random import randint\n\n    palette = []\n    for i in range(256 * len(mode)):\n        palette.append(randint(0, 255))\n    return ImagePalette(mode, palette)\n\n\ndef sepia(white=\"#fff0c0\"):\n    r, g, b = ImageColor.getrgb(white)\n    r = make_linear_lut(0, r)\n    g = make_linear_lut(0, g)\n    b = make_linear_lut(0, b)\n    return ImagePalette(\"RGB\", r + g + b)\n\n\ndef wedge(mode=\"RGB\"):\n    return ImagePalette(mode, list(range(256)) * len(mode))\n\n\ndef load(filename):\n\n    # FIXME: supports GIMP gradients only\n\n    with open(filename, \"rb\") as fp:\n\n        for paletteHandler in [\n            GimpPaletteFile.GimpPaletteFile,\n            GimpGradientFile.GimpGradientFile,\n            PaletteFile.PaletteFile,\n        ]:\n            try:\n                fp.seek(0)\n                lut = paletteHandler(fp).getpalette()\n                if lut:\n                    break\n            except (SyntaxError, ValueError):\n                # import traceback\n                # traceback.print_exc()\n                pass\n        else:\n            raise OSError(\"cannot load palette\")\n\n    return lut  # data, rawmode\n", "path": "src/PIL/ImagePalette.py"}]}