Fix error with loading paletted BMP images using Pillow #388
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Any 8-bit paletted BMP image is unable to be loaded using the Pillow image plugin with imageio but this pull request fixes that. The error that comes up when attempting to load an 8-bit paletted BMP image is:
ValueError: cannot reshape array of size XXX into shape (XXX, 3)
This error occurs in pil_get_frame when attempting to apply the palette to get the data in RGB format.
This error comes from the fact that the raw palette is retrieved from the Pillow image and parsed rather than using the converted/stored palette. In other words, im.palette.getdata() is the raw data that gets saved upon retrieving the data into im.getpalette(). The data in im.getpalette() is converted into one format (such as RGB) while the im.palette.getdata() can be in many different formats.
The reason that im.getpalette() is not used in the pil_get_frame function is because there is some issues with reading animated GIFs with a different color table for each frame causes some issue. To be specific, the dispose method must be set to 1 meaning that each new frame should be pasted on top of the old frame, which is kinda weird/tough to do when you have different color tables. See this issue here for more information, but it may be awhile to get a fix.
As a result of using the raw palette data, we need to know the format it is in. For BMP's, most of the time the format is going to be BGRX where X is just an unused byte. This is what causes the error is because the code currently tries to resize it to be 3 channels no matter what.
In Pillow, the im.palette class saves the raw mode of the data but once it is saved into im.getpalette() (via im.putpalette()), then the raw mode is set to none. This is fine if we don't ever use the raw data from the palette, but we do so we need to save it.
Solution: My way of fixing this is to save the rawmode before it is discarded in another placeholder variable and then restore it when pil_get_frame is called.
A new test is added to load bitmaps. This test will fail until the data is added to the imageio-binaries repository: see here.