Pillow icon indicating copy to clipboard operation
Pillow copied to clipboard

Add WebP advanced options

Open ikait opened this issue 10 years ago • 4 comments

Added more WebP convert options below. https://github.com/webmproject/libwebp/blob/main/src/enc/config_enc.c

ikait avatar Jun 08 '15 10:06 ikait

- pic.use_argb = !!opt->lossless;
+ pic.use_argb = !!opt->lossless || config.preprocessing > 0;

Works well otherwise. (A few additional options have been added since.)

pdknsk avatar Aug 08 '16 18:08 pdknsk

I've updated the patch with the newest options.

diff --git a/PIL/WebPImagePlugin.py b/PIL/WebPImagePlugin.py
index bb06928..44ea7c2 100644
--- a/PIL/WebPImagePlugin.py
+++ b/PIL/WebPImagePlugin.py
@@ -74,6 +74,9 @@ def _save(im, fp, filename):
     emulate_jpeg_size = im.encoderinfo.get("emulate_jpeg_size", False)
     thread_level = im.encoderinfo.get("thread_level", 0)
     low_memory = im.encoderinfo.get("low_memory", False)
+    exact = im.encoderinfo.get("exact", False)
+    near_lossless = im.encoderinfo.get("near_lossless", 100) # 0-100
+    use_sharp_yuv = im.encoderinfo.get("use_sharp_yuv", False)
 
     data = _webp.WebPEncode(
         im.tobytes(),
@@ -103,7 +106,10 @@ def _save(im, fp, filename):
         partition_limit,
         emulate_jpeg_size,
         thread_level,
-        low_memory
+        low_memory,
+        exact,
+        near_lossless,
+        use_sharp_yuv,
     )
     if data is None:
         raise IOError("cannot write file as WEBP (encoder returned None)")
diff --git a/_webp.c b/_webp.c
index 54bd2bf..92738d2 100644
--- a/_webp.c
+++ b/_webp.c
@@ -36,6 +36,9 @@ struct option {
     int emulate_jpeg_size;
     int thread_level;
     int low_memory;
+    int exact;
+    int near_lossless;
+    int use_sharp_yuv;
 } opt;
 
 int getSizeAfterEncode(struct option *opt, uint8_t** rgb, uint8_t** output, int is_rgba) {
@@ -62,14 +65,20 @@ int getSizeAfterEncode(struct option *opt, uint8_t** rgb, uint8_t** output, int
         config.emulate_jpeg_size = opt->emulate_jpeg_size;
         config.thread_level = opt->thread_level;
         config.low_memory = opt->low_memory;
+        config.exact = opt->exact;
+        config.near_lossless = opt->near_lossless;
+        config.use_sharp_yuv = opt->use_sharp_yuv;
     }
 
+    if (config.near_lossless < 100)
+        config.lossless = 1;
+
     WebPPicture pic;
     WebPPictureInit(&pic);
 
     WebPMemoryWriter wrt;
     WebPMemoryWriterInit(&wrt);
-    pic.use_argb = !!opt->lossless;
+    pic.use_argb = !!config.lossless || config.preprocessing > 0 || !!config.use_sharp_yuv;
     pic.writer = WebPMemoryWrite;
     pic.custom_ptr = &wrt;
     pic.width = opt->width;
@@ -99,7 +108,7 @@ PyObject* WebPEncode_wrapper(PyObject* self, PyObject* args)
     Py_ssize_t exif_size;
     size_t ret_size;
 
-    if (!PyArg_ParseTuple(args, "s#iiifss#s#iiifiiiiiiiiiiiiiiii",
+    if (!PyArg_ParseTuple(args, "s#iiifss#s#iiifiiiiiiiiiiiiiiiiiii",
                 (char**)&rgb, &size,
                 &opt.width, &opt.height, &opt.lossless,
                 &opt.quality,
@@ -111,7 +120,8 @@ PyObject* WebPEncode_wrapper(PyObject* self, PyObject* args)
                 &opt.autofilter,
                 &opt.alpha_compression, &opt.alpha_filtering, &opt.alpha_quality,
                 &opt.pass, &opt.preprocessing, &opt.partitions, &opt.partition_limit,
-                &opt.emulate_jpeg_size, &opt.thread_level, &opt.low_memory
+                &opt.emulate_jpeg_size, &opt.thread_level, &opt.low_memory,
+                &opt.exact, &opt.near_lossless, &opt.use_sharp_yuv
                 )) {
         Py_RETURN_NONE;
     }

pdknsk avatar May 09 '17 22:05 pdknsk

We still need testing and documentation on this, as that's (at least a portion) of what's been blocking this PR.

wiredfool avatar May 10 '17 09:05 wiredfool