This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository legacy-imlib2.

View the commit online.

commit 4f928f53a74e5c10d0a7374b73b2bb1ed16e2aca
Author: NRK <n...@disroot.org>
AuthorDate: Fri May 12 12:05:06 2023 +0600

    WEBP saver: allow lossless and respect compression tag
    
    this treats quality == 100 as lossless similar to some other savers.
    
    in case of lossless encoding, compression is derived from "quality" if
    compression_tag was not set. in case of lossy encoding, the default is
    used when compression_tag isn't set.
    
    additionally, this fixes a bug in the older saver where fwrite might
    have been called with a null fdata (which is UB) in case of an error.
---
 src/modules/loaders/loader_webp.c | 67 ++++++++++++++++++++++++++++++---------
 1 file changed, 52 insertions(+), 15 deletions(-)

diff --git a/src/modules/loaders/loader_webp.c b/src/modules/loaders/loader_webp.c
index b35e801..88cfe62 100644
--- a/src/modules/loaders/loader_webp.c
+++ b/src/modules/loaders/loader_webp.c
@@ -7,6 +7,8 @@
 
 #define DBG_PFX "LDR-webp"
 
+#define CLAMP(X, MIN, MAX)  ((X) < (MIN) ? (MIN) : ((X) > (MAX) ? (MAX) : (X)))
+
 static const char  *const _formats[] = { "webp" };
 
 static int
@@ -114,41 +116,76 @@ _load(ImlibImage * im, int load_data)
    return rc;
 }
 
+static int
+webp_write(const uint8_t * data, size_t size, const WebPPicture * pic)
+{
+   FILE               *f = pic->custom_ptr;
+
+   return fwrite(data, 1, size, f) == size;
+}
+
 static int
 _save(ImlibImage * im)
 {
    int                 rc;
    FILE               *f = im->fi->fp;
    ImlibImageTag      *quality_tag;
-   float               quality;
-   uint8_t            *fdata;
-   size_t              encoded_size;
+   ImlibImageTag      *compression_tag;
+   WebPConfig          conf;
+   WebPPicture         pic;
+   int                 compression;
+   int                 lossless;
+   int                 free_pic = 0;
 
    rc = LOAD_FAIL;
-   fdata = NULL;
 
-   quality = 75;
+   if (!WebPConfigInit(&conf) || !WebPPictureInit(&pic))
+      goto quit;
+
+   conf.quality = 75;
    quality_tag = __imlib_GetTag(im, "quality");
    if (quality_tag)
+      conf.quality = CLAMP(quality_tag->val, 0, 100);
+
+   compression_tag = __imlib_GetTag(im, "compression");
+   /* other savers seem to treat quality 100 as lossless, do the same here. */
+   lossless = conf.quality == 100;
+   if (lossless)
+     {
+        compression = 9 - (conf.quality / 10);  /* convert to compression */
+        if (compression_tag)
+           compression = compression_tag->val;
+        WebPConfigLosslessPreset(&conf, CLAMP(compression, 0, 9));
+     }
+   else if (compression_tag)    /* for lossly encoding, only change conf.method if compression_tag was set */
      {
-        quality = quality_tag->val;
-        if (quality < 0)
-           quality = 0;
-        else if (quality > 100)
-           quality = 100;
+        conf.method = CLAMP(compression_tag->val, 0, 9);
+        conf.method *= 0.67;    /* convert from [0, 9] to [0, 6]. (6/9 == 0.67) */
      }
 
-   encoded_size = WebPEncodeBGRA((uint8_t *) im->data, im->w, im->h,
-                                 im->w * 4, quality, &fdata);
+   if (!WebPValidateConfig(&conf))
+     {
+        D("WebPValidateConfig failed");
+        goto quit;
+     }
+
+   pic.use_argb = lossless;     /* use_argb is recommended for lossless */
+   pic.width = im->w;
+   pic.height = im->h;
+   pic.writer = webp_write;
+   pic.custom_ptr = f;
+   if (!WebPPictureImportBGRA(&pic, (uint8_t *) im->data, im->w * 4))
+      QUIT_WITH_RC(LOAD_OOM);
+   free_pic = 1;
 
-   if (fwrite(fdata, encoded_size, 1, f) != 1)
+   if (!WebPEncode(&conf, &pic))
       goto quit;
 
    rc = LOAD_SUCCESS;
 
  quit:
-   if (fdata)
-      WebPFree(fdata);
+   if (free_pic)
+      WebPPictureFree(&pic);
 
    return rc;
 }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to