Merge pull request #500 from wiredfool/webp_lossless_abi

Webp lossless abi
This commit is contained in:
wiredfool 2014-01-20 13:18:30 -08:00
commit e1489d7c76
4 changed files with 125 additions and 93 deletions

View File

@ -2,6 +2,7 @@ from tester import *
from PIL import Image
try:
from PIL import _webp
except:
@ -10,10 +11,7 @@ except:
def test_version():
assert_no_exception(lambda: _webp.WebPDecoderVersion())
def test_good_alpha():
assert_equal(_webp.WebPDecoderBuggyAlpha(), 0)
assert_no_exception(lambda: _webp.WebPDecoderBuggyAlpha())
def test_read_rgb():
@ -66,92 +64,5 @@ def test_write_rgb():
assert_image_similar(image, target, 20.0)
def test_write_lossless_rgb():
temp_file = tempfile("temp.webp")
lena("RGB").save(temp_file, lossless=True)
image = Image.open(temp_file)
image.load()
assert_equal(image.mode, "RGB")
assert_equal(image.size, (128, 128))
assert_equal(image.format, "WEBP")
assert_no_exception(lambda: image.load())
assert_no_exception(lambda: image.getdata())
assert_image_equal(image, lena("RGB"))
def test_write_rgba():
"""
Can we write a RGBA mode file to webp without error. Does it have the bits we
expect?
"""
temp_file = tempfile("temp.webp")
pil_image = Image.new("RGBA", (10, 10), (255, 0, 0, 20))
pil_image.save(temp_file)
if _webp.WebPDecoderBuggyAlpha():
return
image = Image.open(temp_file)
image.load()
assert_equal(image.mode, "RGBA")
assert_equal(image.size, (10, 10))
assert_equal(image.format, "WEBP")
assert_no_exception(image.load)
assert_no_exception(image.getdata)
assert_image_similar(image, pil_image, 1.0)
if _webp.WebPDecoderBuggyAlpha():
skip("Buggy early version of webp installed, not testing transparency")
def test_read_rgba():
# Generated with `cwebp transparent.png -o transparent.webp`
file_path = "Images/transparent.webp"
image = Image.open(file_path)
assert_equal(image.mode, "RGBA")
assert_equal(image.size, (200, 150))
assert_equal(image.format, "WEBP")
assert_no_exception(lambda: image.load())
assert_no_exception(lambda: image.getdata())
orig_bytes = image.tobytes()
target = Image.open('Images/transparent.png')
assert_image_similar(image, target, 20.0)
def test_write_lossless_rgb():
temp_file = tempfile("temp.webp")
#temp_file = "temp.webp"
pil_image = lena('RGBA')
mask = Image.new("RGBA", (64, 64), (128,128,128,128))
pil_image.paste(mask, (0,0), mask) # add some partially transparent bits.
pil_image.save(temp_file, lossless=True)
image = Image.open(temp_file)
image.load()
assert_equal(image.mode, "RGBA")
assert_equal(image.size, pil_image.size)
assert_equal(image.format, "WEBP")
assert_no_exception(lambda: image.load())
assert_no_exception(lambda: image.getdata())
assert_image_equal(image, pil_image)

View File

@ -0,0 +1,82 @@
from tester import *
from PIL import Image
try:
from PIL import _webp
except:
skip('webp support not installed')
if _webp.WebPDecoderBuggyAlpha():
skip("Buggy early version of webp installed, not testing transparency")
def test_read_rgba():
# Generated with `cwebp transparent.png -o transparent.webp`
file_path = "Images/transparent.webp"
image = Image.open(file_path)
assert_equal(image.mode, "RGBA")
assert_equal(image.size, (200, 150))
assert_equal(image.format, "WEBP")
assert_no_exception(lambda: image.load())
assert_no_exception(lambda: image.getdata())
orig_bytes = image.tobytes()
target = Image.open('Images/transparent.png')
assert_image_similar(image, target, 20.0)
def test_write_lossless_rgb():
temp_file = tempfile("temp.webp")
#temp_file = "temp.webp"
pil_image = lena('RGBA')
mask = Image.new("RGBA", (64, 64), (128,128,128,128))
pil_image.paste(mask, (0,0), mask) # add some partially transparent bits.
pil_image.save(temp_file, lossless=True)
image = Image.open(temp_file)
image.load()
assert_equal(image.mode, "RGBA")
assert_equal(image.size, pil_image.size)
assert_equal(image.format, "WEBP")
assert_no_exception(lambda: image.load())
assert_no_exception(lambda: image.getdata())
assert_image_equal(image, pil_image)
def test_write_rgba():
"""
Can we write a RGBA mode file to webp without error. Does it have the bits we
expect?
"""
temp_file = tempfile("temp.webp")
pil_image = Image.new("RGBA", (10, 10), (255, 0, 0, 20))
pil_image.save(temp_file)
if _webp.WebPDecoderBuggyAlpha():
return
image = Image.open(temp_file)
image.load()
assert_equal(image.mode, "RGBA")
assert_equal(image.size, (10, 10))
assert_equal(image.format, "WEBP")
assert_no_exception(image.load)
assert_no_exception(image.getdata)
assert_image_similar(image, pil_image, 1.0)

View File

@ -0,0 +1,33 @@
from tester import *
from PIL import Image
try:
from PIL import _webp
except:
skip('webp support not installed')
if (_webp.WebPDecoderVersion() < 0x0200):
skip('lossless not included')
def test_write_lossless_rgb():
temp_file = tempfile("temp.webp")
lena("RGB").save(temp_file, lossless=True)
image = Image.open(temp_file)
image.load()
assert_equal(image.mode, "RGB")
assert_equal(image.size, (128, 128))
assert_equal(image.format, "WEBP")
assert_no_exception(lambda: image.load())
assert_no_exception(lambda: image.getdata())
assert_image_equal(image, lena("RGB"))

10
_webp.c
View File

@ -34,18 +34,24 @@ PyObject* WebPEncode_wrapper(PyObject* self, PyObject* args)
if (size < width * height * 4){
Py_RETURN_NONE;
}
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
if (lossless) {
ret_size = WebPEncodeLosslessRGBA(rgb, width, height, 4* width, &output);
} else {
} else
#endif
{
ret_size = WebPEncodeRGBA(rgb, width, height, 4* width, quality_factor, &output);
}
} else if (strcmp(mode, "RGB")==0){
if (size < width * height * 3){
Py_RETURN_NONE;
}
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
if (lossless) {
ret_size = WebPEncodeLosslessRGB(rgb, width, height, 3* width, &output);
} else {
} else
#endif
{
ret_size = WebPEncodeRGB(rgb, width, height, 3* width, quality_factor, &output);
}
} else {