summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2021-07-23 23:30:27 +0200
committerGitHub <noreply@github.com>2021-07-23 23:30:27 +0200
commit8accfa98a75c1be74786f321e1a8c77f6869384a (patch)
tree4dd4d3c7d33ed9963dcf9ad3fe32d62ad124942d
parentc380ba2b78879d3047fb0c814f602c98ead7d7ca (diff)
parent97e6c207e7cbea9dd14200a0b7df21fa0c45b5dd (diff)
downloadlibgd-8accfa98a75c1be74786f321e1a8c77f6869384a.tar.gz
Merge pull request #698 from adamsilverstein/webp-lossless
Support writing lossless WebP
-rw-r--r--configure.ac2
-rw-r--r--src/gd.h13
-rw-r--r--src/gd_webp.c9
-rw-r--r--tests/webp/.gitignore1
-rw-r--r--tests/webp/CMakeLists.txt1
-rw-r--r--tests/webp/Makemodule.am3
-rw-r--r--tests/webp/webp_ll_im2im.c41
7 files changed, 67 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index 7c72a31..1746e8f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -279,7 +279,7 @@ GD_LIB_PKG_CHECK([LIBTIFF], [TIFF], [tiff], [libtiff-4], [
])
dnl Check for webp support.
-GD_LIB_PKG_CHECK([LIBWEBP], [WEBP], [webp], [libwebp], [
+GD_LIB_PKG_CHECK([LIBWEBP], [WEBP], [webp], [libwebp >= 0.2.0], [
AC_CHECK_LIB([webp], [WebPGetInfo], [dnl
AS_VAR_APPEND([LIBWEBP_LIBS], [" -lwebp"])
gd_found_lib=yes
diff --git a/src/gd.h b/src/gd.h
index 165f13c..9456a86 100644
--- a/src/gd.h
+++ b/src/gd.h
@@ -1125,6 +1125,19 @@ BGD_DECLARE(void) gdImageJpegCtx(gdImagePtr im, gdIOCtxPtr out, int quality);
/* Best to free this memory with gdFree(), not free() */
BGD_DECLARE(void *) gdImageJpegPtr (gdImagePtr im, int *size, int quality);
+/**
+ * Group: WebP
+ *
+ * Constant: gdWebpLossless
+ *
+ * Lossless quality threshold. When image quality is greater than or equal to
+ * <gdWebpLossless>, the image will be written in the lossless WebP format.
+ *
+ * See also:
+ * - <gdImageWebpEx>
+ */
+#define gdWebpLossless 101
+
BGD_DECLARE(void) gdImageWebpEx (gdImagePtr im, FILE * outFile, int quantization);
BGD_DECLARE(void) gdImageWebp (gdImagePtr im, FILE * outFile);
BGD_DECLARE(void *) gdImageWebpPtr (gdImagePtr im, int *size);
diff --git a/src/gd_webp.c b/src/gd_webp.c
index a0b4787..d887b71 100644
--- a/src/gd_webp.c
+++ b/src/gd_webp.c
@@ -217,7 +217,11 @@ static int _gdImageWebpCtx (gdImagePtr im, gdIOCtx * outfile, int quality)
*(p++) = a;
}
}
- out_size = WebPEncodeRGBA(argb, gdImageSX(im), gdImageSY(im), gdImageSX(im) * 4, quality, &out);
+ if (quality >= gdWebpLossless) {
+ out_size = WebPEncodeLosslessRGBA(argb, gdImageSX(im), gdImageSY(im), gdImageSX(im) * 4, &out);
+ } else {
+ out_size = WebPEncodeRGBA(argb, gdImageSX(im), gdImageSY(im), gdImageSX(im) * 4, quality, &out);
+ }
if (out_size == 0) {
gd_error("gd-webp encoding failed");
ret = 1;
@@ -269,6 +273,9 @@ BGD_DECLARE(void) gdImageWebpCtx (gdImagePtr im, gdIOCtx * outfile, int quality)
_quality_ should be a value in the range 0-100, higher quality values
usually implying both higher quality and larger image sizes.
+ If _quality_ is greater than or equal to <gdWebpLossless> then the image
+ will be written in the lossless WebP format.
+
Variants:
<gdImageWebpCtx> stores the image using a <gdIOCtx> struct.
diff --git a/tests/webp/.gitignore b/tests/webp/.gitignore
index ebc3ec7..b167630 100644
--- a/tests/webp/.gitignore
+++ b/tests/webp/.gitignore
@@ -1,3 +1,4 @@
/bug00111
/bug_double_free
+/webp_ll_im2im
/gdImageWebpEx
diff --git a/tests/webp/CMakeLists.txt b/tests/webp/CMakeLists.txt
index 1d1b98f..6a4431c 100644
--- a/tests/webp/CMakeLists.txt
+++ b/tests/webp/CMakeLists.txt
@@ -2,6 +2,7 @@ IF(WEBP_FOUND)
LIST(APPEND TESTS_FILES
bug00111
gdImageWebpEx
+ webp_ll_im2im
)
IF(JPEG_FOUND)
LIST(APPEND TESTS_FILES
diff --git a/tests/webp/Makemodule.am b/tests/webp/Makemodule.am
index 528edee..c6c9528 100644
--- a/tests/webp/Makemodule.am
+++ b/tests/webp/Makemodule.am
@@ -1,7 +1,8 @@
if HAVE_LIBWEBP
libgd_test_programs += \
webp/bug00111 \
- webp/gdImageWebpEx
+ webp/gdImageWebpEx \
+ webp/webp_ll_im2im
if HAVE_LIBJPEG
libgd_test_programs += \
webp/bug_double_free
diff --git a/tests/webp/webp_ll_im2im.c b/tests/webp/webp_ll_im2im.c
new file mode 100644
index 0000000..0960329
--- /dev/null
+++ b/tests/webp/webp_ll_im2im.c
@@ -0,0 +1,41 @@
+/**
+ * Basic test for writing and reading lossless WebP
+ *
+ * We create an image, write it as WebP, read it in again, and compare it
+ * with the original image.
+ */
+
+#include "gd.h"
+#include "gdtest.h"
+
+int main()
+{
+ gdImagePtr src, dst;
+ int r, g, b;
+ void *p;
+ int size = 0;
+
+ src = gdImageCreateTrueColor(100, 100);
+ gdTestAssert(src != NULL);
+ r = gdImageColorAllocate(src, 0xFF, 0, 0);
+ g = gdImageColorAllocate(src, 0, 0xFF, 0);
+ b = gdImageColorAllocate(src, 0, 0, 0xFF);
+ gdImageFilledRectangle(src, 0, 0, 99, 99, r);
+ gdImageRectangle(src, 20, 20, 79, 79, g);
+ gdImageEllipse(src, 75, 25, 30, 20, b);
+
+ p = gdImageWebpPtrEx(src, &size, gdWebpLossless);
+ gdTestAssert(p != NULL);
+ gdTestAssert(size > 0);
+
+ dst = gdImageCreateFromWebpPtr(size, p);
+ gdTestAssert(dst != NULL);
+
+ gdAssertImageEquals(src, dst);
+
+ gdFree(p);
+ gdImageDestroy(dst);
+ gdImageDestroy(src);
+
+ return gdNumFailures();
+}