Rebased ref, commits from common ancestor: commit 881af695e5ae56aee3ec8534ccec4d75db2a251b Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Sat Feb 19 16:53:58 2022 +0000 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Mar 14 21:59:41 2022 +0100
upgrade expat to 2.4.5 CVE-2022-25235 CVE-2022-25236 CVE-2022-25313 CVE-2022-25314 CVE-2022-25315 Change-Id: I1cb0449411fe938fe47ab47cead685fd04e137dd diff --git a/download.lst b/download.lst index 0a7624c2d47d..fcc06ceb31d7 100644 --- a/download.lst +++ b/download.lst @@ -52,8 +52,8 @@ export EPUBGEN_TARBALL := libepubgen-0.1.1.tar.xz export ETONYEK_SHA256SUM := e61677e8799ce6e55b25afc11aa5339113f6a49cff031f336e32fa58635b1a4a export ETONYEK_VERSION_MICRO := 9 export ETONYEK_TARBALL := libetonyek-0.1.$(ETONYEK_VERSION_MICRO).tar.xz -export EXPAT_SHA256SUM := 5963005ff8720735beb2d2db669afc681adcbcb43dd1eb397d5c2dd7adbc631f -export EXPAT_TARBALL := expat-2.4.4.tar.gz +export EXPAT_SHA256SUM := f2af8fc7cdc63a87920da38cd6d12cb113c3c3a3f437495b1b6541e0cff32579 +export EXPAT_TARBALL := expat-2.4.5.tar.xz export FIREBIRD_SHA256SUM := 6994be3555e23226630c587444be19d309b25b0fcf1f87df3b4e3f88943e5860 export FIREBIRD_TARBALL := Firebird-3.0.0.32483-0.tar.bz2 export FONTCONFIG_SHA256SUM := 19e5b1bc9d013a52063a44e1307629711f0bfef35b9aca16f9c793971e2eb1e5 diff --git a/external/expat/expat-winapi.patch b/external/expat/expat-winapi.patch index bd4da1472fc8..7eae7d5d6139 100644 --- a/external/expat/expat-winapi.patch +++ b/external/expat/expat-winapi.patch @@ -13,15 +13,12 @@ --- misc/expat-2.1.0/lib/xmlparse.c 2021-05-23 16:56:25.000000000 +0100 +++ misc/build/expat-2.1.0/lib/xmlparse.c 2021-05-25 12:42:11.997173600 +0100 -@@ -92,6 +92,11 @@ +@@ -64,6 +64,8 @@ + #endif - #include <expat_config.h> - -+#ifdef _WIN32 + #ifdef _WIN32 +# undef HAVE_GETRANDOM +# undef HAVE_SYSCALL_GETRANDOM -+#endif -+ - #include "ascii.h" - #include "expat.h" - #include "siphash.h" + /* force stdlib to define rand_s() */ + # if ! defined(_CRT_RAND_S) + # define _CRT_RAND_S commit 9d547512d81b72ed20b0fafbd1e2a1cc41ac802b Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Sun Jan 30 19:28:23 2022 +0000 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Mar 14 21:59:40 2022 +0100 upgrade to expat 2.4.4 Change-Id: Ie141268793dc4332d8c253bec4e986894682c7a6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129179 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caol...@redhat.com> diff --git a/download.lst b/download.lst index 281e485ed588..0a7624c2d47d 100644 --- a/download.lst +++ b/download.lst @@ -52,8 +52,8 @@ export EPUBGEN_TARBALL := libepubgen-0.1.1.tar.xz export ETONYEK_SHA256SUM := e61677e8799ce6e55b25afc11aa5339113f6a49cff031f336e32fa58635b1a4a export ETONYEK_VERSION_MICRO := 9 export ETONYEK_TARBALL := libetonyek-0.1.$(ETONYEK_VERSION_MICRO).tar.xz -export EXPAT_SHA256SUM := 2f9b6a580b94577b150a7d5617ad4643a4301a6616ff459307df3e225bcfbf40 -export EXPAT_TARBALL := expat-2.4.1.tar.bz2 +export EXPAT_SHA256SUM := 5963005ff8720735beb2d2db669afc681adcbcb43dd1eb397d5c2dd7adbc631f +export EXPAT_TARBALL := expat-2.4.4.tar.gz export FIREBIRD_SHA256SUM := 6994be3555e23226630c587444be19d309b25b0fcf1f87df3b4e3f88943e5860 export FIREBIRD_TARBALL := Firebird-3.0.0.32483-0.tar.bz2 export FONTCONFIG_SHA256SUM := 19e5b1bc9d013a52063a44e1307629711f0bfef35b9aca16f9c793971e2eb1e5 commit 99b1556c6343a17b900d1557878b7fa6a1039b3d Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Thu Jan 13 15:59:49 2022 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Mar 14 21:59:40 2022 +0100 support for the WebP image format (tdf#114532) This commit implements a WebP reader and writer for both lossless and lossy WebP, export dialog options for selecting lossless/lossy and quality for lossy, and various internal support for the format. Since writing WebP to e.g. ODT documents would make those images unreadable by previous versions with no WebP support, support for that is explicitly disabled in GraphicFilter, to be enabled somewhen later. Change-Id: I9b10f6da6faa78a0bb74415a92e9f163c14685f7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128978 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/Makefile.fetch b/Makefile.fetch index 0a6202a4b3c7..8e6cff22e0bc 100644 --- a/Makefile.fetch +++ b/Makefile.fetch @@ -163,6 +163,7 @@ $(WORKDIR)/download: $(BUILDDIR)/config_$(gb_Side).mk $(SRCDIR)/download.lst $(S $(call fetch_Optional,LIBNUMBERTEXT,LIBNUMBERTEXT_TARBALL) \ $(call fetch_Optional,LIBPNG,LIBPNG_TARBALL) \ $(call fetch_Optional,LIBTOMMATH,LIBTOMMATH_TARBALL) \ + $(call fetch_Optional,LIBWEBP,LIBWEBP_TARBALL) \ $(call fetch_Optional,LIBXML2,LIBXML_TARBALL) \ $(call fetch_Optional,XMLSEC,XMLSEC_TARBALL) \ $(call fetch_Optional,LIBXSLT,LIBXSLT_TARBALL) \ diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk index 12d59fb206e0..15125ff10c60 100644 --- a/RepositoryExternal.mk +++ b/RepositoryExternal.mk @@ -2719,6 +2719,57 @@ endef endif # !SYSTEM_LIBPNG +ifneq ($(SYSTEM_LIBWEBP),) + +define gb_LinkTarget__use_libwebp +$(call gb_LinkTarget_set_include,$(1),\ + $$(INCLUDE) \ + $(LIBWEBP_CFLAGS) \ +) + +$(call gb_LinkTarget_add_libs,$(1),\ + $(LIBWEBP_LIBS) \ +) + +endef + +gb_ExternalProject__use_libwebp := + +else # !SYSTEM_LIBWEBP + +define gb_LinkTarget__use_libwebp +$(call gb_LinkTarget_set_include,$(1),\ + $(LIBWEBP_CFLAGS) \ + $$(INCLUDE) \ +) + +$(call gb_LinkTarget_set_include,$(1),\ + -I$(call gb_UnpackedTarball_get_dir,libwebp)/src \ + $$(INCLUDE) \ +) +ifeq ($(OS),WNT) +$(call gb_LinkTarget_add_libs,$(1),\ + $(call gb_UnpackedTarball_get_dir,libwebp)/output/lib/libwebp$(gb_StaticLibrary_PLAINEXT) \ +) +else +$(call gb_LinkTarget_add_libs,$(1),\ + -L$(call gb_UnpackedTarball_get_dir,libwebp)/src/.libs -lwebp \ +) +endif +$(call gb_LinkTarget_use_external_project,$(1),libwebp) + +endef + +define gb_ExternalProject__use_libwebp +$(call gb_ExternalProject_use_external_project,$(1),\ + libwebp \ +) + +endef + +endif # !SYSTEM_LIBWEBP + + ifneq ($(SYSTEM_CURL),) define gb_LinkTarget__use_curl diff --git a/bin/lo-all-static-libs b/bin/lo-all-static-libs index d89dd8eca296..455861da5a73 100755 --- a/bin/lo-all-static-libs +++ b/bin/lo-all-static-libs @@ -124,6 +124,7 @@ echo $INSTDIR/$LIBO_LIB_FOLDER/lib*.a \ $WORKDIR/UnpackedTarball/liborcus/src/*/.libs/*.a \ $WORKDIR/UnpackedTarball/librevenge/src/*/.libs/*.a \ $WORKDIR/UnpackedTarball/libvisio/src/lib/.libs/*.a \ + $WORKDIR/UnpackedTarball/libwebp/src/.libs/*.a \ $WORKDIR/UnpackedTarball/libwp?/src/lib/.libs/*.a \ $WORKDIR/UnpackedTarball/raptor/src/.libs/*.a \ $WORKDIR/UnpackedTarball/rasqal/src/.libs/*.a \ diff --git a/config_host.mk.in b/config_host.mk.in index d6edba704b21..fe40aae50387 100644 --- a/config_host.mk.in +++ b/config_host.mk.in @@ -387,6 +387,8 @@ export LIBSERIALIZER_JAR=@LIBSERIALIZER_JAR@ export LIBTOMMATH_CFLAGS=@LIBTOMMATH_CFLAGS@ export LIBTOMMATH_LIBS=@LIBTOMMATH_LIBS@ export LIBTOOL=@LIBTOOL@ +export LIBWEBP_CFLAGS=$(gb_SPACE)@LIBWEBP_CFLAGS@ +export LIBWEBP_LIBS=$(gb_SPACE)@LIBWEBP_LIBS@ export LIBXML_CFLAGS=$(gb_SPACE)@LIBXML_CFLAGS@ export LIBXML_JAR=@LIBXML_JAR@ export LIBXML_LIBS=$(gb_SPACE)@LIBXML_LIBS@ @@ -593,6 +595,7 @@ export SYSTEM_LIBNUMBERTEXT_DATA=@SYSTEM_LIBNUMBERTEXT_DATA@ export SYSTEM_LIBORCUS=@SYSTEM_LIBORCUS@ export SYSTEM_LIBPNG=@SYSTEM_LIBPNG@ export SYSTEM_LIBTOMMATH=@SYSTEM_LIBTOMMATH@ +export SYSTEM_LIBWEBP=@SYSTEM_LIBWEBP@ export SYSTEM_LIBXML=@SYSTEM_LIBXML@ export SYSTEM_LIBXML_FOR_BUILD=@SYSTEM_LIBXML_FOR_BUILD@ export SYSTEM_LIBXSLT=@SYSTEM_LIBXSLT@ diff --git a/configure.ac b/configure.ac index bd28bc6eb38e..4b6958f6cf67 100644 --- a/configure.ac +++ b/configure.ac @@ -13023,6 +13023,12 @@ dnl =================================================================== libo_CHECK_SYSTEM_MODULE([libpng],[LIBPNG],[libpng],["-I${WORKDIR}/UnpackedTarball/libpng"],["-L${WORKDIR}/LinkTarget/StaticLibrary -llibpng"]) +dnl =================================================================== +dnl Test whether to build libwebp or rely on the system version +dnl =================================================================== + +libo_CHECK_SYSTEM_MODULE([libwebp],[LIBWEBP],[libwebp]) + dnl =================================================================== dnl Check for runtime JVM search path dnl =================================================================== diff --git a/download.lst b/download.lst index cc0480cc9994..281e485ed588 100644 --- a/download.lst +++ b/download.lst @@ -166,6 +166,8 @@ export LIBNUMBERTEXT_SHA256SUM := 17b8249cb89ae11ae15a85612d2665626c0e0e3e56b356 export LIBNUMBERTEXT_TARBALL := libnumbertext-1.0.7.tar.xz export LIBTOMMATH_SHA256SUM := 083daa92d8ee6f4af96a6143b12d7fc8fe1a547e14f862304f7281f8f7347483 export LIBTOMMATH_TARBALL := ltm-1.0.zip +export LIBWEBP_SHA256SUM := 808b98d2f5b84e9b27fdef6c5372dac769c3bda4502febbfa5031bd3c4d7d018 +export LIBWEBP_TARBALL := libwebp-1.2.1.tar.gz export XMLSEC_SHA256SUM := 2d84360b03042178def1d9ff538acacaed2b3a27411db7b2874f1612ed71abc8 export XMLSEC_TARBALL := xmlsec1-1.2.30.tar.gz export LIBXML_SHA256SUM := c8d6681e38c56f172892c85ddc0852e1fd4b53b4209e7f4ebf17f7e2eae71d92 diff --git a/external/Module_external.mk b/external/Module_external.mk index 1c722a325c2d..2f40ab510261 100644 --- a/external/Module_external.mk +++ b/external/Module_external.mk @@ -64,6 +64,7 @@ $(eval $(call gb_Module_add_moduledirs,external,\ $(call gb_Helper_optional,LIBLANGTAG,liblangtag) \ $(call gb_Helper_optional,LIBNUMBERTEXT,libnumbertext) \ $(call gb_Helper_optional,LIBPNG,libpng) \ + $(call gb_Helper_optional,LIBWEBP,libwebp) \ $(call gb_Helper_optional,LIBXML2,libxml2) \ $(call gb_Helper_optional,LIBXSLT,libxslt) \ $(call gb_Helper_optional,LPSOLVE,lpsolve) \ diff --git a/external/libwebp/ExternalProject_libwebp.mk b/external/libwebp/ExternalProject_libwebp.mk new file mode 100644 index 000000000000..beb7a39e7b64 --- /dev/null +++ b/external/libwebp/ExternalProject_libwebp.mk @@ -0,0 +1,52 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_ExternalProject_ExternalProject,libwebp)) + +$(eval $(call gb_ExternalProject_register_targets,libwebp,\ + build \ +)) + +ifeq ($(COM),MSC) +$(eval $(call gb_ExternalProject_use_nmake,libwebp,build)) + +$(call gb_ExternalProject_get_state_target,libwebp,build): + $(call gb_Trace_StartRange,libwebp,EXTERNAL) + $(call gb_ExternalProject_run,build,\ + nmake -nologo -f Makefile.vc CFG=release-static RTLIBCFG=static OBJDIR=output \ + ) + $(call gb_Trace_EndRange,libwebp,EXTERNAL) +else +$(eval $(call gb_ExternalProject_use_autoconf,libwebp,build)) + +$(call gb_ExternalProject_get_state_target,libwebp,build) : + $(call gb_Trace_StartRange,libwebp,EXTERNAL) + $(call gb_ExternalProject_run,build,\ + export PKG_CONFIG="" \ + && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \ + --enable-static \ + --with-pic \ + --disable-shared \ + --disable-gl \ + --disable-sdl \ + --disable-png \ + --disable-jpeg \ + --disable-tiff \ + --disable-gif \ + --disable-wic \ + $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \ + CXXFLAGS="$(gb_CXXFLAGS) $(if $(ENABLE_OPTIMIZED),$(gb_COMPILEROPTFLAGS),$(gb_COMPILERNOOPTFLAGS))" \ + CPPFLAGS="$(CPPFLAGS) $(BOOST_CPPFLAGS)" \ + $(if $(CROSS_COMPILING),--build=$(BUILD_PLATFORM) --host=$(HOST_PLATFORM)) \ + && $(MAKE) \ + ) + $(call gb_Trace_EndRange,libwebp,EXTERNAL) +endif + +# vim: set noet sw=4 ts=4: diff --git a/external/libwebp/Makefile b/external/libwebp/Makefile new file mode 100644 index 000000000000..e4968cf85fb6 --- /dev/null +++ b/external/libwebp/Makefile @@ -0,0 +1,7 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- + +module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST)))) + +include $(module_directory)/../../solenv/gbuild/partial_build.mk + +# vim: set noet sw=4 ts=4: diff --git a/external/libwebp/Makefile.vc.patch b/external/libwebp/Makefile.vc.patch new file mode 100644 index 000000000000..653998319b82 --- /dev/null +++ b/external/libwebp/Makefile.vc.patch @@ -0,0 +1,145 @@ +--- Makefile.vc.sav 2021-07-30 00:55:37.000000000 +0200 ++++ Makefile.vc 2022-01-25 17:35:30.206117700 +0100 +@@ -7,11 +7,11 @@ + LIBWEBPDEMUX_BASENAME = libwebpdemux + + !IFNDEF ARCH +-!IF ! [ cl 2>&1 | find "x86" > NUL ] ++!IF ! [ $(CC) 2>&1 | grep -q "x86" > NUL ] + ARCH = x86 +-!ELSE IF ! [ cl 2>&1 | find "x64" > NUL ] ++!ELSE IF ! [ $(CC) 2>&1 | grep -q "x64" > NUL ] + ARCH = x64 +-!ELSE IF ! [ cl 2>&1 | find "ARM" > NUL ] ++!ELSE IF ! [ $(CC) 2>&1 | grep -q "ARM" > NUL ] + ARCH = ARM + !ELSE + !ERROR Unable to auto-detect toolchain architecture! \ +@@ -27,8 +27,8 @@ + ## Nothing more to do below this line! + + NOLOGO = /nologo +-CCNODBG = cl.exe $(NOLOGO) /O2 /DNDEBUG +-CCDEBUG = cl.exe $(NOLOGO) /Od /Zi /D_DEBUG /RTC1 ++CCNODBG = $(CC) $(NOLOGO) /O2 /DNDEBUG ++CCDEBUG = $(CC) $(NOLOGO) /Od /Zi /D_DEBUG /RTC1 + CFLAGS = /I. /Isrc $(NOLOGO) /W3 /EHsc /c + CFLAGS = $(CFLAGS) /DWIN32 /D_CRT_SECURE_NO_WARNINGS /DWIN32_LEAN_AND_MEAN + LDFLAGS = /LARGEADDRESSAWARE /MANIFEST /NXCOMPAT /DYNAMICBASE +@@ -67,7 +67,7 @@ + RTLIB = /MD + RTLIBD = /MDd + !ENDIF +-DIRBASE = $(OUTDIR)\$(CFG)\$(ARCH) ++DIRBASE = $(OUTDIR) + DIROBJ = $(DIRBASE)\obj + DIRLIB = $(DIRBASE)\lib + DIRINC = $(DIRBASE)\include +@@ -86,10 +86,10 @@ + + # Target configuration + !IF "$(CFG)" == "release-static" +-CC = $(CCNODBG) ++CC_ = $(CCNODBG) + STATICLIBBUILD = TRUE + !ELSE IF "$(CFG)" == "debug-static" +-CC = $(CCDEBUG) ++CC_ = $(CCDEBUG) + RTLIB = $(RTLIBD) + STATICLIBBUILD = TRUE + LIBWEBPDECODER_BASENAME = $(LIBWEBPDECODER_BASENAME)_debug +@@ -97,11 +97,11 @@ + LIBWEBPMUX_BASENAME = $(LIBWEBPMUX_BASENAME)_debug + LIBWEBPDEMUX_BASENAME = $(LIBWEBPDEMUX_BASENAME)_debug + !ELSE IF "$(CFG)" == "release-dynamic" +-CC = $(CCNODBG) ++CC_ = $(CCNODBG) + RC = $(RCNODBG) + DLLBUILD = TRUE + !ELSE IF "$(CFG)" == "debug-dynamic" +-CC = $(CCDEBUG) ++CC_ = $(CCDEBUG) + RC = $(RCDEBUG) + RTLIB = $(RTLIBD) + DLLBUILD = TRUE +@@ -112,7 +112,7 @@ + !ENDIF + + !IF "$(STATICLIBBUILD)" == "TRUE" +-CC = $(CC) $(RTLIB) ++CC_ = $(CC_) $(RTLIB) + CFGSET = TRUE + LIBWEBPDECODER = $(DIRLIB)\$(LIBWEBPDECODER_BASENAME).lib + LIBWEBP = $(DIRLIB)\$(LIBWEBP_BASENAME).lib +@@ -120,7 +120,7 @@ + LIBWEBPDEMUX = $(DIRLIB)\$(LIBWEBPDEMUX_BASENAME).lib + !ELSE IF "$(DLLBUILD)" == "TRUE" + DLLINC = webp_dll.h +-CC = $(CC) /I$(DIROBJ) /FI$(DLLINC) $(RTLIB) /DWEBP_DLL ++CC_ = $(CC_) /I$(DIROBJ) /FI$(DLLINC) $(RTLIB) /DWEBP_DLL + LIBWEBPDECODER = $(DIRLIB)\$(LIBWEBPDECODER_BASENAME)_dll.lib + LIBWEBP = $(DIRLIB)\$(LIBWEBP_BASENAME)_dll.lib + LIBWEBPMUX = $(DIRLIB)\$(LIBWEBPMUX_BASENAME)_dll.lib +@@ -421,7 +421,7 @@ + $(DIROBJ)\$(DLLINC) + + {$(DIROBJ)}.c{$(DIROBJ)}.obj: +- $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$@ $< ++ $(CC_) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$@ $< + + {src}.rc{$(DIROBJ)}.res: + $(RC) /fo$@ $< +@@ -461,39 +461,39 @@ + # File-specific flag builds. Note batch rules take precedence over wildcards, + # so for now name each file individually. + $(DIROBJ)\examples\anim_diff.obj: examples\anim_diff.c +- $(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ ++ $(CC_) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ + /Fo$(DIROBJ)\examples\ examples\$(@B).c + $(DIROBJ)\examples\anim_dump.obj: examples\anim_dump.c +- $(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ ++ $(CC_) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ + /Fo$(DIROBJ)\examples\ examples\$(@B).c + $(DIROBJ)\examples\anim_util.obj: examples\anim_util.c +- $(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ ++ $(CC_) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ + /Fo$(DIROBJ)\examples\ examples\$(@B).c + $(DIROBJ)\examples\gif2webp.obj: examples\gif2webp.c +- $(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ ++ $(CC_) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ + /Fo$(DIROBJ)\examples\ examples\$(@B).c + $(DIROBJ)\examples\gifdec.obj: examples\gifdec.c +- $(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ ++ $(CC_) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ + /Fo$(DIROBJ)\examples\ examples\$(@B).c + # Batch rules + {examples}.c{$(DIROBJ)\examples}.obj:: +- $(CC) $(CFLAGS) /Fd$(DIROBJ)\examples\ /Fo$(DIROBJ)\examples\ $< ++ $(CC_) $(CFLAGS) /Fd$(DIROBJ)\examples\ /Fo$(DIROBJ)\examples\ $< + {extras}.c{$(DIROBJ)\extras}.obj:: +- $(CC) $(CFLAGS) /Fd$(DIROBJ)\extras\ /Fo$(DIROBJ)\extras\ $< ++ $(CC_) $(CFLAGS) /Fd$(DIROBJ)\extras\ /Fo$(DIROBJ)\extras\ $< + {imageio}.c{$(DIROBJ)\imageio}.obj:: +- $(CC) $(CFLAGS) /Fd$(DIROBJ)\imageio\ /Fo$(DIROBJ)\imageio\ $< ++ $(CC_) $(CFLAGS) /Fd$(DIROBJ)\imageio\ /Fo$(DIROBJ)\imageio\ $< + {src\dec}.c{$(DIROBJ)\dec}.obj:: +- $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dec\ $< ++ $(CC_) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dec\ $< + {src\demux}.c{$(DIROBJ)\demux}.obj:: +- $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\demux\ $< ++ $(CC_) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\demux\ $< + {src\dsp}.c{$(DIROBJ)\dsp}.obj:: +- $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dsp\ $< ++ $(CC_) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dsp\ $< + {src\enc}.c{$(DIROBJ)\enc}.obj:: +- $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\enc\ $< ++ $(CC_) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\enc\ $< + {src\mux}.c{$(DIROBJ)\mux}.obj:: +- $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\mux\ $< ++ $(CC_) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\mux\ $< + {src\utils}.c{$(DIROBJ)\utils}.obj:: +- $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\utils\ $< ++ $(CC_) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\utils\ $< + + LNKLIBS = ole32.lib windowscodecs.lib shlwapi.lib + !IF "$(UNICODE)" == "1" diff --git a/external/libwebp/Module_libwebp.mk b/external/libwebp/Module_libwebp.mk new file mode 100644 index 000000000000..b89056ac3d35 --- /dev/null +++ b/external/libwebp/Module_libwebp.mk @@ -0,0 +1,17 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_Module_Module,libwebp)) + +$(eval $(call gb_Module_add_targets,libwebp,\ + ExternalProject_libwebp \ + UnpackedTarball_libwebp \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/external/libwebp/README b/external/libwebp/README new file mode 100644 index 000000000000..1308c278baca --- /dev/null +++ b/external/libwebp/README @@ -0,0 +1 @@ +libwebp is a library to encode and decode images in WebP format, from [https://developers.google.com/speed/webp/] diff --git a/external/libwebp/UnpackedTarball_libwebp.mk b/external/libwebp/UnpackedTarball_libwebp.mk new file mode 100644 index 000000000000..67f797157717 --- /dev/null +++ b/external/libwebp/UnpackedTarball_libwebp.mk @@ -0,0 +1,20 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_UnpackedTarball_UnpackedTarball,libwebp)) + +$(eval $(call gb_UnpackedTarball_set_tarball,libwebp,$(LIBWEBP_TARBALL))) + +$(eval $(call gb_UnpackedTarball_set_patchlevel,libwebp,0)) + +$(eval $(call gb_UnpackedTarball_add_patches,libwebp,\ + external/libwebp/Makefile.vc.patch \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/filter/Configuration_filter.mk b/filter/Configuration_filter.mk index d53afa704fc9..efe7b10988dc 100644 --- a/filter/Configuration_filter.mk +++ b/filter/Configuration_filter.mk @@ -440,6 +440,7 @@ $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_web_filters.xc writer_web_pdf_Export\ writer_web_png_Export\ writer_web_jpg_Export\ + writer_web_webp_Export\ writerweb8_writer_template\ writerweb8_writer \ )) @@ -713,6 +714,7 @@ $(eval $(call filter_Configuration_add_types,fcfg_langpack,fcfg_drawgraphics_typ svm_StarView_Metafile \ tga_Truevision_TARGA \ tif_Tag_Image_File \ + webp_WebP \ wmf_MS_Windows_Metafile \ xbm_X_Consortium \ xpm_XPM \ @@ -740,6 +742,7 @@ $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_drawgraphics_f SVM___StarView_Metafile \ TGA___Truevision_TARGA \ TIF___Tag_Image_File \ + WEBP___WebP \ WMF___MS_Windows_Metafile \ XBM___X_Consortium \ XPM \ @@ -755,6 +758,7 @@ $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_drawgraphics_f draw_png_Export \ draw_svg_Export \ draw_tif_Export \ + draw_webp_Export \ draw_wmf_Export \ )) @@ -779,6 +783,7 @@ $(eval $(call filter_Configuration_add_types,fcfg_langpack,fcfg_impressgraphics_ svm_StarView_Metafile \ tif_Tag_Image_File \ wmf_MS_Windows_Metafile \ + webp_WebP \ xpm_XPM \ )) @@ -793,6 +798,7 @@ $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_impressgraphic impress_png_Export \ impress_svg_Export \ impress_tif_Export \ + impress_webp_Export \ impress_wmf_Export \ )) @@ -807,6 +813,7 @@ $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_writergraphics writer_jpg_Export \ writer_png_Export \ writer_svg_Export \ + writer_webp_Export \ )) # fcfg_calcgraphics @@ -819,6 +826,7 @@ $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_calcgraphics_f calc_jpg_Export \ calc_png_Export \ calc_svg_Export \ + calc_webp_Export \ )) # fcfg_internalgraphics @@ -846,6 +854,7 @@ $(eval $(call filter_Configuration_add_types,fcfg_langpack,fcfg_internalgraphics svm_StarView_Metafile \ tga_Truevision_TARGA \ tif_Tag_Image_File \ + webp_WebP \ wmf_MS_Windows_Metafile \ xbm_X_Consortium \ xpm_XPM \ @@ -885,11 +894,13 @@ $(eval $(call filter_Configuration_add_internal_filters,fcfg_langpack,fcfg_inter tga_Import \ tif_Export \ tif_Import \ + webp_Export \ + webp_Import \ wmf_Export \ wmf_Import \ xbm_Import \ xpm_Import \ - mov_Import \ + mov_Import \ )) # fcfg_xslt diff --git a/filter/qa/complex/filter/detection/typeDetection/files.csv b/filter/qa/complex/filter/detection/typeDetection/files.csv index b882ea1179ca..8e558590b4e7 100644 --- a/filter/qa/complex/filter/detection/typeDetection/files.csv +++ b/filter/qa/complex/filter/detection/typeDetection/files.csv @@ -111,6 +111,7 @@ ppm;Graphics/pic.ppm;ppm_Portable_Pixelmap;ppm_Portable_Pixelmap ras;Graphics/pic.ras;ras_Sun_Rasterfile;ras_Sun_Rasterfile svm;Graphics/pic.svm;svm_StarView_Metafile;svm_StarView_Metafile:generic_Text tif;Graphics/pic.tif;tif_Tag_Image_File;tif_Tag_Image_File:generic_Text +webp;Graphics/pic.webp;webp_WebP;webp_WebP wmf;Graphics/pic.wmf;wmf_MS_Windows_Metafile;wmf_MS_Windows_Metafile:generic_Text diff --git a/filter/source/config/cache/typedetection.cxx b/filter/source/config/cache/typedetection.cxx index e9e149511cff..c06a0db12d2c 100644 --- a/filter/source/config/cache/typedetection.cxx +++ b/filter/source/config/cache/typedetection.cxx @@ -232,6 +232,7 @@ int getFlatTypeRank(const OUString& rType) "pcd_Photo_CD_Base", "pcd_Photo_CD_Base4", "pcd_Photo_CD_Base16", + "webp_WebP", "impress_CGM_Computer_Graphics_Metafile", // There is binary and ascii variants ? "draw_WordPerfect_Graphics", "draw_Visio_Document", diff --git a/filter/source/config/fragments/filters/WEBP___WebP.xcu b/filter/source/config/fragments/filters/WEBP___WebP.xcu new file mode 100644 index 000000000000..9c650e3de42e --- /dev/null +++ b/filter/source/config/fragments/filters/WEBP___WebP.xcu @@ -0,0 +1,30 @@ +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . +--> + <node oor:name="WEBP - WebP" oor:op="replace"> + <prop oor:name="Flags"><value>IMPORT ALIEN</value></prop> + <prop oor:name="UIComponent"/> + <prop oor:name="FilterService"/> + <prop oor:name="UserData"><value></value></prop> + <prop oor:name="UIName"> + <value xml:lang="en-US">WEBP - WebP Image</value> + </prop> + <prop oor:name="FileFormatVersion"><value>0</value></prop> + <prop oor:name="Type"><value>webp_WebP</value></prop> + <prop oor:name="TemplateName"/> + <prop oor:name="DocumentService"><value>com.sun.star.drawing.DrawingDocument</value></prop> + </node> diff --git a/filter/source/config/fragments/filters/calc_webp_Export.xcu b/filter/source/config/fragments/filters/calc_webp_Export.xcu new file mode 100644 index 000000000000..a6e5d18a3347 --- /dev/null +++ b/filter/source/config/fragments/filters/calc_webp_Export.xcu @@ -0,0 +1,20 @@ +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. +--> + <node oor:name="calc_webp_Export" oor:op="replace"> + <prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER SUPPORTSSELECTION</value></prop> + <prop oor:name="UIComponent"><value>com.sun.star.svtools.SvFilterOptionsDialog</value></prop> + <prop oor:name="FilterService"><value>com.sun.star.comp.GraphicExportFilter</value></prop> + <prop oor:name="UserData"><value></value></prop> + <prop oor:name="UIName"> + <value xml:lang="en-US">WEBP - WebP Image</value> + </prop> + <prop oor:name="FileFormatVersion"><value>0</value></prop> + <prop oor:name="Type"><value>webp_WebP</value></prop> + <prop oor:name="TemplateName"/> + <prop oor:name="DocumentService"><value>com.sun.star.sheet.SpreadsheetDocument</value></prop> + </node> diff --git a/filter/source/config/fragments/filters/draw_webp_Export.xcu b/filter/source/config/fragments/filters/draw_webp_Export.xcu new file mode 100644 index 000000000000..e6da69197a61 --- /dev/null +++ b/filter/source/config/fragments/filters/draw_webp_Export.xcu @@ -0,0 +1,30 @@ +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . +--> + <node oor:name="draw_webp_Export" oor:op="replace"> + <prop oor:name="Flags"><value>EXPORT ALIEN SUPPORTSSELECTION</value></prop> + <prop oor:name="UIComponent"><value>com.sun.star.svtools.SvFilterOptionsDialog</value></prop> + <prop oor:name="FilterService"/> + <prop oor:name="UserData"><value></value></prop> + <prop oor:name="UIName"> + <value xml:lang="en-US">WEBP - WebP Image</value> + </prop> + <prop oor:name="FileFormatVersion"><value>0</value></prop> + <prop oor:name="Type"><value>webp_WebP</value></prop> + <prop oor:name="TemplateName"/> + <prop oor:name="DocumentService"><value>com.sun.star.drawing.DrawingDocument</value></prop> + </node> diff --git a/filter/source/config/fragments/filters/impress_webp_Export.xcu b/filter/source/config/fragments/filters/impress_webp_Export.xcu new file mode 100644 index 000000000000..00284a272cba --- /dev/null +++ b/filter/source/config/fragments/filters/impress_webp_Export.xcu @@ -0,0 +1,30 @@ +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . +--> + <node oor:name="impress_webp_Export" oor:op="replace"> + <prop oor:name="Flags"><value>EXPORT ALIEN SUPPORTSSELECTION</value></prop> + <prop oor:name="UIComponent"><value>com.sun.star.svtools.SvFilterOptionsDialog</value></prop> + <prop oor:name="FilterService"/> + <prop oor:name="UserData"><value></value></prop> + <prop oor:name="UIName"> + <value xml:lang="en-US">WEBP - WebP Image</value> + </prop> + <prop oor:name="FileFormatVersion"><value>0</value></prop> + <prop oor:name="Type"><value>webp_WebP</value></prop> + <prop oor:name="TemplateName"/> + <prop oor:name="DocumentService"><value>com.sun.star.presentation.PresentationDocument</value></prop> + </node> diff --git a/filter/source/config/fragments/filters/writer_web_webp_Export.xcu b/filter/source/config/fragments/filters/writer_web_webp_Export.xcu new file mode 100644 index 000000000000..5273bb72228b --- /dev/null +++ b/filter/source/config/fragments/filters/writer_web_webp_Export.xcu @@ -0,0 +1,21 @@ +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * +--> + <node oor:name="writer_web_webp_Export" oor:op="replace"> + <prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop> + <prop oor:name="UIComponent"><value>com.sun.star.svtools.SvFilterOptionsDialog</value></prop> + <prop oor:name="FilterService"><value>com.sun.star.comp.GraphicExportFilter</value></prop> + <prop oor:name="UserData"><value></value></prop> + <prop oor:name="UIName"> + <value xml:lang="en-US">WEBP - WebP Image</value> + </prop> + <prop oor:name="FileFormatVersion"><value>0</value></prop> + <prop oor:name="Type"><value>webp_WebP</value></prop> + <prop oor:name="TemplateName"/> + <prop oor:name="DocumentService"><value>com.sun.star.text.WebDocument</value></prop> + </node> diff --git a/filter/source/config/fragments/filters/writer_webp_Export.xcu b/filter/source/config/fragments/filters/writer_webp_Export.xcu new file mode 100644 index 000000000000..ceb56a8c035f --- /dev/null +++ b/filter/source/config/fragments/filters/writer_webp_Export.xcu @@ -0,0 +1,30 @@ +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . +--> + <node oor:name="writer_webp_Export" oor:op="replace"> + <prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop> + <prop oor:name="UIComponent"><value>com.sun.star.svtools.SvFilterOptionsDialog</value></prop> + <prop oor:name="FilterService"><value>com.sun.star.comp.GraphicExportFilter</value></prop> + <prop oor:name="UserData"><value></value></prop> + <prop oor:name="UIName"> + <value xml:lang="en-US">WEBP - WebP Image</value> + </prop> + <prop oor:name="FileFormatVersion"><value>0</value></prop> + <prop oor:name="Type"><value>webp_WebP</value></prop> + <prop oor:name="TemplateName"/> + <prop oor:name="DocumentService"><value>com.sun.star.text.TextDocument</value></prop> + </node> diff --git a/filter/source/config/fragments/internalgraphicfilters/webp_Export.xcu b/filter/source/config/fragments/internalgraphicfilters/webp_Export.xcu new file mode 100644 index 000000000000..70ff15429734 --- /dev/null +++ b/filter/source/config/fragments/internalgraphicfilters/webp_Export.xcu @@ -0,0 +1,27 @@ +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . +--> + <node oor:name="webp_Export" oor:op="replace" > + <prop oor:name="Type"><value>webp_WebP</value></prop> + <prop oor:name="FormatName"><value>SVEWEBP</value></prop> + <prop oor:name="RealFilterName"/> + <prop oor:name="UIComponent"><value>com.sun.star.svtools.SvFilterOptionsDialog</value></prop> + <prop oor:name="UIName"> + <value xml:lang="en-US">WEBP - WebP Image</value> + </prop> + <prop oor:name="Flags"><value>EXPORT</value></prop> + </node> diff --git a/filter/source/config/fragments/internalgraphicfilters/webp_Import.xcu b/filter/source/config/fragments/internalgraphicfilters/webp_Import.xcu new file mode 100644 index 000000000000..cdce5c9e4047 --- /dev/null +++ b/filter/source/config/fragments/internalgraphicfilters/webp_Import.xcu @@ -0,0 +1,27 @@ +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . +--> + <node oor:name="webp_Import" oor:op="replace" > + <prop oor:name="Type"><value>webp_WebP</value></prop> + <prop oor:name="FormatName"><value>SVIWEBP</value></prop> + <prop oor:name="RealFilterName"><value>WEBP - WebP</value></prop> + <prop oor:name="UIComponent"/> + <prop oor:name="UIName"> + <value xml:lang="en-US">WEBP - WebP Image</value> + </prop> + <prop oor:name="Flags"><value>IMPORT</value></prop> + </node> diff --git a/filter/source/config/fragments/types/webp_WebP.xcu b/filter/source/config/fragments/types/webp_WebP.xcu new file mode 100644 index 000000000000..e58984fbedc7 --- /dev/null +++ b/filter/source/config/fragments/types/webp_WebP.xcu @@ -0,0 +1,29 @@ +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . +--> + <node oor:name="webp_WebP" oor:op="replace" > + <prop oor:name="DetectService"><value>com.sun.star.comp.draw.FormatDetector</value></prop> + <prop oor:name="URLPattern"/> + <prop oor:name="Extensions"><value>webp</value></prop> + <prop oor:name="MediaType"><value>image/webp</value></prop> + <prop oor:name="Preferred"><value>false</value></prop> + <prop oor:name="PreferredFilter"><value>WEBP - WebP</value></prop> + <prop oor:name="UIName"> + <value>WEBP - WebP Image</value> + </prop> + <prop oor:name="ClipboardFormat"/> + </node> diff --git a/icon-themes/breeze/res/sx03223.png b/icon-themes/breeze/res/sx03223.png new file mode 100644 index 000000000000..82e6f7b14f31 Binary files /dev/null and b/icon-themes/breeze/res/sx03223.png differ diff --git a/icon-themes/breeze_dark/res/sx03223.png b/icon-themes/breeze_dark/res/sx03223.png new file mode 100644 index 000000000000..82e6f7b14f31 Binary files /dev/null and b/icon-themes/breeze_dark/res/sx03223.png differ diff --git a/icon-themes/breeze_dark_svg/res/sx03223.svg b/icon-themes/breeze_dark_svg/res/sx03223.svg new file mode 100644 index 000000000000..576860153fb7 --- /dev/null +++ b/icon-themes/breeze_dark_svg/res/sx03223.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m2 2v8.992188l-1 1v.007812h1v2h12v-2.998047h1v-.009765l-1-1.0000005v-7.9921875zm1 1h10v5.9921875l-3.9941406-3.9921875h-.0058594v.0019531h-.0058594l-2.4960937 2.4921875-.4941407-.4941406h-.0039062-.0039062l-2.9960938 2.9941406zm2 1c-.554 0-1 .446-1 1s.446 1 1 1 1-.446 1-1-.446-1-1-1zm4 2.4101562 4 3.9980468v.591797h-2.992188l-2.8007808-2.796875zm-3 2 .5.5 2.0898438 2.0898438h-5.1816407zm-3 3.5898438h6.5898438l.0019531.001953h1.4082031v-.001953h2v1h-10z" fill="#4e9b06"/></svg> \ No newline at end of file diff --git a/icon-themes/breeze_svg/res/sx03223.svg b/icon-themes/breeze_svg/res/sx03223.svg new file mode 100644 index 000000000000..576860153fb7 --- /dev/null +++ b/icon-themes/breeze_svg/res/sx03223.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m2 2v8.992188l-1 1v.007812h1v2h12v-2.998047h1v-.009765l-1-1.0000005v-7.9921875zm1 1h10v5.9921875l-3.9941406-3.9921875h-.0058594v.0019531h-.0058594l-2.4960937 2.4921875-.4941407-.4941406h-.0039062-.0039062l-2.9960938 2.9941406zm2 1c-.554 0-1 .446-1 1s.446 1 1 1 1-.446 1-1-.446-1-1-1zm4 2.4101562 4 3.9980468v.591797h-2.992188l-2.8007808-2.796875zm-3 2 .5.5 2.0898438 2.0898438h-5.1816407zm-3 3.5898438h6.5898438l.0019531.001953h1.4082031v-.001953h2v1h-10z" fill="#4e9b06"/></svg> \ No newline at end of file diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox index 94733ff414ad..fdea223f45d3 100644 --- a/include/sal/log-areas.dox +++ b/include/sal/log-areas.dox @@ -468,6 +468,7 @@ certain functionality. @li @c vcl.emf - EMF/EMF+ processing @li @c vcl.eventtesting @li @c vcl.filter +@li @c vcl.filter.webp @li @c vcl.fonts - font-specific code @li @c vcl.fonts.detail @li @c vcl.gdi - the GDI part of VCL, devices, bitmaps, etc. diff --git a/include/svl/inettype.hxx b/include/svl/inettype.hxx index 9bea57d26da0..806c5a3e4383 100644 --- a/include/svl/inettype.hxx +++ b/include/svl/inettype.hxx @@ -82,6 +82,7 @@ #define CONTENT_TYPE_STR_IMAGE_PNG "image/png" #define CONTENT_TYPE_STR_IMAGE_TIFF "image/tiff" #define CONTENT_TYPE_STR_IMAGE_BMP "image/x-MS-bmp" +#define CONTENT_TYPE_STR_IMAGE_WEBP "image/webp" #define CONTENT_TYPE_STR_INET_MSG_RFC822 "message/rfc822" #define CONTENT_TYPE_STR_INET_MULTI_ALTERNATIVE "multipart/alternative" #define CONTENT_TYPE_STR_INET_MULTI_DIGEST "multipart/digest" @@ -149,6 +150,7 @@ enum INetContentType CONTENT_TYPE_IMAGE_PNG, CONTENT_TYPE_IMAGE_TIFF, CONTENT_TYPE_IMAGE_BMP, + CONTENT_TYPE_IMAGE_WEBP, CONTENT_TYPE_TEXT_HTML, CONTENT_TYPE_TEXT_PLAIN, CONTENT_TYPE_TEXT_URL, diff --git a/include/svtools/imagemgr.hxx b/include/svtools/imagemgr.hxx index 4abd02168ead..bd08e3696b0f 100644 --- a/include/svtools/imagemgr.hxx +++ b/include/svtools/imagemgr.hxx @@ -37,6 +37,7 @@ enum class SvImageId { GIF = START + 61, HTML = START + 63, JPG = START + 64, + WEBP = START + 65, Math = START + 68, MathTemplate = START + 69, File = START + 74, diff --git a/include/svx/strings.hrc b/include/svx/strings.hrc index 95e9690b0b9e..2dc1b255c9c0 100644 --- a/include/svx/strings.hrc +++ b/include/svx/strings.hrc @@ -1380,6 +1380,7 @@ #define STR_IMAGE_PCT NC_("STR_IMAGE_PCT", "PCT image") #define STR_IMAGE_SVG NC_("STR_IMAGE_SVG", "SVG image") #define STR_IMAGE_BMP NC_("STR_IMAGE_BMP", "BMP image") +#define STR_IMAGE_WEBP NC_("STR_IMAGE_WEBP", "WebP image") #define STR_IMAGE_UNKNOWN NC_("STR_IMAGE_UNKNOWN", "Unknown") #define STR_SWITCH NC_("STR_SWITCH", "Switch") diff --git a/include/vcl/gfxlink.hxx b/include/vcl/gfxlink.hxx index 72352f6902a1..029e211639b5 100644 --- a/include/vcl/gfxlink.hxx +++ b/include/vcl/gfxlink.hxx @@ -46,12 +46,13 @@ enum class GfxLinkType NativeSvg = 9, NativeMov = 10, NativeBmp = 11, - NativePdf = 12, // If a new type is added, make sure to change NativeLast too + NativePdf = 12, + NativeWebp = 13, // If a new type is added, make sure to change NativeLast too // Alias for when the first native type starts and last native // type ends. NativeFirst = NativeGif, - NativeLast = NativePdf, + NativeLast = NativeWebp, }; class Graphic; diff --git a/include/vcl/graphicfilter.hxx b/include/vcl/graphicfilter.hxx index bd108a4f49b9..f2ac2c352597 100644 --- a/include/vcl/graphicfilter.hxx +++ b/include/vcl/graphicfilter.hxx @@ -78,6 +78,8 @@ namespace o3tl #define IMP_XPM "SVIXPM" #define IMP_SVG "SVISVG" #define IMP_PDF "SVIPDF" +#define IMP_WEBP "SVIWEBP" + #define EXP_BMP "SVBMP" #define EXP_SVMETAFILE "SVMETAFILE" #define EXP_WMF "SVWMF" @@ -86,6 +88,7 @@ namespace o3tl #define EXP_SVG "SVESVG" #define EXP_PDF "SVEPDF" #define EXP_PNG "SVEPNG" +#define EXP_WEBP "SVEWEBP" #define BMP_SHORTNAME u"BMP" #define GIF_SHORTNAME u"GIF" @@ -99,6 +102,7 @@ namespace o3tl #define EMF_SHORTNAME u"EMF" #define SVG_SHORTNAME u"SVG" #define PDF_SHORTNAME u"PDF" +#define WEBP_SHORTNAME u"WEBP" // Info class for all supported file formats @@ -121,6 +125,7 @@ enum class GraphicFileFormat TGA = 0x000e, PSD = 0x000f, EPS = 0x0010, + WEBP = 0x0011, DXF = 0x00f1, MET = 0x00f2, PCT = 0x00f3, @@ -168,6 +173,7 @@ class VCL_DLLPUBLIC GraphicDescriptor final bool ImpDetectTGA( SvStream& rStm, bool bExtendedInfo ); bool ImpDetectPSD( SvStream& rStm, bool bExtendedInfo ); bool ImpDetectEPS( SvStream& rStm, bool bExtendedInfo ); + bool ImpDetectWEBP( SvStream& rStm, bool bExtendedInfo ); bool ImpDetectDXF( SvStream& rStm, bool bExtendedInfo ); bool ImpDetectMET( SvStream& rStm, bool bExtendedInfo ); bool ImpDetectPCT( SvStream& rStm, bool bExtendedInfo ); diff --git a/include/vcl/salctype.hxx b/include/vcl/salctype.hxx index 409fc5a79993..71f256b1986e 100644 --- a/include/vcl/salctype.hxx +++ b/include/vcl/salctype.hxx @@ -37,7 +37,8 @@ enum class ConvertDataFormat TIF, WMF, EMF, - SVG + SVG, + WEBP }; class SvStream; diff --git a/readlicense_oo/license/license.xml b/readlicense_oo/license/license.xml index eb02fd8588cb..5ebc1f0f3f97 100644 --- a/readlicense_oo/license/license.xml +++ b/readlicense_oo/license/license.xml @@ -1141,6 +1141,37 @@ glennrp at users.sourceforge.net<br /> February 3, 2011 </p> </div> + <div class="LIBWEBP"> + <h2>libwebp</h2> + <p>The following software may be included in this product: libwebp. Use of any of this software is governed by + the terms of the license below:</p> + <p>Copyright (c) 2010, Google Inc. All rights reserved.</p> + <p>Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met:</p> + <ol> + <li>Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer.</li> + <li>Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution.</li> + <li>Neither the name of Google nor the names of its contributors may + be used to endorse or promote products derived from this software + without specific prior written permission.</li> + </ol> + <p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</p> + </div> <div class="PAGEMAKER"> <h2>libpagemaker</h2> <p>The following software may be included in this product: libpagemaker. Use of any of this software is governed diff --git a/scp2/source/draw/registryitem_draw.scp b/scp2/source/draw/registryitem_draw.scp index 93cadcaa1ca5..79440c00653b 100644 --- a/scp2/source/draw/registryitem_draw.scp +++ b/scp2/source/draw/registryitem_draw.scp @@ -1092,6 +1092,7 @@ CONDITIONAL_REGISTER_DOC_EXTENSION( Tiff, gid_Module_Prg_Draw_Other_Reg, tiff, CONDITIONAL_REGISTER_DOC_EXTENSION( Xbm, gid_Module_Prg_Draw_Other_Reg, xbm, XBM, X_BITMAP, 5, sdraw.exe, open, Draw ) CONDITIONAL_REGISTER_DOC_EXTENSION( Xpm, gid_Module_Prg_Draw_Other_Reg, xpm, XPM, X_PIXMAP, 5, sdraw.exe, open, Draw ) CONDITIONAL_REGISTER_DOC_EXTENSION( PCD, gid_Module_Prg_Draw_Other_Reg, pcd, PCD, KODAK_PHOTO_CD_IMAGE, 5, sdraw.exe, open, Draw ) +CONDITIONAL_REGISTER_DOC_EXTENSION( Webp, gid_Module_Prg_Draw_Other_Reg, webp, WEBP, WEBP, 5, sdraw.exe, open, Draw ) // registering ms-visio URI scheme handler CONDITIONAL_REGISTER_URI_HANDLER( ms-visio, ms_visio, gid_Module_Prg_Draw_MSO_Reg, SELECT_VISIO ) diff --git a/solenv/sanitizers/ui/svt.suppr b/solenv/sanitizers/ui/svt.suppr index 2ee563213663..be0b9107e616 100644 --- a/solenv/sanitizers/ui/svt.suppr +++ b/solenv/sanitizers/ui/svt.suppr @@ -1,6 +1,6 @@ svtools/uiconfig/ui/checkboxcontrol.ui://GtkCheckButton[@id='checkbox'] button-no-label svtools/uiconfig/ui/editcontrol.ui://GtkEntry[@id='entry'] no-labelled-by -svtools/uiconfig/ui/graphicexport.ui://GtkScale[@id='compressionjpgsb'] no-labelled-by +svtools/uiconfig/ui/graphicexport.ui://GtkScale[@id='compressionjpgwebpsb'] no-labelled-by svtools/uiconfig/ui/graphicexport.ui://GtkScale[@id='compressionpngsb'] no-labelled-by svtools/uiconfig/ui/graphicexport.ui://GtkLabel[@id='estsizeft'] orphan-label svtools/uiconfig/ui/placeedit.ui://GtkButton[@id='repositoriesRefresh'] button-no-label diff --git a/svtools/inc/bitmaps.hlst b/svtools/inc/bitmaps.hlst index 35332e05ede0..c9c5bd88dc50 100644 --- a/svtools/inc/bitmaps.hlst +++ b/svtools/inc/bitmaps.hlst @@ -39,6 +39,7 @@ #define BMP_MET_SC "res/sx03218.png" #define BMP_PNG_SC "res/sx03219.png" #define BMP_SVM_SC "res/sx03222.png" +#define BMP_WEBP_SC "res/sx03223.png" #define BMP_GLOBAL_DOC_SC "res/sx03226.png" #define BMP_DRAW_SC "res/sx03227.png" #define BMP_DRAWTEMPLATE_SC "res/sx03228.png" @@ -85,6 +86,7 @@ #define BMP_MET_LC "res/lx03218.png" #define BMP_PNG_LC "res/lx03219.png" #define BMP_SVM_LC "res/lx03222.png" +#define BMP_WEBP_LC "res/lx03223.png" #define BMP_GLOBAL_DOC_LC "res/lx03226.png" #define BMP_DRAW_LC "res/lx03227.png" #define BMP_DRAWTEMPLATE_LC "res/lx03228.png" diff --git a/svtools/source/filter/exportdialog.cxx b/svtools/source/filter/exportdialog.cxx index 43f7cedcba7b..b8b1d092b4c2 100644 --- a/svtools/source/filter/exportdialog.cxx +++ b/svtools/source/filter/exportdialog.cxx @@ -56,6 +56,7 @@ #define FORMAT_EMF 13 #define FORMAT_EPS 14 #define FORMAT_SVG 16 +#define FORMAT_WEBP 17 #define UNIT_DEFAULT -1 #define UNIT_INCH 0 @@ -88,6 +89,8 @@ static sal_Int16 GetFilterFormat(const OUString& rExt) nFormat = FORMAT_EPS; else if ( rExt == "SVG" ) nFormat = FORMAT_SVG; + else if ( rExt == u"WEBP" ) + nFormat = FORMAT_WEBP; return nFormat; } @@ -292,6 +295,15 @@ uno::Sequence< beans::PropertyValue > ExportDialog::GetFilterData( bool bUpdateC pFilterOptions->WriteInt32("CompressionMode", nCheck); } break; + + case FORMAT_WEBP : + { + assert(mpSbCompression); + pFilterOptions->WriteInt32("Quality", static_cast<sal_Int32>(mpSbCompression->get_value())); + pFilterOptions->WriteBool("Lossless", mxCbLossless->get_active()); + } + break; + } uno::Sequence< beans::PropertyValue > aRet( pFilterOptions->GetFilterData() ); @@ -584,12 +596,13 @@ ExportDialog::ExportDialog(FltCallDialogParameter& rPara, , mxLbResolution(m_xBuilder->weld_combo_box("resolutionlb")) , mxColorDepth(m_xBuilder->weld_widget("colordepth")) , mxLbColorDepth(m_xBuilder->weld_combo_box("colordepthlb")) - , mxJPGQuality(m_xBuilder->weld_widget("jpgquality")) + , mxJPGWEBPQuality(m_xBuilder->weld_widget("jpgwebpquality")) , mxPNGCompression(m_xBuilder->weld_widget("pngcompression")) , mxSbPngCompression(m_xBuilder->weld_scale("compressionpngsb")) , mxNfPngCompression(m_xBuilder->weld_spin_button("compressionpngnf")) - , mxSbJpgCompression(m_xBuilder->weld_scale("compressionjpgsb")) - , mxNfJpgCompression(m_xBuilder->weld_spin_button("compressionjpgnf")) + , mxSbJpgWebpCompression(m_xBuilder->weld_scale("compressionjpgwebpsb")) + , mxNfJpgWebpCompression(m_xBuilder->weld_spin_button("compressionjpgwebpnf")) + , mxCbLossless(m_xBuilder->weld_check_button("losslesscb")) , mxMode(m_xBuilder->weld_widget("mode")) , mxCbInterlaced(m_xBuilder->weld_check_button("interlacedcb")) , mxBMPCompression(m_xBuilder->weld_widget("bmpcompression")) @@ -681,6 +694,8 @@ ExportDialog::ExportDialog(FltCallDialogParameter& rPara, mxCbInterlaced->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) ); + mxCbLossless->connect_toggled( LINK( this, ExportDialog, UpdateHdlLossless ) ); + mxCbSaveTransparency->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) ); mxCbEPSPreviewTIFF->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) ); @@ -758,15 +773,16 @@ void ExportDialog::createFilterOptions() mxColorDepth->show(); // Quality - mxJPGQuality->show(); + mxJPGWEBPQuality->show(); sal_Int32 nQuality = mpFilterOptionsItem->ReadInt32("Quality", 75); if ((nQuality < 1 ) || (nQuality > 100)) nQuality = 75; - mpSbCompression = mxSbJpgCompression.get(); - mpNfCompression = mxNfJpgCompression.get(); + mpSbCompression = mxSbJpgWebpCompression.get(); + mpNfCompression = mxNfJpgWebpCompression.get(); mpSbCompression->set_range(1, 100); mpNfCompression->set_range(1, 100); mpNfCompression->set_value(nQuality); + mxCbLossless->hide(); // only for WebP } break; case FORMAT_PNG : @@ -849,6 +865,24 @@ void ExportDialog::createFilterOptions() mxRbEPSCompressionNone->set_active( nCompr != 1 ); } break; + case FORMAT_WEBP : + { + // Quality + mxJPGWEBPQuality->show(); + sal_Int32 nQuality = mpFilterOptionsItem->ReadInt32("Quality", 75); + if ((nQuality < 1 ) || (nQuality > 100)) + nQuality = 75; + mpSbCompression = mxSbJpgWebpCompression.get(); + mpNfCompression = mxNfJpgWebpCompression.get(); + mpSbCompression->set_range(1, 100); + mpNfCompression->set_range(1, 100); + mpNfCompression->set_value(nQuality); + + // Lossless + mxCbLossless->set_active(mpFilterOptionsItem->ReadBool("Lossless", true)); + UpdateHdlLossless(*mxCbLossless); + } + break; } } @@ -992,6 +1026,13 @@ IMPL_LINK_NOARG(ExportDialog, UpdateHdl, weld::ToggleButton&, void) updateControls(); } +IMPL_LINK_NOARG(ExportDialog, UpdateHdlLossless, weld::ToggleButton&, void) +{ + mpSbCompression->set_sensitive(!mxCbLossless->get_active()); + mpNfCompression->set_sensitive(!mxCbLossless->get_active()); + updateControls(); +} + IMPL_LINK_NOARG(ExportDialog, UpdateHdlMtfSizeX, weld::SpinButton&, void) { double fRatio = static_cast< double >( maOriginalSize.Height ) / maOriginalSize.Width; diff --git a/svtools/source/filter/exportdialog.hxx b/svtools/source/filter/exportdialog.hxx index 137279ee6464..b77ea8e46408 100644 --- a/svtools/source/filter/exportdialog.hxx +++ b/svtools/source/filter/exportdialog.hxx @@ -104,14 +104,16 @@ private: std::unique_ptr<weld::Widget> mxColorDepth; std::unique_ptr<weld::ComboBox> mxLbColorDepth; - std::unique_ptr<weld::Widget> mxJPGQuality; + std::unique_ptr<weld::Widget> mxJPGWEBPQuality; std::unique_ptr<weld::Widget> mxPNGCompression; std::unique_ptr<weld::Scale> mxSbPngCompression; std::unique_ptr<weld::SpinButton> mxNfPngCompression; - std::unique_ptr<weld::Scale> mxSbJpgCompression; - std::unique_ptr<weld::SpinButton> mxNfJpgCompression; + std::unique_ptr<weld::Scale> mxSbJpgWebpCompression; + std::unique_ptr<weld::SpinButton> mxNfJpgWebpCompression; + + std::unique_ptr<weld::CheckButton> mxCbLossless; std::unique_ptr<weld::Widget> mxMode; std::unique_ptr<weld::CheckButton> mxCbInterlaced; @@ -148,6 +150,7 @@ private: DECL_LINK(UpdateHdlMtfSizeY, weld::SpinButton&, void); DECL_LINK(UpdateHdlNfResolution, weld::SpinButton&, void); DECL_LINK(SbCompressionUpdateHdl, weld::Scale&, void); + DECL_LINK(UpdateHdlLossless, weld::ToggleButton&, void); DECL_LINK(OK, weld::Button&, void); diff --git a/svtools/source/misc/imagemgr.cxx b/svtools/source/misc/imagemgr.cxx index 2a3932ac86a5..5d4fb28533d6 100644 --- a/svtools/source/misc/imagemgr.cxx +++ b/svtools/source/misc/imagemgr.cxx @@ -152,6 +152,7 @@ SvtExtensionResIdMapping_Impl const ExtensionMap_Impl[] = { "url", false, STR_DESCRIPTION_LINK, SvImageId::NONE }, { "vor", false, STR_DESCRIPTION_SOFFICE_TEMPLATE_DOC, SvImageId::WriterTemplate }, { "vxd", true, STR_DESCRIPTION_SYSFILE, SvImageId::NONE }, + { "webp", true, STR_DESCRIPTION_GRAPHIC_DOC, SvImageId::WEBP }, { "wmf", true, STR_DESCRIPTION_GRAPHIC_DOC, SvImageId::WMF }, { "xls", false, STR_DESCRIPTION_EXCEL_DOC, SvImageId::Calc }, { "xlt", false, STR_DESCRIPTION_EXCEL_TEMPLATE_DOC, SvImageId::CalcTemplate }, @@ -549,6 +550,8 @@ static OUString GetImageNameFromList_Impl( SvImageId nImageId, vcl::ImageType eI return BMP_TEXTFILE_LC; case SvImageId::TIFF: return BMP_TIFF_LC; + case SvImageId::WEBP: + return BMP_WEBP_LC; case SvImageId::WMF: return BMP_WMF_LC; case SvImageId::Writer: @@ -648,6 +651,8 @@ static OUString GetImageNameFromList_Impl( SvImageId nImageId, vcl::ImageType eI return BMP_TEXTFILE_SC; case SvImageId::TIFF: return BMP_TIFF_SC; + case SvImageId::WEBP: + return BMP_WEBP_SC; case SvImageId::WMF: return BMP_WMF_SC; case SvImageId::Writer: diff --git a/svtools/uiconfig/ui/graphicexport.ui b/svtools/uiconfig/ui/graphicexport.ui index 0df6dc97015c..9debb4f15fbe 100644 --- a/svtools/uiconfig/ui/graphicexport.ui +++ b/svtools/uiconfig/ui/graphicexport.ui @@ -335,7 +335,7 @@ </packing> </child> <child> - <object class="GtkFrame" id="jpgquality"> + <object class="GtkFrame" id="jpgwebpquality"> <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> @@ -352,7 +352,28 @@ <property name="can_focus">False</property> <property name="column_spacing">6</property> <child> - <object class="GtkSpinButton" id="compressionjpgnf"> + <object class="GtkCheckButton" id="losslesscb"> + <property name="label" translatable="yes" context="graphicexport|rlecb">Lossless</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> + <property name="xalign">0</property> + <property name="active">True</property> + <property name="draw_indicator">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="losslesscb-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="graphicexport|extended_tip|losslesscb">Lossless images do not lose quality but result in larger files.</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="compressionjpgwebpnf"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="activates_default">True</property> @@ -361,17 +382,17 @@ <property name="truncate-multiline">True</property> <child internal-child="accessible"> <object class="AtkObject" id="compressionjpgnf-atkobject"> - <property name="AtkObject::accessible-description" translatable="yes" context="graphicexport|extended_tip|compressionjpgnf">Sets the quality for the export. Choose from a low quality with minimal file size, up to a high quality and big file size</property> + <property name="AtkObject::accessible-description" translatable="yes" context="graphicexport|extended_tip|compressionjpgwebpnf">Sets the quality for the export. Choose from a low quality with minimal file size, up to a high quality and big file size</property> </object> </child> </object> <packing> <property name="left_attach">1</property> - <property name="top_attach">0</property> + <property name="top_attach">1</property> </packing> </child> <child> - <object class="GtkScale" id="compressionjpgsb"> + <object class="GtkScale" id="compressionjpgwebpsb"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="valign">center</property> @@ -381,7 +402,7 @@ </object> <packing> <property name="left_attach">0</property> - <property name="top_attach">0</property> + <property name="top_attach">1</property> </packing> </child> </object> diff --git a/svx/source/core/graphichelper.cxx b/svx/source/core/graphichelper.cxx index fb483c5bfe54..160f8147f76c 100644 --- a/svx/source/core/graphichelper.cxx +++ b/svx/source/core/graphichelper.cxx @@ -117,6 +117,9 @@ void GraphicHelper::GetPreferredExtension( OUString& rExtension, const Graphic& case GfxLinkType::NativePdf: aExtension = "pdf"; break; + case GfxLinkType::NativeWebp: + aExtension = "webp"; + break; default: break; } diff --git a/svx/source/gallery2/galtheme.cxx b/svx/source/gallery2/galtheme.cxx index 2319328dc8f9..0926af01188c 100644 --- a/svx/source/gallery2/galtheme.cxx +++ b/svx/source/gallery2/galtheme.cxx @@ -420,6 +420,7 @@ bool GalleryTheme::InsertGraphic(const Graphic& rGraphic, sal_uInt32 nInsertPos) case GfxLinkType::NativeMet: nExportFormat = ConvertDataFormat::MET; break; case GfxLinkType::NativePct: nExportFormat = ConvertDataFormat::PCT; break; case GfxLinkType::NativeSvg: nExportFormat = ConvertDataFormat::SVG; break; + case GfxLinkType::NativeWebp: nExportFormat = ConvertDataFormat::WEBP; break; default: break; } diff --git a/svx/source/xml/xmlgrhlp.cxx b/svx/source/xml/xmlgrhlp.cxx index b9082b6325c2..d75510054149 100644 --- a/svx/source/xml/xmlgrhlp.cxx +++ b/svx/source/xml/xmlgrhlp.cxx @@ -669,6 +669,7 @@ OUString SvXMLGraphicHelper::implSaveGraphic(css::uno::Reference<css::graphic::X } break; case GfxLinkType::NativePdf: aExtension = ".pdf"; break; + case GfxLinkType::NativeWebp: aExtension = ".webp"; break; default: aExtension = ".grf"; diff --git a/svx/source/xoutdev/_xoutbmp.cxx b/svx/source/xoutdev/_xoutbmp.cxx index 1d0c23e92780..df195d08eaf0 100644 --- a/svx/source/xoutdev/_xoutbmp.cxx +++ b/svx/source/xoutdev/_xoutbmp.cxx @@ -34,6 +34,7 @@ #define FORMAT_GIF u"gif" #define FORMAT_JPG u"jpg" #define FORMAT_PNG u"png" +#define FORMAT_WEBP u"webp" using namespace com::sun::star; @@ -179,6 +180,7 @@ ErrCode XOutBitmap::WriteGraphic( const Graphic& rGraphic, OUString& rFileName, case GfxLinkType::NativeJpg: aExt = FORMAT_JPG; break; case GfxLinkType::NativePng: aExt = FORMAT_PNG; break; + case GfxLinkType::NativeWebp: aExt = FORMAT_WEBP; break; default: break; diff --git a/vcl/CppunitTest_vcl_filters_test.mk b/vcl/CppunitTest_vcl_filters_test.mk index 03a423233c9e..435a7fd04027 100644 --- a/vcl/CppunitTest_vcl_filters_test.mk +++ b/vcl/CppunitTest_vcl_filters_test.mk @@ -11,6 +11,12 @@ $(eval $(call gb_CppunitTest_CppunitTest,vcl_filters_test)) $(eval $(call gb_CppunitTest_add_exception_objects,vcl_filters_test, \ vcl/qa/cppunit/graphicfilter/filters-test \ + vcl/qa/cppunit/graphicfilter/filters-webp-test \ +)) + +$(eval $(call gb_CppunitTest_set_include,vcl_filters_test,\ + $$(INCLUDE) \ + -I$(SRCDIR)/vcl/inc \ )) ifeq ($(DISABLE_CVE_TESTS),TRUE) diff --git a/vcl/Executable_webpfuzzer.mk b/vcl/Executable_webpfuzzer.mk new file mode 100644 index 000000000000..3851fbe52cd1 --- /dev/null +++ b/vcl/Executable_webpfuzzer.mk @@ -0,0 +1,45 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +include $(SRCDIR)/vcl/commonfuzzer.mk + +$(eval $(call gb_Executable_Executable,webpfuzzer)) + +$(eval $(call gb_Executable_use_api,webpfuzzer,\ + offapi \ + udkapi \ +)) + +$(eval $(call gb_Executable_use_externals,webpfuzzer,\ + $(fuzzer_externals) \ +)) + +$(eval $(call gb_Executable_set_include,webpfuzzer,\ + $$(INCLUDE) \ + -I$(SRCDIR)/vcl/inc \ +)) + +$(eval $(call gb_Executable_use_libraries,webpfuzzer,\ + $(fuzzer_core_libraries) \ +)) + +$(eval $(call gb_Executable_use_static_libraries,webpfuzzer,\ + $(fuzzer_statics) \ +)) + +$(eval $(call gb_Executable_add_exception_objects,webpfuzzer,\ + vcl/workben/webpfuzzer \ +)) + +$(eval $(call gb_Executable_add_libs,webpfuzzer,\ + $(LIB_FUZZING_ENGINE) \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index c661063e9641..6d8924994972 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -104,6 +104,7 @@ $(eval $(call gb_Library_use_externals,vcl,\ icu_headers \ icuuc \ lcms2 \ + libwebp \ mdds_headers \ $(if $(filter SKIA,$(BUILD_TYPE)),skia) \ )) @@ -443,6 +444,8 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/filter/png/PngImageReader \ vcl/source/filter/png/pngread \ vcl/source/filter/png/pngwrite \ + vcl/source/filter/webp/reader \ + vcl/source/filter/webp/writer \ vcl/source/font/Feature \ vcl/source/font/FeatureCollector \ vcl/source/font/FeatureParser \ diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk index f2b4058d876c..db49fba8e7ef 100644 --- a/vcl/Module_vcl.mk +++ b/vcl/Module_vcl.mk @@ -181,6 +181,7 @@ $(eval $(call gb_Module_add_targets,vcl,\ Executable_mtpfuzzer \ Executable_htmlfuzzer \ Executable_sftfuzzer \ + Executable_webpfuzzer \ )) endif diff --git a/vcl/inc/filter/WebpReader.hxx b/vcl/inc/filter/WebpReader.hxx new file mode 100644 index 000000000000..fd8cc4894a26 --- /dev/null +++ b/vcl/inc/filter/WebpReader.hxx @@ -0,0 +1,28 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <vcl/graph.hxx> + +VCL_DLLPUBLIC bool ImportWebpGraphic(SvStream& rStream, Graphic& rGraphic); + +bool ReadWebpInfo(SvStream& rStream, Size& pixelSize, sal_uInt16& bitsPerPixel, bool& hasAlpha); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/filter/WebpWriter.hxx b/vcl/inc/filter/WebpWriter.hxx new file mode 100644 index 000000000000..d3b6431c63ff --- /dev/null +++ b/vcl/inc/filter/WebpWriter.hxx @@ -0,0 +1,29 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <tools/stream.hxx> +#include <vcl/graph.hxx> +#include <vcl/FilterConfigItem.hxx> + +VCL_DLLPUBLIC bool ExportWebpGraphic(SvStream& rStream, const Graphic& rGraphic, + FilterConfigItem* pFilterConfigItem); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/graphic/GraphicFormatDetector.hxx b/vcl/inc/graphic/GraphicFormatDetector.hxx index e914ee64a3ca..3222fb712a4f 100644 --- a/vcl/inc/graphic/GraphicFormatDetector.hxx +++ b/vcl/inc/graphic/GraphicFormatDetector.hxx @@ -68,6 +68,7 @@ public: bool checkTGA(); bool checkMOV(); bool checkPDF(); + bool checkWEBP(); }; } diff --git a/vcl/inc/graphic/UnoGraphicDescriptor.hxx b/vcl/inc/graphic/UnoGraphicDescriptor.hxx index ad46952ce925..125a1f8b1d2b 100644 --- a/vcl/inc/graphic/UnoGraphicDescriptor.hxx +++ b/vcl/inc/graphic/UnoGraphicDescriptor.hxx @@ -51,6 +51,7 @@ #define MIMETYPE_EMF "image/x-emf" #define MIMETYPE_SVG "image/svg+xml" #define MIMETYPE_PDF "application/pdf" +#define MIMETYPE_WEBP "image/webp" #define MIMETYPE_VCLGRAPHIC "image/x-vclgraphic" namespace comphelper { class PropertySetInfo; } diff --git a/vcl/qa/cppunit/GraphicDescriptorTest.cxx b/vcl/qa/cppunit/GraphicDescriptorTest.cxx index cb6c6d25d80a..9bbe10a5cea7 100644 --- a/vcl/qa/cppunit/GraphicDescriptorTest.cxx +++ b/vcl/qa/cppunit/GraphicDescriptorTest.cxx @@ -33,12 +33,14 @@ class GraphicDescriptorTest : public test::BootstrapFixtureBase void testDetectJPG(); void testDetectGIF(); void testDetectBMP(); + void testDetectWEBP(); CPPUNIT_TEST_SUITE(GraphicDescriptorTest); CPPUNIT_TEST(testDetectPNG); CPPUNIT_TEST(testDetectJPG); CPPUNIT_TEST(testDetectGIF); CPPUNIT_TEST(testDetectBMP); + CPPUNIT_TEST(testDetectWEBP); CPPUNIT_TEST_SUITE_END(); }; @@ -122,6 +124,20 @@ void GraphicDescriptorTest::testDetectBMP() CPPUNIT_ASSERT_EQUAL(MapUnit::MapMM, aGraphic.GetPrefMapMode().GetMapUnit()); } +void GraphicDescriptorTest::testDetectWEBP() +{ + SvMemoryStream aStream; + createBitmapAndExportForType(aStream, u"webp"); + + GraphicDescriptor aDescriptor(aStream, nullptr); + aDescriptor.Detect(true); + + CPPUNIT_ASSERT_EQUAL(GraphicFileFormat::WEBP, aDescriptor.GetFileFormat()); + + CPPUNIT_ASSERT_EQUAL(tools::Long(100), aDescriptor.GetSizePixel().Width()); + CPPUNIT_ASSERT_EQUAL(tools::Long(100), aDescriptor.GetSizePixel().Height()); +} + } // namespace CPPUNIT_TEST_SUITE_REGISTRATION(GraphicDescriptorTest); diff --git a/vcl/qa/cppunit/GraphicFormatDetectorTest.cxx b/vcl/qa/cppunit/GraphicFormatDetectorTest.cxx index 1ce516bf52b3..5f13b7d8d68e 100644 --- a/vcl/qa/cppunit/GraphicFormatDetectorTest.cxx +++ b/vcl/qa/cppunit/GraphicFormatDetectorTest.cxx @@ -43,6 +43,7 @@ class GraphicFormatDetectorTest : public test::BootstrapFixtureBase void testDetectSVGZ(); void testDetectPDF(); void testDetectEPS(); + void testDetectWEBP(); void testMatchArray(); void testCheckArrayForMatchingStrings(); @@ -63,6 +64,7 @@ class GraphicFormatDetectorTest : public test::BootstrapFixtureBase CPPUNIT_TEST(testDetectSVGZ); CPPUNIT_TEST(testDetectPDF); CPPUNIT_TEST(testDetectEPS); + CPPUNIT_TEST(testDetectWEBP); CPPUNIT_TEST(testMatchArray); CPPUNIT_TEST(testCheckArrayForMatchingStrings); CPPUNIT_TEST_SUITE_END(); @@ -308,6 +310,21 @@ void GraphicFormatDetectorTest::testDetectEPS() CPPUNIT_ASSERT_EQUAL(OUString("EPS"), rFormatExtension); } +void GraphicFormatDetectorTest::testDetectWEBP() +{ + SvFileStream aFileStream(getFullUrl(u"TypeDetectionExample.webp"), StreamMode::READ); + vcl::GraphicFormatDetector aDetector(aFileStream, "WEBP"); + + CPPUNIT_ASSERT(aDetector.detect()); + CPPUNIT_ASSERT(aDetector.checkWEBP()); + + aFileStream.Seek(aDetector.mnStreamPosition); + + OUString rFormatExtension; + CPPUNIT_ASSERT(ImpPeekGraphicFormat(aFileStream, rFormatExtension, false)); + CPPUNIT_ASSERT_EQUAL(OUString("WEBP"), rFormatExtension); +} + void GraphicFormatDetectorTest::testMatchArray() { std::string aString("<?xml version=\"1.0\" standalone=\"no\"?>\n" diff --git a/vcl/qa/cppunit/GraphicTest.cxx b/vcl/qa/cppunit/GraphicTest.cxx index 50ff4a133f86..dadb8e2be8d1 100644 --- a/vcl/qa/cppunit/GraphicTest.cxx +++ b/vcl/qa/cppunit/GraphicTest.cxx @@ -220,7 +220,7 @@ void GraphicTest::testUnloadedGraphic() void GraphicTest::testUnloadedGraphicLoading() { - const OUString aFormats[] = { "png", "gif", "jpg" }; + const OUString aFormats[] = { "png", "gif", "jpg", "webp" }; for (OUString const& sFormat : aFormats) { diff --git a/vcl/qa/cppunit/data/TypeDetectionExample.webp b/vcl/qa/cppunit/data/TypeDetectionExample.webp new file mode 100644 index 000000000000..e85ae121637b Binary files /dev/null and b/vcl/qa/cppunit/data/TypeDetectionExample.webp differ diff --git a/vcl/qa/cppunit/graphicfilter/data/webp/alpha_lossless.webp b/vcl/qa/cppunit/graphicfilter/data/webp/alpha_lossless.webp new file mode 100644 index 000000000000..abb67cc5f4b6 Binary files /dev/null and b/vcl/qa/cppunit/graphicfilter/data/webp/alpha_lossless.webp differ diff --git a/vcl/qa/cppunit/graphicfilter/data/webp/alpha_lossy.webp b/vcl/qa/cppunit/graphicfilter/data/webp/alpha_lossy.webp new file mode 100644 index 000000000000..c587b1bb22c0 Binary files /dev/null and b/vcl/qa/cppunit/graphicfilter/data/webp/alpha_lossy.webp differ diff --git a/vcl/qa/cppunit/graphicfilter/data/webp/fail/.gitignore b/vcl/qa/cppunit/graphicfilter/data/webp/fail/.gitignore new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/vcl/qa/cppunit/graphicfilter/data/webp/indeterminate/.gitignore b/vcl/qa/cppunit/graphicfilter/data/webp/indeterminate/.gitignore new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/vcl/qa/cppunit/graphicfilter/data/webp/noalpha_lossless.webp b/vcl/qa/cppunit/graphicfilter/data/webp/noalpha_lossless.webp new file mode 100644 index 000000000000..b22ebc3b28bb Binary files /dev/null and b/vcl/qa/cppunit/graphicfilter/data/webp/noalpha_lossless.webp differ diff --git a/vcl/qa/cppunit/graphicfilter/data/webp/noalpha_lossy.webp b/vcl/qa/cppunit/graphicfilter/data/webp/noalpha_lossy.webp new file mode 100644 index 000000000000..c118febb0e9a Binary files /dev/null and b/vcl/qa/cppunit/graphicfilter/data/webp/noalpha_lossy.webp differ diff --git a/vcl/qa/cppunit/graphicfilter/data/webp/pass/.gitignore b/vcl/qa/cppunit/graphicfilter/data/webp/pass/.gitignore new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/vcl/qa/cppunit/graphicfilter/filters-test.cxx b/vcl/qa/cppunit/graphicfilter/filters-test.cxx index fe7485e3944a..168ca916f641 100644 --- a/vcl/qa/cppunit/graphicfilter/filters-test.cxx +++ b/vcl/qa/cppunit/graphicfilter/filters-test.cxx @@ -144,6 +144,8 @@ void VclFiltersTest::testExportImport() checkExportImport(u"png"); fprintf(stderr, "Check ExportImport BMP\n"); checkExportImport(u"bmp"); + fprintf(stderr, "Check ExportImport WEBP\n"); + checkExportImport(u"webp"); } void VclFiltersTest::testCVEs() diff --git a/vcl/qa/cppunit/graphicfilter/filters-webp-test.cxx b/vcl/qa/cppunit/graphicfilter/filters-webp-test.cxx new file mode 100644 index 000000000000..8e404a686218 --- /dev/null +++ b/vcl/qa/cppunit/graphicfilter/filters-webp-test.cxx @@ -0,0 +1,203 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <unotest/filters-test.hxx> +#include <test/bootstrapfixture.hxx> +#include <vcl/FilterConfigItem.hxx> +#include <bitmapwriteaccess.hxx> +#include <tools/stream.hxx> +#include <vcl/graph.hxx> +#include <vcl/graphicfilter.hxx> +#include <graphic/GraphicFormatDetector.hxx> +#include <filter/WebpReader.hxx> +#include <comphelper/propertyvalue.hxx> + +using namespace css; + +/* Implementation of Filters test */ + +class WebpFilterTest : public test::FiltersTest, public test::BootstrapFixture +{ +public: + WebpFilterTest() + : BootstrapFixture(true, false) + { + } + + virtual bool load(const OUString&, const OUString& rURL, const OUString&, SfxFilterFlags, + SotClipboardFormatId, unsigned int) override; + + /** + * Ensure CVEs remain unbroken + */ + void testCVEs(); + + void testRoundtripLossless(); + void testRoundtripLossy(); + void testReadAlphaLossless(); + void testReadAlphaLossy(); + void testReadNoAlphaLossless(); + void testReadNoAlphaLossy(); + + CPPUNIT_TEST_SUITE(WebpFilterTest); + CPPUNIT_TEST(testCVEs); + CPPUNIT_TEST(testRoundtripLossless); + CPPUNIT_TEST(testRoundtripLossy); + CPPUNIT_TEST(testReadAlphaLossless); + CPPUNIT_TEST(testReadAlphaLossy); + CPPUNIT_TEST(testReadNoAlphaLossless); + CPPUNIT_TEST(testReadNoAlphaLossy); + CPPUNIT_TEST_SUITE_END(); + +private: + void testRoundtrip(bool lossy); + void testRead(bool lossy, bool alpha); +}; + +bool WebpFilterTest::load(const OUString&, const OUString& rURL, const OUString&, SfxFilterFlags, + SotClipboardFormatId, unsigned int) +{ + SvFileStream aFileStream(rURL, StreamMode::READ); + Graphic aGraphic; + return ImportWebpGraphic(aFileStream, aGraphic); +} + +void WebpFilterTest::testCVEs() +{ +#ifndef DISABLE_CVE_TESTS + testDir(OUString(), m_directories.getURLFromSrc(u"/vcl/qa/cppunit/graphicfilter/data/webp/")); +#endif +} + +void WebpFilterTest::testRoundtripLossless() { testRoundtrip(false); } + +void WebpFilterTest::testRoundtripLossy() { testRoundtrip(true); } + +void WebpFilterTest::testRoundtrip(bool lossy) +{ + // Do not use just 2x2, lossy saving would change colors. + Bitmap aBitmap(Size(20, 20), 24); + AlphaMask aAlpha(Size(20, 20)); + { + BitmapScopedWriteAccess pAccess(aBitmap); + pAccess->SetFillColor(COL_WHITE); + pAccess->FillRect(tools::Rectangle(Point(0, 0), Size(10, 10))); + pAccess->SetFillColor(COL_BLACK); + pAccess->FillRect(tools::Rectangle(Point(10, 0), Size(10, 10))); + pAccess->SetFillColor(COL_LIGHTRED); + pAccess->FillRect(tools::Rectangle(Point(0, 10), Size(10, 10))); + pAccess->SetFillColor(COL_BLUE); + pAccess->FillRect(tools::Rectangle(Point(10, 10), Size(10, 10))); + AlphaScopedWriteAccess pAccessAlpha(aAlpha); + pAccessAlpha->SetFillColor(BitmapColor(0)); // opaque + pAccessAlpha->FillRect(tools::Rectangle(Point(0, 0), Size(10, 10))); + pAccessAlpha->FillRect(tools::Rectangle(Point(10, 0), Size(10, 10))); + pAccessAlpha->FillRect(tools::Rectangle(Point(0, 10), Size(10, 10))); + pAccessAlpha->SetFillColor(BitmapColor(64, 64, 64)); + pAccessAlpha->FillRect(tools::Rectangle(Point(10, 10), Size(10, 10))); + } + BitmapEx aBitmapEx(aBitmap, aAlpha); + + SvMemoryStream aStream; + GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); + sal_uInt16 nFilterFormat = rFilter.GetExportFormatNumberForShortName(u"webp"); + css::uno::Sequence<css::beans::PropertyValue> aFilterData{ + comphelper::makePropertyValue("Lossless", !lossy), + comphelper::makePropertyValue("Quality", sal_Int32(100)) + }; + rFilter.ExportGraphic(Graphic(aBitmapEx), "none", aStream, nFilterFormat, &aFilterData); + aStream.Seek(STREAM_SEEK_TO_BEGIN); + + Graphic aGraphic; + ErrCode bResult = rFilter.ImportGraphic(aGraphic, "none", aStream); + CPPUNIT_ASSERT_EQUAL(ERRCODE_NONE, bResult); + CPPUNIT_ASSERT_EQUAL(GfxLinkType::NativeWebp, aGraphic.GetGfxLink().GetType()); + BitmapEx aResultBitmap = aGraphic.GetBitmapEx(); + CPPUNIT_ASSERT_EQUAL(Size(20, 20), aResultBitmap.GetSizePixel()); + CPPUNIT_ASSERT(aResultBitmap.IsAlpha()); + + { + Bitmap tmpBitmap = aResultBitmap.GetBitmap(); + Bitmap::ScopedReadAccess pAccess(tmpBitmap); + // Note that x,y are swapped. + CPPUNIT_ASSERT_EQUAL(COL_WHITE, Color(pAccess->GetPixel(0, 0))); + CPPUNIT_ASSERT_EQUAL(COL_BLACK, Color(pAccess->GetPixel(0, 19))); + if (lossy) + { + CPPUNIT_ASSERT_LESS(sal_uInt16(3), + pAccess->GetPixel(19, 0).GetColorError(COL_LIGHTRED)); + CPPUNIT_ASSERT_LESS(sal_uInt16(3), pAccess->GetPixel(19, 19).GetColorError(COL_BLUE)); + } + else + { + CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, Color(pAccess->GetPixel(19, 0))); + CPPUNIT_ASSERT_EQUAL(COL_BLUE, Color(pAccess->GetPixel(19, 19))); + } + AlphaMask tmpAlpha = aResultBitmap.GetAlpha(); + AlphaMask::ScopedReadAccess pAccessAlpha(tmpAlpha); + CPPUNIT_ASSERT_EQUAL(sal_uInt8(0), pAccessAlpha->GetPixelIndex(0, 0)); + CPPUNIT_ASSERT_EQUAL(sal_uInt8(0), pAccessAlpha->GetPixelIndex(0, 19)); + CPPUNIT_ASSERT_EQUAL(sal_uInt8(0), pAccessAlpha->GetPixelIndex(19, 0)); + CPPUNIT_ASSERT_EQUAL(sal_uInt8(64), pAccessAlpha->GetPixelIndex(19, 19)); + } + + aStream.Seek(STREAM_SEEK_TO_BEGIN); + vcl::GraphicFormatDetector aDetector(aStream, ""); + + CPPUNIT_ASSERT_EQUAL(true, aDetector.detect()); + CPPUNIT_ASSERT_EQUAL(true, aDetector.checkWEBP()); + CPPUNIT_ASSERT_EQUAL(OUString(u"WEBP"), aDetector.msDetectedFormat); +} + +void WebpFilterTest::testReadAlphaLossless() { testRead(false, true); } + +void WebpFilterTest::testReadAlphaLossy() { testRead(true, true); } + +void WebpFilterTest::testReadNoAlphaLossless() { testRead(false, false); } + +void WebpFilterTest::testReadNoAlphaLossy() { testRead(true, false); } + +void WebpFilterTest::testRead(bool lossy, bool alpha) +{ + // Read a file created in GIMP and check it's read correctly. + OUString file = m_directories.getURLFromSrc(u"/vcl/qa/cppunit/graphicfilter/data/webp/") + + (alpha ? u"alpha" : u"noalpha") + "_" + (lossy ? u"lossy" : u"lossless") + + ".webp"; + SvFileStream aFileStream(file, StreamMode::READ); + Graphic aGraphic; + GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); + ErrCode bResult = rFilter.ImportGraphic(aGraphic, "none", aFileStream); + CPPUNIT_ASSERT_EQUAL(ERRCODE_NONE, bResult); + CPPUNIT_ASSERT_EQUAL(GfxLinkType::NativeWebp, aGraphic.GetGfxLink().GetType()); + BitmapEx aResultBitmap = aGraphic.GetBitmapEx(); + CPPUNIT_ASSERT_EQUAL(Size(10, 10), aResultBitmap.GetSizePixel()); + CPPUNIT_ASSERT_EQUAL(alpha, aResultBitmap.IsAlpha()); + + { + Bitmap tmpBitmap = aResultBitmap.GetBitmap(); + Bitmap::ScopedReadAccess pAccess(tmpBitmap); + // Note that x,y are swapped. + if (lossy) + CPPUNIT_ASSERT_LESS(sal_uInt16(2), pAccess->GetPixel(0, 0).GetColorError(COL_LIGHTRED)); + else + CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, Color(pAccess->GetPixel(0, 0))); + CPPUNIT_ASSERT_EQUAL(COL_LIGHTBLUE, Color(pAccess->GetPixel(9, 9))); + if (alpha) + { + AlphaMask tmpAlpha = aResultBitmap.GetAlpha(); + AlphaMask::ScopedReadAccess pAccessAlpha(tmpAlpha); + CPPUNIT_ASSERT_EQUAL(sal_uInt8(0), pAccessAlpha->GetPixelIndex(0, 0)); + CPPUNIT_ASSERT_EQUAL(sal_uInt8(255), pAccessAlpha->GetPixelIndex(0, 9)); + } + } +} + +CPPUNIT_TEST_SUITE_REGISTRATION(WebpFilterTest); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/filter/FilterConfigCache.cxx b/vcl/source/filter/FilterConfigCache.cxx index 478756ff17f0..acd3086e5a5d 100644 --- a/vcl/source/filter/FilterConfigCache.cxx +++ b/vcl/source/filter/FilterConfigCache.cxx @@ -41,8 +41,8 @@ using namespace ::com::sun::star::configuration ; const char* FilterConfigCache::FilterConfigCacheEntry::InternalPixelFilterNameList[] = { - IMP_BMP, IMP_GIF, IMP_PNG,IMP_JPEG, IMP_XBM, IMP_XPM, - EXP_BMP, EXP_JPEG, EXP_PNG, IMP_MOV, nullptr + IMP_BMP, IMP_GIF, IMP_PNG,IMP_JPEG, IMP_XBM, IMP_XPM, IMP_WEBP, + EXP_BMP, EXP_JPEG, EXP_PNG, IMP_MOV, EXP_WEBP, nullptr }; const char* FilterConfigCache::FilterConfigCacheEntry::InternalVectorFilterNameList[] = @@ -255,6 +255,8 @@ const char* FilterConfigCache::InternalFilterListForSvxLight[] = "xpm","2","exp", "svg","1","SVISVG", "svg","2","SVESVG", + "webp","1","SVIWEBP", + "webp","2","SVEWEBP", nullptr }; diff --git a/vcl/source/filter/GraphicFormatDetector.cxx b/vcl/source/filter/GraphicFormatDetector.cxx index 56f7a9f2d006..162125f3fe97 100644 --- a/vcl/source/filter/GraphicFormatDetector.cxx +++ b/vcl/source/filter/GraphicFormatDetector.cxx @@ -28,6 +28,7 @@ namespace vcl { + namespace { bool isPCT(SvStream& rStream, sal_uLong nStreamPos, sal_uLong nStreamLen) @@ -545,6 +546,18 @@ bool GraphicFormatDetector::checkPDF() return false; } +bool GraphicFormatDetector::checkWEBP() +{ + if (maFirstBytes[0] == 'R' && maFirstBytes[1] == 'I' && maFirstBytes[2] == 'F' + && maFirstBytes[3] == 'F' && maFirstBytes[8] == 'W' && maFirstBytes[9] == 'E' + && maFirstBytes[10] == 'B' && maFirstBytes[11] == 'P') + { + msDetectedFormat = "WEBP"; + return true; + } + return false; +} + } // vcl namespace /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx index 4a606d7d1ebb..f57475eda91c 100644 --- a/vcl/source/filter/graphicfilter.cxx +++ b/vcl/source/filter/graphicfilter.cxx @@ -47,6 +47,8 @@ #include "jpeg/jpeg.hxx" #include "ixbm/xbmread.hxx" #include "ixpm/xpmread.hxx" +#include <filter/WebpReader.hxx> +#include <filter/WebpWriter.hxx> #include <osl/module.hxx> #include <com/sun/star/uno/Reference.h> #include <com/sun/star/awt/Size.hpp> @@ -65,6 +67,7 @@ #include <vector> #include <memory> #include <string_view> +#include <o3tl/string_view.hxx> #include "FilterConfigCache.hxx" #include "graphicfilter_internal.hxx" @@ -74,6 +77,41 @@ #define PMGCHUNG_msOG 0x6d734f47 // Microsoft Office Animated GIF +// Support for GfxLinkType::NativeWebp is so far disabled, +// as enabling it would write .webp images e.g. to .odt documents, +// making those images unreadable for older readers. So for now +// disable the support so that .webp images will be written out as .png, +// and somewhen later enable the support unconditionally. + +namespace +{ +template <typename charT, typename traits = std::char_traits<charT>> +constexpr bool starts_with(std::basic_string_view<charT, traits> sv, + std::basic_string_view<charT, traits> x) noexcept +{ + return sv.substr(0, x.size()) == x; +} +template <typename charT, typename traits = std::char_traits<charT>> +constexpr bool starts_with(std::basic_string_view<charT, traits> sv, charT const* x) +{ + return starts_with(sv, std::basic_string_view<charT, traits>(x)); +} + +} + +static bool supportNativeWebp() +{ + const char* const testname = getenv("LO_TESTNAME"); + if(testname == nullptr) + return false; + // Enable support only for those unittests that test it. + if( std::string_view("_anonymous_namespace___GraphicTest__testUnloadedGraphicLoading_") == testname + || std::string_view("VclFiltersTest__testExportImport_") == testname + || starts_with(std::string_view(testname), "WebpFilterTest__")) + return true; + return false; +} + typedef ::std::vector< GraphicFilter* > FilterList_impl; static FilterList_impl* pFilterHdlList = nullptr; @@ -444,6 +482,16 @@ bool ImpPeekGraphicFormat( SvStream& rStream, OUString& rFormatExtension, bool b } } + if (!bTest || rFormatExtension.startsWith("WEBP")) + { + bSomethingTested = true; + if (aDetector.checkWEBP()) + { + rFormatExtension = aDetector.msDetectedFormat; + return true; + } + } + return bTest && !bSomethingTested; } @@ -1325,6 +1373,13 @@ Graphic GraphicFilter::ImportUnloadedGraphic(SvStream& rIStream, sal_uInt64 size { eLinkType = GfxLinkType::NativePdf; } + else if (aFilterName.equalsIgnoreAsciiCase(IMP_WEBP)) + { + if(supportNativeWebp()) + eLinkType = GfxLinkType::NativeWebp; + else + nStatus = ERRCODE_GRFILTER_FILTERERROR; + } else { nStatus = ERRCODE_GRFILTER_FILTERERROR; @@ -1726,6 +1781,16 @@ ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, else nStatus = ERRCODE_GRFILTER_FILTERERROR; } + else if (aFilterName.equalsIgnoreAsciiCase(IMP_WEBP)) + { + if (ImportWebpGraphic(rIStream, rGraphic)) + { + if(supportNativeWebp()) + eLinkType = GfxLinkType::NativeWebp; + } + else + nStatus = ERRCODE_GRFILTER_FILTERERROR; + } else nStatus = ERRCODE_GRFILTER_FILTERERROR; } @@ -2150,6 +2215,14 @@ ErrCode GraphicFilter::ExportGraphic( const Graphic& rGraphic, const OUString& r } } } + else if (aFilterName.equalsIgnoreAsciiCase(EXP_WEBP)) + { + if (!ExportWebpGraphic(rOStm, aGraphic, &aConfigItem)) + nStatus = ERRCODE_GRFILTER_FORMATERROR; + + if( rOStm.GetError() ) + nStatus = ERRCODE_GRFILTER_IOERROR; + } else nStatus = ERRCODE_GRFILTER_FILTERERROR; } @@ -2230,6 +2303,7 @@ IMPL_LINK( GraphicFilter, FilterCallback, ConvertData&, rData, bool ) case ConvertDataFormat::WMF: aShortName = WMF_SHORTNAME; break; case ConvertDataFormat::EMF: aShortName = EMF_SHORTNAME; break; case ConvertDataFormat::SVG: aShortName = SVG_SHORTNAME; break; + case ConvertDataFormat::WEBP: aShortName = WEBP_SHORTNAME; break; default: break; diff --git a/vcl/source/filter/graphicfilter2.cxx b/vcl/source/filter/graphicfilter2.cxx index ebebf829a33f..dd13e8123340 100644 --- a/vcl/source/filter/graphicfilter2.cxx +++ b/vcl/source/filter/graphicfilter2.cxx @@ -25,6 +25,7 @@ #include <vcl/outdev.hxx> #include <vcl/graphicfilter.hxx> #include <unotools/ucbstreamhelper.hxx> +#include <filter/WebpReader.hxx> #include "graphicfilter_internal.hxx" #define DATA_SIZE 640 @@ -87,6 +88,7 @@ bool GraphicDescriptor::Detect( bool bExtendedInfo ) else if ( ImpDetectPSD( rStm, bExtendedInfo ) ) bRet = true; else if ( ImpDetectEPS( rStm, bExtendedInfo ) ) bRet = true; else if ( ImpDetectPCD( rStm, bExtendedInfo ) ) bRet = true; + else if ( ImpDetectWEBP( rStm, bExtendedInfo ) ) bRet = true; rStm.SetEndian( nOldFormat ); } @@ -1143,6 +1145,36 @@ bool GraphicDescriptor::ImpDetectSVG( SvStream& /*rStm*/, bool /*bExtendedInfo*/ return bRet; } +bool GraphicDescriptor::ImpDetectWEBP( SvStream& rStm, bool bExtendedInfo ) +{ + sal_uInt32 nTemp32 = 0; + bool bRet = false; + + sal_Int32 nStmPos = rStm.Tell(); + rStm.SetEndian( SvStreamEndian::BIG ); + rStm.ReadUInt32( nTemp32 ); + + if ( nTemp32 == 0x52494646 ) + { + rStm.ReadUInt32( nTemp32 ); // skip + rStm.ReadUInt32( nTemp32 ); + if ( nTemp32 == 0x57454250 ) + { + nFormat = GraphicFileFormat::WEBP; + bRet = true; + + if ( bExtendedInfo ) + { + rStm.Seek(nStmPos); + ReadWebpInfo(rStm, aPixSize, nBitsPerPixel, bIsAlpha ); + bIsTransparent = bIsAlpha; + } + } + } + rStm.Seek( nStmPos ); + return bRet; +} + OUString GraphicDescriptor::GetImportFormatShortName( GraphicFileFormat nFormat ) { const char *pKeyName = nullptr; @@ -1172,6 +1204,7 @@ OUString GraphicDescriptor::GetImportFormatShortName( GraphicFileFormat nFormat case GraphicFileFormat::WMF : pKeyName = "wmf"; break; case GraphicFileFormat::EMF : pKeyName = "emf"; break; case GraphicFileFormat::SVG : pKeyName = "svg"; break; + case GraphicFileFormat::WEBP : pKeyName = "webp"; break; default: assert(false); } diff --git a/vcl/source/filter/webp/reader.cxx b/vcl/source/filter/webp/reader.cxx new file mode 100644 index 000000000000..90a9278e16dc --- /dev/null +++ b/vcl/source/filter/webp/reader.cxx @@ -0,0 +1,319 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <memory> +#include <vcl/graph.hxx> +#include <tools/stream.hxx> +#include <filter/WebpReader.hxx> +#include <bitmapwriteaccess.hxx> +#include <salinst.hxx> +#include <sal/log.hxx> +#include <unotools/configmgr.hxx> +#include <svdata.hxx> + +#include <webp/decode.h> + +static bool readWebpInfo(SvStream& stream, std::vector<uint8_t>& data, + WebPBitstreamFeatures& features) +{ + for (;;) + { + // Read 4096 (more) bytes. + size_t lastSize = data.size(); + data.resize(data.size() + 4096); + sal_Size nBytesRead = stream.ReadBytes(data.data() + lastSize, 4096); + if (nBytesRead <= 0) + return false; + data.resize(lastSize + nBytesRead); + int status = WebPGetFeatures(data.data(), data.size(), &features); + if (status == VP8_STATUS_OK) + break; + if (status == VP8_STATUS_NOT_ENOUGH_DATA) + continue; // Try again with 4096 more bytes read. + return false; + } + return true; +} + +static bool readWebp(SvStream& stream, Graphic& graphic) +{ + WebPDecoderConfig config; + if (!WebPInitDecoderConfig(&config)) + { ... etc. - the rest is truncated