Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified Tests/images/hopper_webp_bits.ppm
Binary file not shown.
17 changes: 4 additions & 13 deletions Tests/test_file_webp.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ def setUp(self):
self.skipTest('WebP support not installed')
return

# WebPAnimDecoder only returns RGBA or RGBX, never RGB
self.rgb_mode = "RGBX" if _webp.HAVE_WEBPANIM else "RGB"
self.rgb_mode = "RGB"

def test_version(self):
_webp.WebPDecoderVersion()
Expand All @@ -29,8 +28,7 @@ def test_read_rgb(self):
Does it have the bits we expect?
"""

file_path = "Tests/images/hopper.webp"
image = Image.open(file_path)
image = Image.open("Tests/images/hopper.webp")

self.assertEqual(image.mode, self.rgb_mode)
self.assertEqual(image.size, (128, 128))
Expand All @@ -40,9 +38,7 @@ def test_read_rgb(self):

# generated with:
# dwebp -ppm ../../Tests/images/hopper.webp -o hopper_webp_bits.ppm
target = Image.open('Tests/images/hopper_webp_bits.ppm')
target = target.convert(self.rgb_mode)
self.assert_image_similar(image, target, 20.0)
self.assert_image_similar_tofile(image, 'Tests/images/hopper_webp_bits.ppm', 1.0)

def test_write_rgb(self):
"""
Expand All @@ -61,13 +57,8 @@ def test_write_rgb(self):
image.load()
image.getdata()

# If we're using the exact same version of WebP, this test should pass.
# but it doesn't if the WebP is generated on Ubuntu and tested on
# Fedora.

# generated with: dwebp -ppm temp.webp -o hopper_webp_write.ppm
# target = Image.open('Tests/images/hopper_webp_write.ppm')
# self.assert_image_equal(image, target)
self.assert_image_similar_tofile(image, 'Tests/images/hopper_webp_write.ppm', 12.0)

# This test asserts that the images are similar. If the average pixel
# difference between the two images is less than the epsilon value,
Expand Down
3 changes: 1 addition & 2 deletions Tests/test_file_webp_lossless.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ def setUp(self):
if (_webp.WebPDecoderVersion() < 0x0200):
self.skipTest('lossless not included')

# WebPAnimDecoder only returns RGBA or RGBX, never RGB
self.rgb_mode = "RGBX" if _webp.HAVE_WEBPANIM else "RGB"
self.rgb_mode = "RGB"

def test_write_lossless_rgb(self):
temp_file = self.tempfile("temp.webp")
Expand Down
24 changes: 17 additions & 7 deletions src/PIL/WebPImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
_VALID_WEBP_MODES = {
"RGBX": True,
"RGBA": True,
"RGB": True,
}

_VALID_WEBP_LEGACY_MODES = {
Expand Down Expand Up @@ -63,7 +64,8 @@ def _open(self):
bgcolor & 0xFF
self.info["background"] = (bg_r, bg_g, bg_b, bg_a)
self._n_frames = frame_count
self.mode = mode
self.mode = 'RGB' if mode == 'RGBX' else mode
self.rawmode = mode
self.tile = []

# Attempt to read ICC / EXIF / XMP chunks from file
Expand Down Expand Up @@ -154,7 +156,7 @@ def load(self):

# Set tile
self.fp = BytesIO(data)
self.tile = [("raw", (0, 0) + self.size, 0, self.mode)]
self.tile = [("raw", (0, 0) + self.size, 0, self.rawmode)]

return super(WebPImageFile, self).load()

Expand Down Expand Up @@ -240,16 +242,23 @@ def _save_all(im, fp, filename):

# Make sure image mode is supported
frame = ims
rawmode = ims.mode
if ims.mode not in _VALID_WEBP_MODES:
alpha = ims.mode == 'P' and 'A' in ims.im.getpalettemode()
frame = ims.convert('RGBA' if alpha else 'RGBX')
alpha = 'A' in ims.mode or 'a' in ims.mode \
or (ims.mode == 'P' and 'A' in ims.im.getpalettemode())
rawmode = 'RGBA' if alpha else 'RGB'
frame = ims.convert(rawmode)

if rawmode == 'RGB':
# For faster conversion, use RGBX
rawmode = 'RGBX'

# Append the frame to the animation encoder
enc.add(
frame.tobytes(),
frame.tobytes('raw', rawmode),
timestamp,
frame.size[0], frame.size[1],
frame.mode,
rawmode,
lossless,
quality,
method
Expand Down Expand Up @@ -288,7 +297,8 @@ def _save(im, fp, filename):
xmp = im.encoderinfo.get("xmp", "")

if im.mode not in _VALID_WEBP_LEGACY_MODES:
alpha = im.mode == 'P' and 'A' in im.im.getpalettemode()
alpha = 'A' in im.mode or 'a' in im.mode \
or (im.mode == 'P' and 'A' in im.im.getpalettemode())
im = im.convert('RGBA' if alpha else 'RGB')

data = _webp.WebPEncode(
Expand Down
2 changes: 2 additions & 0 deletions src/_webp.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ PyObject* _anim_encoder_add(PyObject* self, PyObject* args)
WebPPictureImportRGBA(frame, rgb, 4 * width);
} else if (strcmp(mode, "RGBX")==0) {
WebPPictureImportRGBX(frame, rgb, 4 * width);
} else {
WebPPictureImportRGB(frame, rgb, 3 * width);
}

// Add the frame to the encoder
Expand Down