Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow FLI palette chunk to not be first #6626

Merged
merged 1 commit into from Oct 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Binary file added Tests/images/hopper_palette_chunk_second.fli
Binary file not shown.
8 changes: 7 additions & 1 deletion Tests/test_file_fli.py
Expand Up @@ -4,7 +4,7 @@

from PIL import FliImagePlugin, Image

from .helper import assert_image_equal_tofile, is_pypy
from .helper import assert_image_equal, assert_image_equal_tofile, is_pypy

# created as an export of a palette image from Gimp2.6
# save as...-> hopper.fli, default options.
Expand Down Expand Up @@ -79,6 +79,12 @@ def test_invalid_file():
FliImagePlugin.FliImageFile(invalid_file)


def test_palette_chunk_second():
with Image.open("Tests/images/hopper_palette_chunk_second.fli") as im:
with Image.open(static_test_file) as expected:
assert_image_equal(im.convert("RGB"), expected.convert("RGB"))


def test_n_frames():
with Image.open(static_test_file) as im:
assert im.n_frames == 1
Expand Down
19 changes: 14 additions & 5 deletions src/PIL/FliImagePlugin.py
Expand Up @@ -15,6 +15,7 @@
# See the README file for information on usage and redistribution.
#

import os

from . import Image, ImageFile, ImagePalette
from ._binary import i16le as i16
Expand Down Expand Up @@ -80,11 +81,19 @@ def _open(self):

if i16(s, 4) == 0xF1FA:
# look for palette chunk
s = self.fp.read(6)
if i16(s, 4) == 11:
self._palette(palette, 2)
elif i16(s, 4) == 4:
self._palette(palette, 0)
number_of_subchunks = i16(s, 6)
chunk_size = None
for _ in range(number_of_subchunks):
if chunk_size is not None:
self.fp.seek(chunk_size - 6, os.SEEK_CUR)
s = self.fp.read(6)
chunk_type = i16(s, 4)
if chunk_type in (4, 11):
self._palette(palette, 2 if chunk_type == 11 else 0)
break
chunk_size = i32(s)
if not chunk_size:
break

palette = [o8(r) + o8(g) + o8(b) for (r, g, b) in palette]
self.palette = ImagePalette.raw("RGB", b"".join(palette))
Expand Down