Repository: python-pillow/Pillow

Issue:
Docs not providing required information for setting image palletes
OT: don't bite me because I use pallet and not palette. (this is the only thing I use that uses palette)

so I'm trying to create a new image and write a pallet to it, but the data I'm providing is in formats of:
- [ I/L ]
- [ I/L, A ]
- [ R, G, B ]
- [ R, G, B, A ]

if I specify `pmode = ['L','LA','RGB','RGBA'][len(pallet[0])]`, is that compatible with `img.putpalette(pallet, pmode)`??

also, the pallet data I'm providing is not of a fixed size, and will give as many colors as it was originally provided.

for more of an idea, here's the export portion of my program's image I/O script:

```python
def ugeExportImage(FT,CMD):
    #name = ugeGetImageName()
    width = ugeGetImageWidth()
    height = ugeGetImageHeight()
    pixels = ugeGetImageData()
    pallet = ugeGetImagePallet()

    mode = ['L','LA','RGB','RGBA'][len(pixels[0])-1]
    pmode= None
    if pallet!=[] and mode=='L': mode='P'; pmode = ['L','LA','RGB','RGBA'][len(pallet[0])-1]

    img = Image.new( mode, (width,height))
    img.putdata([tuple(p) for p in pixels])
    if mode=='P': img.putpalette( pallet, pmode )

    Data = StringIO()
    img.save(Data, format=FT)
    Data.seek(0)
    string(Data.read())
```

the documentation doesn't tell me what pallet formats are supported, nor does it tell me all pallet sequence types.



Discussion:
Send a PR?

Looks like the `rawmode` parameter can any of the RGB section of this list - https://github.com/python-pillow/Pillow/blob/master/libImaging/Unpack.c#L1080

I think if we started inserting mode lists of this length in the documentation, it could become cluttered. Perhaps someone can suggest a more organised approach to this?

As an aside -

https://pillow.readthedocs.org/en/3.0.x/reference/Image.html#PIL.Image.Image.putpalette -

```
Attaches a palette to this image.  The image must be a "P" or
"L" image, and the palette sequence must contain 768 integer
values, where each group of three values represent the red,
green, and blue values for the corresponding pixel index.
Instead of an integer sequence, you can use an 8-bit string.

Parameters: data – A palette sequence (either a list or a string).
```

Your code can create images of modes L, LA, RGB and RGBA - rather than just P or L as specified in the documentation.

I think I understand, you're saying I'm free to put the palette rawmode as any of L, LA, RGB, or RGBA, and it's not restricted at all, right?? (just making sure as I want to do it right, rather than play around with the stuff as I shouldn't have to figure out what's right)

thanks :)

also, sorry for the late reply, I'm currently without any internet connection...
I'm saying that the documentation states that the image that `putpalette` is applied to must be P or L, and your code is applying it to images or L, LA, RGB or RGBA - where L is the only option that is actually P or L.

The `putpalette` method itself does not impose any unnecessary restrictions on the rawmode - only the restrictions of what Pillow can load an image with when `load()` is called at the end. Based on my analysis the last time around, the RGB section of the list includes - RGB, RGB;L, RGB;R, RGB;16B, BGR, RGB;15, BGR;15, RGB;16, BGR;16, RGB;4B, BGR;5, RGBX, RGBX;L, BGRX, XRGB, XBGR, YCC;P, R, G and B.

`if pallet!=[] and mode=='L':`
^ that's what sets the pmode to apply the palette, otherwize it's None.

I just realized though that my code above is invalid...
idk where my head was when I built that export script... haha
`mode = ['L','LA','RGB','RGBA'][len(pixels[0])-1]`
^ this will error when `pixels = ugeGetImageData()` applies index data instead of pixel data.

so it looks like we're both at a misunderstanding on different tangents... heh
sorry for that. :)

OT: I've had a wake-up call and have been yelled at while I was away, palette is correct... lol

so if a palette is returned from an image in my interface, and the image data is pixel data (lists) and not index data (ints), the palette is invalid and should be ignored.
(I'm cracking down on my API though so this shouldn't happen)

but what I'm confused on is if the pillow palette data can be given a rawmode from any of L, LA, RGB, or RGBA.

so yea, that's what my last post was about.

thanks :)

From reading the source code, and from experimentation, RGB yes, L, LA and RGBA, no.

ah alright thanks

just to note, it's likely you'll have a clash there
I've made my palette format the same as my image format (except for indices) for safety. ;)

I do know there are formats with palettes which at least support alpha (maybe not so  much L because that would be stupid).
OpenGL has some pretty good palette support as well (like mine) ;)

anyways... I see you have the enhancement tag, so I'll leave this alone and wait for something to be done :)

thanks again

I've created PR #5634 to resolve this.

Resolving patch:
diff --git a/src/PIL/Image.py b/src/PIL/Image.py
--- a/src/PIL/Image.py
+++ b/src/PIL/Image.py
@@ -1751,14 +1751,19 @@ def putpalette(self, data, rawmode="RGB"):
         Attaches a palette to this image.  The image must be a "P", "PA", "L"
         or "LA" image.
 
-        The palette sequence must contain at most 768 integer values, or 1024
-        integer values if alpha is included. Each group of values represents
-        the red, green, blue (and alpha if included) values for the
-        corresponding pixel index. Instead of an integer sequence, you can use
-        an 8-bit string.
+        The palette sequence must contain at most 256 colors, made up of one
+        integer value for each channel in the raw mode.
+        For example, if the raw mode is "RGB", then it can contain at most 768
+        values, made up of red, green and blue values for the corresponding pixel
+        index in the 256 colors.
+        If the raw mode is "RGBA", then it can contain at most 1024 values,
+        containing red, green, blue and alpha values.
+
+        Alternatively, an 8-bit string may be used instead of an integer sequence.
 
         :param data: A palette sequence (either a list or a string).
-        :param rawmode: The raw mode of the palette.
+        :param rawmode: The raw mode of the palette. Either "RGB", "RGBA", or a
+           mode that can be transformed to "RGB" (e.g. "R", "BGR;15", "RGBA;L").
         """
         from . import ImagePalette
 


Test patch: