mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-03-03 11:35:52 +03:00
Merge branch 'master' into winbuild-rewrite
This commit is contained in:
commit
c04013fa74
3
.github/workflows/test-docker.yml
vendored
3
.github/workflows/test-docker.yml
vendored
|
@ -14,6 +14,7 @@ jobs:
|
|||
arch,
|
||||
ubuntu-16.04-xenial-amd64,
|
||||
ubuntu-18.04-bionic-amd64,
|
||||
ubuntu-20.04-focal-amd64,
|
||||
debian-9-stretch-x86,
|
||||
debian-10-buster-x86,
|
||||
centos-6-amd64,
|
||||
|
@ -21,8 +22,8 @@ jobs:
|
|||
centos-8-amd64,
|
||||
amazon-1-amd64,
|
||||
amazon-2-amd64,
|
||||
fedora-30-amd64,
|
||||
fedora-31-amd64,
|
||||
fedora-32-amd64,
|
||||
]
|
||||
dockerTag: [master]
|
||||
|
||||
|
|
|
@ -28,6 +28,9 @@ matrix:
|
|||
|
||||
- python: "pypy3"
|
||||
name: "PyPy3 Xenial"
|
||||
- python: "3.9-dev"
|
||||
name: "3.9-dev Xenial"
|
||||
services: xvfb
|
||||
- python: "3.8"
|
||||
name: "3.8 Xenial"
|
||||
services: xvfb
|
||||
|
|
15
CHANGES.rst
15
CHANGES.rst
|
@ -2,6 +2,21 @@
|
|||
Changelog (Pillow)
|
||||
==================
|
||||
|
||||
7.2.0 (unreleased)
|
||||
------------------
|
||||
|
||||
- Fixed bug when unpickling TIFF images #4565
|
||||
[radarhere]
|
||||
|
||||
- Fix pickling WebP #4561
|
||||
[hugovk, radarhere]
|
||||
|
||||
7.1.2 (2020-04-25)
|
||||
------------------
|
||||
|
||||
- Raise an EOFError when seeking too far in PNG #4528
|
||||
[radarhere]
|
||||
|
||||
7.1.1 (2020-04-02)
|
||||
------------------
|
||||
|
||||
|
|
|
@ -21,10 +21,8 @@ exclude .appveyor.yml
|
|||
exclude .coveragerc
|
||||
exclude .editorconfig
|
||||
exclude .readthedocs.yml
|
||||
exclude azure-pipelines.yml
|
||||
exclude codecov.yml
|
||||
global-exclude .git*
|
||||
global-exclude *.pyc
|
||||
global-exclude *.so
|
||||
prune .azure-pipelines
|
||||
prune .ci
|
||||
|
|
|
@ -272,12 +272,8 @@ def on_github_actions():
|
|||
|
||||
|
||||
def on_ci():
|
||||
# Travis and AppVeyor have "CI"
|
||||
# Azure Pipelines has "TF_BUILD"
|
||||
# GitHub Actions has "GITHUB_ACTIONS"
|
||||
return (
|
||||
"CI" in os.environ or "TF_BUILD" in os.environ or "GITHUB_ACTIONS" in os.environ
|
||||
)
|
||||
# GitHub Actions, Travis and AppVeyor have "CI"
|
||||
return "CI" in os.environ
|
||||
|
||||
|
||||
def is_big_endian():
|
||||
|
|
|
@ -66,7 +66,7 @@ def test_load_set_dpi():
|
|||
assert im.size == (164, 164)
|
||||
|
||||
with Image.open("Tests/images/drawing_wmf_ref_144.png") as expected:
|
||||
assert_image_similar(im, expected, 2.0)
|
||||
assert_image_similar(im, expected, 2.1)
|
||||
|
||||
|
||||
def test_save(tmp_path):
|
||||
|
|
|
@ -95,8 +95,9 @@ class TestImageFile:
|
|||
|
||||
def test_raise_ioerror(self):
|
||||
with pytest.raises(IOError):
|
||||
with pytest.raises(DeprecationWarning):
|
||||
with pytest.warns(DeprecationWarning) as record:
|
||||
ImageFile.raise_ioerror(1)
|
||||
assert len(record) == 1
|
||||
|
||||
def test_raise_oserror(self):
|
||||
with pytest.raises(OSError):
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import pickle
|
||||
|
||||
import pytest
|
||||
from PIL import Image
|
||||
|
||||
from .helper import skip_unless_feature
|
||||
|
||||
def helper_pickle_file(tmp_path, pickle, protocol=0, mode=None):
|
||||
|
||||
def helper_pickle_file(tmp_path, pickle, protocol, test_file, mode):
|
||||
# Arrange
|
||||
with Image.open("Tests/images/hopper.jpg") as im:
|
||||
with Image.open(test_file) as im:
|
||||
filename = str(tmp_path / "temp.pkl")
|
||||
if mode:
|
||||
im = im.convert(mode)
|
||||
|
@ -20,9 +23,7 @@ def helper_pickle_file(tmp_path, pickle, protocol=0, mode=None):
|
|||
assert im == loaded_im
|
||||
|
||||
|
||||
def helper_pickle_string(
|
||||
pickle, protocol=0, test_file="Tests/images/hopper.jpg", mode=None
|
||||
):
|
||||
def helper_pickle_string(pickle, protocol, test_file, mode):
|
||||
with Image.open(test_file) as im:
|
||||
if mode:
|
||||
im = im.convert(mode)
|
||||
|
@ -35,41 +36,31 @@ def helper_pickle_string(
|
|||
assert im == loaded_im
|
||||
|
||||
|
||||
def test_pickle_image(tmp_path):
|
||||
@pytest.mark.parametrize(
|
||||
("test_file", "test_mode"),
|
||||
[
|
||||
("Tests/images/hopper.jpg", None),
|
||||
("Tests/images/hopper.jpg", "L"),
|
||||
("Tests/images/hopper.jpg", "PA"),
|
||||
pytest.param(
|
||||
"Tests/images/hopper.webp", None, marks=skip_unless_feature("webp")
|
||||
),
|
||||
("Tests/images/hopper.tif", None),
|
||||
("Tests/images/test-card.png", None),
|
||||
("Tests/images/zero_bb.png", None),
|
||||
("Tests/images/zero_bb_scale2.png", None),
|
||||
("Tests/images/non_zero_bb.png", None),
|
||||
("Tests/images/non_zero_bb_scale2.png", None),
|
||||
("Tests/images/p_trns_single.png", None),
|
||||
("Tests/images/pil123p.png", None),
|
||||
("Tests/images/itxt_chunks.png", None),
|
||||
],
|
||||
)
|
||||
def test_pickle_image(tmp_path, test_file, test_mode):
|
||||
# Act / Assert
|
||||
for protocol in range(0, pickle.HIGHEST_PROTOCOL + 1):
|
||||
helper_pickle_string(pickle, protocol)
|
||||
helper_pickle_file(tmp_path, pickle, protocol)
|
||||
|
||||
|
||||
def test_pickle_p_mode():
|
||||
# Act / Assert
|
||||
for test_file in [
|
||||
"Tests/images/test-card.png",
|
||||
"Tests/images/zero_bb.png",
|
||||
"Tests/images/zero_bb_scale2.png",
|
||||
"Tests/images/non_zero_bb.png",
|
||||
"Tests/images/non_zero_bb_scale2.png",
|
||||
"Tests/images/p_trns_single.png",
|
||||
"Tests/images/pil123p.png",
|
||||
"Tests/images/itxt_chunks.png",
|
||||
]:
|
||||
for protocol in range(0, pickle.HIGHEST_PROTOCOL + 1):
|
||||
helper_pickle_string(pickle, protocol=protocol, test_file=test_file)
|
||||
|
||||
|
||||
def test_pickle_pa_mode(tmp_path):
|
||||
# Act / Assert
|
||||
for protocol in range(0, pickle.HIGHEST_PROTOCOL + 1):
|
||||
helper_pickle_string(pickle, protocol, mode="PA")
|
||||
helper_pickle_file(tmp_path, pickle, protocol, mode="PA")
|
||||
|
||||
|
||||
def test_pickle_l_mode(tmp_path):
|
||||
# Act / Assert
|
||||
for protocol in range(0, pickle.HIGHEST_PROTOCOL + 1):
|
||||
helper_pickle_string(pickle, protocol, mode="L")
|
||||
helper_pickle_file(tmp_path, pickle, protocol, mode="L")
|
||||
helper_pickle_string(pickle, protocol, test_file, test_mode)
|
||||
helper_pickle_file(tmp_path, pickle, protocol, test_file, test_mode)
|
||||
|
||||
|
||||
def test_pickle_la_mode_with_palette(tmp_path):
|
||||
|
@ -88,3 +79,15 @@ def test_pickle_la_mode_with_palette(tmp_path):
|
|||
|
||||
im.mode = "PA"
|
||||
assert im == loaded_im
|
||||
|
||||
|
||||
@skip_unless_feature("webp")
|
||||
def test_pickle_tell():
|
||||
# Arrange
|
||||
image = Image.open("Tests/images/hopper.webp")
|
||||
|
||||
# Act: roundtrip
|
||||
unpickled_image = pickle.loads(pickle.dumps(image))
|
||||
|
||||
# Assert
|
||||
assert unpickled_image.tell() == 0
|
||||
|
|
|
@ -394,14 +394,18 @@ These platforms are built and tested for every change.
|
|||
+----------------------------------+--------------------------+-----------------------+
|
||||
| Debian 10 Buster | 3.7 |x86 |
|
||||
+----------------------------------+--------------------------+-----------------------+
|
||||
| Fedora 30 | 3.7 |x86-64 |
|
||||
+----------------------------------+--------------------------+-----------------------+
|
||||
| Fedora 31 | 3.7 |x86-64 |
|
||||
+----------------------------------+--------------------------+-----------------------+
|
||||
| Fedora 32 | 3.8 |x86-64 |
|
||||
+----------------------------------+--------------------------+-----------------------+
|
||||
| macOS 10.15 Catalina | 3.5, 3.6, 3.7, 3.8, PyPy3|x86-64 |
|
||||
+----------------------------------+--------------------------+-----------------------+
|
||||
| Ubuntu Linux 16.04 LTS | 3.5, 3.6, 3.7, 3.8, PyPy3|x86-64 |
|
||||
+----------------------------------+--------------------------+-----------------------+
|
||||
| Ubuntu Linux 18.04 LTS | 3.6 |x86-64 |
|
||||
+----------------------------------+--------------------------+-----------------------+
|
||||
| Ubuntu Linux 20.04 LTS | 3.8 |x86-64 |
|
||||
+----------------------------------+--------------------------+-----------------------+
|
||||
| Windows Server 2016 | 3.8 |x86 |
|
||||
| +--------------------------+-----------------------+
|
||||
| | 3.5 |x86-64 |
|
||||
|
|
|
@ -100,6 +100,25 @@ Example: Draw Partial Opacity Text
|
|||
|
||||
out.show()
|
||||
|
||||
Example: Draw Multiline Text
|
||||
----------------------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
# create an image
|
||||
out = Image.new("RGB", (150, 100), (255, 255, 255))
|
||||
|
||||
# get a font
|
||||
fnt = ImageFont.truetype("Pillow/Tests/fonts/FreeMono.ttf", 40)
|
||||
# get a drawing context
|
||||
d = ImageDraw.Draw(out)
|
||||
|
||||
# draw multiline text
|
||||
d.multiline_text((10,10), "Hello\nWorld", font=fnt, fill=(0, 0, 0))
|
||||
|
||||
out.show()
|
||||
|
||||
|
||||
Functions
|
||||
|
|
16
docs/releasenotes/7.1.2.rst
Normal file
16
docs/releasenotes/7.1.2.rst
Normal file
|
@ -0,0 +1,16 @@
|
|||
7.1.2
|
||||
-----
|
||||
|
||||
Fix another regression seeking PNG files
|
||||
========================================
|
||||
|
||||
This fixes a regression introduced in 7.1.0 when adding support for APNG files.
|
||||
|
||||
When calling ``seek(n)`` on a regular PNG where ``n > 0``, it failed to raise an
|
||||
``EOFError`` as it should have done, resulting in:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
AttributeError: 'NoneType' object has no attribute 'read'
|
||||
|
||||
Pillow 7.1.2 now raises the correct exception.
|
|
@ -6,6 +6,7 @@ Release Notes
|
|||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
7.1.2
|
||||
7.1.1
|
||||
7.1.0
|
||||
7.0.0
|
||||
|
|
|
@ -59,16 +59,10 @@ class DcxImageFile(PcxImageFile):
|
|||
|
||||
self.__fp = self.fp
|
||||
self.frame = None
|
||||
self.n_frames = len(self._offset)
|
||||
self.is_animated = self.n_frames > 1
|
||||
self.seek(0)
|
||||
|
||||
@property
|
||||
def n_frames(self):
|
||||
return len(self._offset)
|
||||
|
||||
@property
|
||||
def is_animated(self):
|
||||
return len(self._offset) > 1
|
||||
|
||||
def seek(self, frame):
|
||||
if not self._seek_check(frame):
|
||||
return
|
||||
|
|
|
@ -51,7 +51,8 @@ class FliImageFile(ImageFile.ImageFile):
|
|||
raise SyntaxError("not an FLI/FLC file")
|
||||
|
||||
# frames
|
||||
self.__framecount = i16(s[6:8])
|
||||
self.n_frames = i16(s[6:8])
|
||||
self.is_animated = self.n_frames > 1
|
||||
|
||||
# image characteristics
|
||||
self.mode = "P"
|
||||
|
@ -110,14 +111,6 @@ class FliImageFile(ImageFile.ImageFile):
|
|||
palette[i] = (r, g, b)
|
||||
i += 1
|
||||
|
||||
@property
|
||||
def n_frames(self):
|
||||
return self.__framecount
|
||||
|
||||
@property
|
||||
def is_animated(self):
|
||||
return self.__framecount > 1
|
||||
|
||||
def seek(self, frame):
|
||||
if not self._seek_check(frame):
|
||||
return
|
||||
|
|
|
@ -2247,6 +2247,7 @@ class Image:
|
|||
:py:attr:`PIL.Image.BICUBIC`, or :py:attr:`PIL.Image.LANCZOS`.
|
||||
If omitted, it defaults to :py:attr:`PIL.Image.BICUBIC`.
|
||||
(was :py:attr:`PIL.Image.NEAREST` prior to version 2.5.0).
|
||||
See: :ref:`concept-filters`.
|
||||
:param reducing_gap: Apply optimization by resizing the image
|
||||
in two steps. First, reducing the image by integer times
|
||||
using :py:meth:`~PIL.Image.Image.reduce` or
|
||||
|
@ -2324,7 +2325,7 @@ class Image:
|
|||
It may also be an object with a :py:meth:`~method.getdata` method
|
||||
that returns a tuple supplying new **method** and **data** values::
|
||||
|
||||
class Example(object):
|
||||
class Example:
|
||||
def getdata(self):
|
||||
method = Image.EXTENT
|
||||
data = (0, 0, 100, 100)
|
||||
|
@ -2336,6 +2337,7 @@ class Image:
|
|||
environment), or :py:attr:`PIL.Image.BICUBIC` (cubic spline
|
||||
interpolation in a 4x4 environment). If omitted, or if the image
|
||||
has mode "1" or "P", it is set to :py:attr:`PIL.Image.NEAREST`.
|
||||
See: :ref:`concept-filters`.
|
||||
:param fill: If **method** is an
|
||||
:py:class:`~PIL.Image.ImageTransformHandler` object, this is one of
|
||||
the arguments passed to it. Otherwise, it is unused.
|
||||
|
|
|
@ -150,10 +150,10 @@ class ImageFile(Image.Image):
|
|||
def load(self):
|
||||
"""Load image data based on tile list"""
|
||||
|
||||
pixel = Image.Image.load(self)
|
||||
|
||||
if self.tile is None:
|
||||
raise OSError("cannot load this image")
|
||||
|
||||
pixel = Image.Image.load(self)
|
||||
if not self.tile:
|
||||
return pixel
|
||||
|
||||
|
|
|
@ -64,20 +64,14 @@ class MicImageFile(TiffImagePlugin.TiffImageFile):
|
|||
|
||||
self.__fp = self.fp
|
||||
self.frame = None
|
||||
self._n_frames = len(self.images)
|
||||
self.is_animated = self._n_frames > 1
|
||||
|
||||
if len(self.images) > 1:
|
||||
self.category = Image.CONTAINER
|
||||
|
||||
self.seek(0)
|
||||
|
||||
@property
|
||||
def n_frames(self):
|
||||
return len(self.images)
|
||||
|
||||
@property
|
||||
def is_animated(self):
|
||||
return len(self.images) > 1
|
||||
|
||||
def seek(self, frame):
|
||||
if not self._seek_check(frame):
|
||||
return
|
||||
|
|
|
@ -48,15 +48,16 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile):
|
|||
|
||||
def _after_jpeg_open(self, mpheader=None):
|
||||
self.mpinfo = mpheader if mpheader is not None else self._getmp()
|
||||
self.__framecount = self.mpinfo[0xB001]
|
||||
self.n_frames = self.mpinfo[0xB001]
|
||||
self.__mpoffsets = [
|
||||
mpent["DataOffset"] + self.info["mpoffset"] for mpent in self.mpinfo[0xB002]
|
||||
]
|
||||
self.__mpoffsets[0] = 0
|
||||
# Note that the following assertion will only be invalid if something
|
||||
# gets broken within JpegImagePlugin.
|
||||
assert self.__framecount == len(self.__mpoffsets)
|
||||
assert self.n_frames == len(self.__mpoffsets)
|
||||
del self.info["mpoffset"] # no longer needed
|
||||
self.is_animated = self.n_frames > 1
|
||||
self.__fp = self.fp # FIXME: hack
|
||||
self.__fp.seek(self.__mpoffsets[0]) # get ready to read first frame
|
||||
self.__frame = 0
|
||||
|
@ -67,14 +68,6 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile):
|
|||
def load_seek(self, pos):
|
||||
self.__fp.seek(pos)
|
||||
|
||||
@property
|
||||
def n_frames(self):
|
||||
return self.__framecount
|
||||
|
||||
@property
|
||||
def is_animated(self):
|
||||
return self.__framecount > 1
|
||||
|
||||
def seek(self, frame):
|
||||
if not self._seek_check(frame):
|
||||
return
|
||||
|
|
|
@ -119,6 +119,8 @@ class PsdImageFile(ImageFile.ImageFile):
|
|||
if size:
|
||||
self.layers = _layerinfo(self.fp)
|
||||
self.fp.seek(end)
|
||||
self.n_frames = len(self.layers)
|
||||
self.is_animated = self.n_frames > 1
|
||||
|
||||
#
|
||||
# image descriptor
|
||||
|
@ -130,14 +132,6 @@ class PsdImageFile(ImageFile.ImageFile):
|
|||
self.frame = 1
|
||||
self._min_frame = 1
|
||||
|
||||
@property
|
||||
def n_frames(self):
|
||||
return len(self.layers)
|
||||
|
||||
@property
|
||||
def is_animated(self):
|
||||
return len(self.layers) > 1
|
||||
|
||||
def seek(self, layer):
|
||||
if not self._seek_check(layer):
|
||||
return
|
||||
|
|
|
@ -1015,10 +1015,6 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
self.seek(current)
|
||||
return self._n_frames
|
||||
|
||||
@property
|
||||
def is_animated(self):
|
||||
return self._is_animated
|
||||
|
||||
def seek(self, frame):
|
||||
"""Select a given frame as current image"""
|
||||
if not self._seek_check(frame):
|
||||
|
@ -1052,7 +1048,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
if self.__next == 0:
|
||||
self._n_frames = frame + 1
|
||||
if len(self._frame_pos) == 1:
|
||||
self._is_animated = self.__next != 0
|
||||
self.is_animated = self.__next != 0
|
||||
self.__frame += 1
|
||||
self.fp.seek(self._frame_pos[frame])
|
||||
self.tag_v2.load(self.fp)
|
||||
|
@ -1066,7 +1062,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
return self.__frame
|
||||
|
||||
def load(self):
|
||||
if self.use_load_libtiff:
|
||||
if self.tile and self.use_load_libtiff:
|
||||
return self._load_libtiff()
|
||||
return super().load()
|
||||
|
||||
|
@ -1087,19 +1083,14 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
|
||||
# allow closing if we're on the first frame, there's no next
|
||||
# This is the ImageFile.load path only, libtiff specific below.
|
||||
if not self._is_animated:
|
||||
if not self.is_animated:
|
||||
self._close_exclusive_fp_after_loading = True
|
||||
|
||||
def _load_libtiff(self):
|
||||
""" Overload method triggered when we detect a compressed tiff
|
||||
Calls out to libtiff """
|
||||
|
||||
pixel = Image.Image.load(self)
|
||||
|
||||
if self.tile is None:
|
||||
raise OSError("cannot load this image")
|
||||
if not self.tile:
|
||||
return pixel
|
||||
Image.Image.load(self)
|
||||
|
||||
self.load_prepare()
|
||||
|
||||
|
@ -1138,7 +1129,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
except ValueError:
|
||||
raise OSError("Couldn't set the image")
|
||||
|
||||
close_self_fp = self._exclusive_fp and not self._is_animated
|
||||
close_self_fp = self._exclusive_fp and not self.is_animated
|
||||
if hasattr(self.fp, "getvalue"):
|
||||
# We've got a stringio like thing passed in. Yay for all in memory.
|
||||
# The decoder needs the entire file in one shot, so there's not
|
||||
|
|
|
@ -38,6 +38,8 @@ class WebPImageFile(ImageFile.ImageFile):
|
|||
|
||||
format = "WEBP"
|
||||
format_description = "WebP image"
|
||||
__loaded = 0
|
||||
__logical_frame = 0
|
||||
|
||||
def _open(self):
|
||||
if not _webp.HAVE_WEBPANIM:
|
||||
|
@ -52,7 +54,8 @@ class WebPImageFile(ImageFile.ImageFile):
|
|||
self._size = width, height
|
||||
self.fp = BytesIO(data)
|
||||
self.tile = [("raw", (0, 0) + self.size, 0, self.mode)]
|
||||
self._n_frames = 1
|
||||
self.n_frames = 1
|
||||
self.is_animated = False
|
||||
return
|
||||
|
||||
# Use the newer AnimDecoder API to parse the (possibly) animated file,
|
||||
|
@ -70,7 +73,8 @@ class WebPImageFile(ImageFile.ImageFile):
|
|||
bgcolor & 0xFF,
|
||||
)
|
||||
self.info["background"] = (bg_r, bg_g, bg_b, bg_a)
|
||||
self._n_frames = frame_count
|
||||
self.n_frames = frame_count
|
||||
self.is_animated = self.n_frames > 1
|
||||
self.mode = "RGB" if mode == "RGBX" else mode
|
||||
self.rawmode = mode
|
||||
self.tile = []
|
||||
|
@ -88,30 +92,15 @@ class WebPImageFile(ImageFile.ImageFile):
|
|||
|
||||
# Initialize seek state
|
||||
self._reset(reset=False)
|
||||
self.seek(0)
|
||||
|
||||
def _getexif(self):
|
||||
if "exif" not in self.info:
|
||||
return None
|
||||
return dict(self.getexif())
|
||||
|
||||
@property
|
||||
def n_frames(self):
|
||||
return self._n_frames
|
||||
|
||||
@property
|
||||
def is_animated(self):
|
||||
return self._n_frames > 1
|
||||
|
||||
def seek(self, frame):
|
||||
if not _webp.HAVE_WEBPANIM:
|
||||
return super().seek(frame)
|
||||
|
||||
# Perform some simple checks first
|
||||
if frame >= self._n_frames:
|
||||
raise EOFError("attempted to seek beyond end of sequence")
|
||||
if frame < 0:
|
||||
raise EOFError("negative frame index is not valid")
|
||||
if not self._seek_check(frame):
|
||||
return
|
||||
|
||||
# Set logical frame to requested position
|
||||
self.__logical_frame = frame
|
||||
|
|
|
@ -823,6 +823,7 @@ static int decode_bcn(Imaging im, ImagingCodecState state, const UINT8* src, int
|
|||
if (state->y >= ymax) return -1; \
|
||||
} \
|
||||
break
|
||||
|
||||
DECODE_LOOP(1, 8, rgba);
|
||||
DECODE_LOOP(2, 16, rgba);
|
||||
DECODE_LOOP(3, 16, rgba);
|
||||
|
|
Loading…
Reference in New Issue
Block a user