From 1204d9961f67bfd0947b2eeec56ecb141f2c8126 Mon Sep 17 00:00:00 2001 From: David Tschumperle Date: Wed, 18 Sep 2024 07:44:39 +0200 Subject: [PATCH 1/4] . --- html/header.html | 2 +- html/header_doxygen.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/html/header.html b/html/header.html index 311d37ff..25b4127a 100644 --- a/html/header.html +++ b/html/header.html @@ -23,7 +23,7 @@
Logo

- Latest stable version: 3.4.2        Current pre-release: 3.4.3 (2024/09/13) + Latest stable version: 3.4.2        Current pre-release: 3.4.3 (2024/09/17)


diff --git a/html/header_doxygen.html b/html/header_doxygen.html index c9c783f4..2b91654d 100644 --- a/html/header_doxygen.html +++ b/html/header_doxygen.html @@ -26,7 +26,7 @@
Logo

- Latest stable version: 3.4.2        Current pre-release: 3.4.3 (2024/09/13) + Latest stable version: 3.4.2        Current pre-release: 3.4.3 (2024/09/17)


From 1c9a2bfa5cbddf37086dddd7abd7fad5ddf55b7e Mon Sep 17 00:00:00 2001 From: apocelipes Date: Wed, 18 Sep 2024 22:29:59 +0800 Subject: [PATCH 2/4] Support for loading/saving WebP files by using libwebp Fixes #364. --- CImg.h | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 137 insertions(+), 1 deletion(-) diff --git a/CImg.h b/CImg.h index 1e759661..0c98914f 100644 --- a/CImg.h +++ b/CImg.h @@ -522,6 +522,18 @@ extern "C" { #include #endif +// Configure WebP support +// (https://chromium.googlesource.com/webm/libwebp/) +// +// Define 'cimg_use_webp' to enable WebP support. +// +// WebP library may be used to get a native support of '.webp' files. +// (see method 'CImg::{load,save}_webp()'). +#ifdef cimg_use_webp +#include +#include +#endif + // Configure LibMINC2 support. // (http://en.wikibooks.org/wiki/MINC/Reference/MINC2.0_File_Format_Reference) // @@ -55349,6 +55361,7 @@ namespace cimg_library { else if (!cimg::strcasecmp(ext,"gif")) load_gif_external(filename); else if (!cimg::strcasecmp(ext,"heic") || !cimg::strcasecmp(ext,"avif")) load_heif(filename); + else if (!cimg::strcasecmp(ext,"webp")) load_webp(filename); // 3D binary formats else if (!cimg::strcasecmp(ext,"dcm") || @@ -55420,6 +55433,7 @@ namespace cimg_library { else if (!cimg::strcasecmp(f_type,"tif")) load_tiff(filename); else if (!cimg::strcasecmp(f_type,"gif")) load_gif_external(filename); else if (!cimg::strcasecmp(f_type,"dcm")) load_medcon_external(filename); + else if (!cimg::strcasecmp(f_type,"webp")) load_webp(filename); else is_loaded = false; } catch (CImgIOException&) { is_loaded = false; } } @@ -58189,6 +58203,68 @@ namespace cimg_library { #endif } + //! Load image from a WebP file. + /** + \param filename Filename, as a C-string. + **/ + CImg& load_webp(const char *const filename) { + return _load_webp(filename); + } + + //! Load image from a WebP file \newinstance. + static CImg get_load_webp(const char *const filename) { + return CImg().load_webp(filename); + } + + CImg& _load_webp(const char *const filename) { +#ifndef cimg_use_webp + return load_other(filename); +#else + std::FILE *file = cimg::fopen(filename, "rb"); + const long data_size = cimg::fsize(file); + if (data_size <= 0) { + cimg::fclose(file); + throw CImgIOException(_cimg_instance + "load_webp(): Failed to get file size '%s'.", + cimg_instance, + filename); + } + CImg buffer(data_size); + cimg::fread(buffer._data, buffer._width, file); + int width = 0, height = 0; + if (!WebPGetInfo(buffer._data, data_size, &width, &height)) { + cimg::fclose(file); + throw CImgIOException(_cimg_instance + "load_webp(): Failed to get image width/height '%s'.", + cimg_instance, + filename); + } + assign(width,height,1,4); + unsigned char *imgData = WebPDecodeRGBA(buffer._data, data_size, NULL, NULL); + if (!imgData) { + cimg::fclose(file); + throw CImgIOException(_cimg_instance + "load_webp(): Failed to decode image '%s'.", + cimg_instance, + filename); + } + T *ptr_r = _data, *ptr_g = _data + 1UL*width*height, + *ptr_b = _data + 2UL*width*height, *ptr_a = _data + 3UL*width*height; + cimg_forY(*this,y) { + const unsigned char *ptrs = (unsigned char*)&imgData[y*width*4]; + cimg_forX(*this,x) { + *(ptr_r++) = (T)*(ptrs++); + *(ptr_g++) = (T)*(ptrs++); + *(ptr_b++) = (T)*(ptrs++); + *(ptr_a++) = (T)*(ptrs++); + } + } + WebPFree(imgData); + cimg::fclose(file); + return *this; +#endif + } + //! Load image using GraphicsMagick's external tool 'gm'. /** \param filename Filename, as a C-string. @@ -59942,6 +60018,7 @@ namespace cimg_library { else if (!cimg::strcasecmp(ext,"exr")) return save_exr(fn); else if (!cimg::strcasecmp(ext,"tif") || !cimg::strcasecmp(ext,"tiff")) return save_tiff(fn); + else if (!cimg::strcasecmp(ext,"webp")) return save_webp(fn); // 3D binary formats else if (!*ext) { @@ -60205,6 +60282,61 @@ namespace cimg_library { return *this; } + //! Save image as a WebP file. + /** + \param filename Filename, as a C-string. + \param quality Image quality (in %) + **/ + const CImg& save_webp(const char *const filename, const int quality=100) const { + return _save_webp(filename,quality); + } + + const CImg& _save_webp(const char *const filename, const int quality) const { + if (!filename) + throw CImgArgumentException(_cimg_instance + "save_webp(): Specified filename is (null).", + cimg_instance); + if (_spectrum != 3 && _spectrum != 4) + throw CImgArgumentException(_cimg_instance + "save_webp(): WebP only supports (A)RGB colorspace.", + cimg_instance); +#ifndef cimg_use_webp + return save_other(filename); +#else + CImg rgbaBuffer(size()); + T *ptr_r = _data, *ptr_g = _data + 1UL*_width*_height, + *ptr_b = _data + 2UL*_width*_height, *ptr_a = _spectrum==3?NULL:_data + 3UL*_width*_height; + uint8_t *ptr = rgbaBuffer._data; + cimg_forY(*this,y) { + cimg_forX(*this,x) { + *(ptr++) = (T)*(ptr_r++); + *(ptr++) = (T)*(ptr_g++); + *(ptr++) = (T)*(ptr_b++); + if (ptr_a) *(ptr++) = (T)*(ptr_a++); + } + } + uint8_t *imgData = NULL; + const int stride = _width*_spectrum*sizeof(uint8_t); + size_t size = 0; + if (_spectrum == 3) { + size = WebPEncodeRGB(rgbaBuffer._data, _width, _height, stride, (float)quality, &imgData); + } else { + size = WebPEncodeRGBA(rgbaBuffer._data, _width, _height, stride, (float)quality, &imgData); + } + if (!imgData) { + throw CImgIOException(_cimg_instance + "save_webp(): Failed to encode image to file '%s'.", + cimg_instance, + filename); + } + std::FILE *file = cimg::fopen(filename, "wb"); + cimg::fwrite(imgData, size, file); + cimg::fclose(file); + WebPFree(imgData); + return *this; +#endif + } + //! Save image as a JPEG file. /** \param filename Filename, as a C-string. @@ -68314,7 +68446,8 @@ namespace cimg_library { *const _pfm = "pfm", *const _png = "png", *const _pnm = "pnm", - *const _tif = "tif"; + *const _tif = "tif", + *const _webp = "webp"; const char *f_type = 0; CImg header; @@ -68347,6 +68480,9 @@ namespace cimg_library { else if ((uheader[0]==0x49 && uheader[1]==0x49 && uheader[2]==0x2A && uheader[3]==0x00) || (uheader[0]==0x4D && uheader[1]==0x4D && uheader[2]==0x00 && uheader[3]==0x2A)) // TIFF f_type = _tif; + else if (uheader[0]==0x52 && uheader[1]==0x49 && uheader[2]==0x46 && uheader[3]==0x46 && + uheader[8]==0x57 && uheader[9]==0x45 && uheader[10]==0x42 && uheader[11]==0x50) // WebP + f_type = _webp; else { // PNM or PFM CImgList _header = header.get_split(CImg::vector('\n'),0,false); cimglist_for(_header,l) { From 33f0b50305763407a1332d35d6b31966c21dfba3 Mon Sep 17 00:00:00 2001 From: David Tschumperle Date: Thu, 19 Sep 2024 08:28:28 +0200 Subject: [PATCH 3/4] CImg::save_webp(): Mark argument 'quality' as unused when 'cimg_use_webp' not defined (avoid compiler warnings). --- CImg.h | 1 + 1 file changed, 1 insertion(+) diff --git a/CImg.h b/CImg.h index 0c98914f..a204205d 100644 --- a/CImg.h +++ b/CImg.h @@ -60301,6 +60301,7 @@ namespace cimg_library { "save_webp(): WebP only supports (A)RGB colorspace.", cimg_instance); #ifndef cimg_use_webp + cimg::unused(quality); return save_other(filename); #else CImg rgbaBuffer(size()); From e83fdf8f2df5bb12c00e42632f553aa04de424f2 Mon Sep 17 00:00:00 2001 From: David Tschumperle Date: Thu, 19 Sep 2024 08:49:33 +0200 Subject: [PATCH 4/4] Enabling native webp support on Linux. --- examples/Makefile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/examples/Makefile b/examples/Makefile index 75e8a36a..36ff061a 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -304,7 +304,14 @@ BOARD_INCDIR = -I/usr/include/board BOARD_CFLAGS = $(BOARD_DEFINE) $(BOARD_INCDIR) BOARD_LIBS = -lboard -# Flags to compile GIMP plug-ins. +# Enable native support of WebP image files, using the WebP library. +# (https://chromium.googlesource.com/webm/libwebp/) +WEBP_DEFINE = -Dcimg_use_webp +WEBP_INCDIR = $(shell pkg-config --cflags libwebp) +WEBP_CFLAGS = $(WEBP_DEFINE) $(WEBP_INCDIR) +WEBP_LIBS = $(shell pkg-config --libs libwep || echo -lwebp) + +# Flags to compile executable on Windows. ifeq ($(MSYSTEM),MINGW32) GIMP_CFLAGS = -mwindows endif