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.