diff options
Diffstat (limited to 'plug-ins/file-webp')
-rw-r--r-- | plug-ins/file-webp/Makefile.am | 64 | ||||
-rw-r--r-- | plug-ins/file-webp/Makefile.in | 1028 | ||||
-rw-r--r-- | plug-ins/file-webp/file-webp-dialog.c | 403 | ||||
-rw-r--r-- | plug-ins/file-webp/file-webp-dialog.h | 33 | ||||
-rw-r--r-- | plug-ins/file-webp/file-webp-load.c | 294 | ||||
-rw-r--r-- | plug-ins/file-webp/file-webp-load.h | 31 | ||||
-rw-r--r-- | plug-ins/file-webp/file-webp-save.c | 889 | ||||
-rw-r--r-- | plug-ins/file-webp/file-webp-save.h | 54 | ||||
-rw-r--r-- | plug-ins/file-webp/file-webp.c | 320 | ||||
-rw-r--r-- | plug-ins/file-webp/file-webp.h | 32 |
10 files changed, 3148 insertions, 0 deletions
diff --git a/plug-ins/file-webp/Makefile.am b/plug-ins/file-webp/Makefile.am new file mode 100644 index 0000000..20bb79b --- /dev/null +++ b/plug-ins/file-webp/Makefile.am @@ -0,0 +1,64 @@ +## Process this file with automake to produce Makefile.in + +libgimpui = $(top_builddir)/libgimp/libgimpui-$(GIMP_API_VERSION).la +libgimpconfig = $(top_builddir)/libgimpconfig/libgimpconfig-$(GIMP_API_VERSION).la +libgimpwidgets = $(top_builddir)/libgimpwidgets/libgimpwidgets-$(GIMP_API_VERSION).la +libgimp = $(top_builddir)/libgimp/libgimp-$(GIMP_API_VERSION).la +libgimpcolor = $(top_builddir)/libgimpcolor/libgimpcolor-$(GIMP_API_VERSION).la +libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la +libgimpmath = $(top_builddir)/libgimpmath/libgimpmath-$(GIMP_API_VERSION).la + +if OS_WIN32 +mwindows = -mwindows +endif + +if HAVE_WINDRES +include $(top_srcdir)/build/windows/gimprc-plug-ins.rule +file_webp_RC = file-webp.rc.o +endif + +AM_LDFLAGS = $(mwindows) + +libexecdir = $(gimpplugindir)/plug-ins/file-webp + +AM_CPPFLAGS = \ + -I$(top_srcdir) \ + $(GTK_CFLAGS) \ + $(EXIF_CFLAGS) \ + $(GEGL_CFLAGS) \ + $(GEXIV2_CFLAGS) \ + $(WEBP_CFLAGS) \ + $(WEBPMUX_CFLAGS) \ + $(WEBPDEMUX_CFLAGS) \ + -I$(includedir) + +libexec_PROGRAMS = file-webp + +file_webp_SOURCES = \ + file-webp.c \ + file-webp.h \ + file-webp-dialog.c \ + file-webp-dialog.h \ + file-webp-load.c \ + file-webp-load.h \ + file-webp-save.c \ + file-webp-save.h + +file_webp_LDADD = \ + $(libgimpui) \ + $(libgimpwidgets) \ + $(libgimpconfig) \ + $(libgimp) \ + $(libgimpcolor) \ + $(libgimpmath) \ + $(libgimpbase) \ + $(webp_LIBS) \ + $(GTK_LIBS) \ + $(GEGL_LIBS) \ + $(GEXIV2_LIBS) \ + $(WEBP_LIBS) \ + $(WEBPMUX_LIBS) \ + $(WEBPDEMUX_LIBS) \ + $(RT_LIBS) \ + $(INTLLIBS) \ + $(file_webp_RC) diff --git a/plug-ins/file-webp/Makefile.in b/plug-ins/file-webp/Makefile.in new file mode 100644 index 0000000..d1dcbc2 --- /dev/null +++ b/plug-ins/file-webp/Makefile.in @@ -0,0 +1,1028 @@ +# Makefile.in generated by automake 1.16.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Version resources for Microsoft Windows + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +libexec_PROGRAMS = file-webp$(EXEEXT) +subdir = plug-ins/file-webp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4macros/gtk-doc.m4 \ + $(top_srcdir)/m4macros/intltool.m4 \ + $(top_srcdir)/m4macros/libtool.m4 \ + $(top_srcdir)/m4macros/ltoptions.m4 \ + $(top_srcdir)/m4macros/ltsugar.m4 \ + $(top_srcdir)/m4macros/ltversion.m4 \ + $(top_srcdir)/m4macros/lt~obsolete.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/m4macros/alsa.m4 \ + $(top_srcdir)/m4macros/ax_compare_version.m4 \ + $(top_srcdir)/m4macros/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4macros/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4macros/ax_prog_cc_for_build.m4 \ + $(top_srcdir)/m4macros/ax_prog_perl_version.m4 \ + $(top_srcdir)/m4macros/detectcflags.m4 \ + $(top_srcdir)/m4macros/pythondev.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(libexecdir)" +PROGRAMS = $(libexec_PROGRAMS) +am_file_webp_OBJECTS = file-webp.$(OBJEXT) file-webp-dialog.$(OBJEXT) \ + file-webp-load.$(OBJEXT) file-webp-save.$(OBJEXT) +file_webp_OBJECTS = $(am_file_webp_OBJECTS) +am__DEPENDENCIES_1 = +file_webp_DEPENDENCIES = $(libgimpui) $(libgimpwidgets) \ + $(libgimpconfig) $(libgimp) $(libgimpcolor) $(libgimpmath) \ + $(libgimpbase) $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) $(file_webp_RC) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/file-webp-dialog.Po \ + ./$(DEPDIR)/file-webp-load.Po ./$(DEPDIR)/file-webp-save.Po \ + ./$(DEPDIR)/file-webp.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(file_webp_SOURCES) +DIST_SOURCES = $(file_webp_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build/windows/gimprc-plug-ins.rule \ + $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +AA_LIBS = @AA_LIBS@ +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +ALL_LINGUAS = @ALL_LINGUAS@ +ALSA_CFLAGS = @ALSA_CFLAGS@ +ALSA_LIBS = @ALSA_LIBS@ +ALTIVEC_EXTRA_CFLAGS = @ALTIVEC_EXTRA_CFLAGS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPSTREAM_UTIL = @APPSTREAM_UTIL@ +AR = @AR@ +AS = @AS@ +ATK_CFLAGS = @ATK_CFLAGS@ +ATK_LIBS = @ATK_LIBS@ +ATK_REQUIRED_VERSION = @ATK_REQUIRED_VERSION@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BABL_CFLAGS = @BABL_CFLAGS@ +BABL_LIBS = @BABL_LIBS@ +BABL_REQUIRED_VERSION = @BABL_REQUIRED_VERSION@ +BUG_REPORT_URL = @BUG_REPORT_URL@ +BUILD_EXEEXT = @BUILD_EXEEXT@ +BUILD_OBJEXT = @BUILD_OBJEXT@ +BZIP2_LIBS = @BZIP2_LIBS@ +CAIRO_CFLAGS = @CAIRO_CFLAGS@ +CAIRO_LIBS = @CAIRO_LIBS@ +CAIRO_PDF_CFLAGS = @CAIRO_PDF_CFLAGS@ +CAIRO_PDF_LIBS = @CAIRO_PDF_LIBS@ +CAIRO_PDF_REQUIRED_VERSION = @CAIRO_PDF_REQUIRED_VERSION@ +CAIRO_REQUIRED_VERSION = @CAIRO_REQUIRED_VERSION@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CC_VERSION = @CC_VERSION@ +CFLAGS = @CFLAGS@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@ +CPP_FOR_BUILD = @CPP_FOR_BUILD@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DESKTOP_DATADIR = @DESKTOP_DATADIR@ +DESKTOP_FILE_VALIDATE = @DESKTOP_FILE_VALIDATE@ +DLLTOOL = @DLLTOOL@ +DOC_SHOOTER = @DOC_SHOOTER@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILE_AA = @FILE_AA@ +FILE_EXR = @FILE_EXR@ +FILE_HEIF = @FILE_HEIF@ +FILE_JP2_LOAD = @FILE_JP2_LOAD@ +FILE_MNG = @FILE_MNG@ +FILE_PDF_SAVE = @FILE_PDF_SAVE@ +FILE_PS = @FILE_PS@ +FILE_WMF = @FILE_WMF@ +FILE_XMC = @FILE_XMC@ +FILE_XPM = @FILE_XPM@ +FONTCONFIG_CFLAGS = @FONTCONFIG_CFLAGS@ +FONTCONFIG_LIBS = @FONTCONFIG_LIBS@ +FONTCONFIG_REQUIRED_VERSION = @FONTCONFIG_REQUIRED_VERSION@ +FREETYPE2_REQUIRED_VERSION = @FREETYPE2_REQUIRED_VERSION@ +FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ +FREETYPE_LIBS = @FREETYPE_LIBS@ +GDBUS_CODEGEN = @GDBUS_CODEGEN@ +GDK_PIXBUF_CFLAGS = @GDK_PIXBUF_CFLAGS@ +GDK_PIXBUF_CSOURCE = @GDK_PIXBUF_CSOURCE@ +GDK_PIXBUF_LIBS = @GDK_PIXBUF_LIBS@ +GDK_PIXBUF_REQUIRED_VERSION = @GDK_PIXBUF_REQUIRED_VERSION@ +GEGL = @GEGL@ +GEGL_CFLAGS = @GEGL_CFLAGS@ +GEGL_LIBS = @GEGL_LIBS@ +GEGL_MAJOR_MINOR_VERSION = @GEGL_MAJOR_MINOR_VERSION@ +GEGL_REQUIRED_VERSION = @GEGL_REQUIRED_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GEXIV2_CFLAGS = @GEXIV2_CFLAGS@ +GEXIV2_LIBS = @GEXIV2_LIBS@ +GEXIV2_REQUIRED_VERSION = @GEXIV2_REQUIRED_VERSION@ +GIMP_API_VERSION = @GIMP_API_VERSION@ +GIMP_APP_VERSION = @GIMP_APP_VERSION@ +GIMP_BINARY_AGE = @GIMP_BINARY_AGE@ +GIMP_COMMAND = @GIMP_COMMAND@ +GIMP_DATA_VERSION = @GIMP_DATA_VERSION@ +GIMP_FULL_NAME = @GIMP_FULL_NAME@ +GIMP_INTERFACE_AGE = @GIMP_INTERFACE_AGE@ +GIMP_MAJOR_VERSION = @GIMP_MAJOR_VERSION@ +GIMP_MICRO_VERSION = @GIMP_MICRO_VERSION@ +GIMP_MINOR_VERSION = @GIMP_MINOR_VERSION@ +GIMP_MKENUMS = @GIMP_MKENUMS@ +GIMP_MODULES = @GIMP_MODULES@ +GIMP_PACKAGE_REVISION = @GIMP_PACKAGE_REVISION@ +GIMP_PKGCONFIG_VERSION = @GIMP_PKGCONFIG_VERSION@ +GIMP_PLUGINS = @GIMP_PLUGINS@ +GIMP_PLUGIN_VERSION = @GIMP_PLUGIN_VERSION@ +GIMP_REAL_VERSION = @GIMP_REAL_VERSION@ +GIMP_SYSCONF_VERSION = @GIMP_SYSCONF_VERSION@ +GIMP_TOOL_VERSION = @GIMP_TOOL_VERSION@ +GIMP_UNSTABLE = @GIMP_UNSTABLE@ +GIMP_USER_VERSION = @GIMP_USER_VERSION@ +GIMP_VERSION = @GIMP_VERSION@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GIO_UNIX_CFLAGS = @GIO_UNIX_CFLAGS@ +GIO_UNIX_LIBS = @GIO_UNIX_LIBS@ +GIO_WINDOWS_CFLAGS = @GIO_WINDOWS_CFLAGS@ +GIO_WINDOWS_LIBS = @GIO_WINDOWS_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_COMPILE_RESOURCES = @GLIB_COMPILE_RESOURCES@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GLIB_REQUIRED_VERSION = @GLIB_REQUIRED_VERSION@ +GMODULE_NO_EXPORT_CFLAGS = @GMODULE_NO_EXPORT_CFLAGS@ +GMODULE_NO_EXPORT_LIBS = @GMODULE_NO_EXPORT_LIBS@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GOBJECT_QUERY = @GOBJECT_QUERY@ +GREP = @GREP@ +GS_LIBS = @GS_LIBS@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_LIBS = @GTK_LIBS@ +GTK_MAC_INTEGRATION_CFLAGS = @GTK_MAC_INTEGRATION_CFLAGS@ +GTK_MAC_INTEGRATION_LIBS = @GTK_MAC_INTEGRATION_LIBS@ +GTK_REQUIRED_VERSION = @GTK_REQUIRED_VERSION@ +GTK_UPDATE_ICON_CACHE = @GTK_UPDATE_ICON_CACHE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HARFBUZZ_CFLAGS = @HARFBUZZ_CFLAGS@ +HARFBUZZ_LIBS = @HARFBUZZ_LIBS@ +HARFBUZZ_REQUIRED_VERSION = @HARFBUZZ_REQUIRED_VERSION@ +HAVE_CXX14 = @HAVE_CXX14@ +HAVE_FINITE = @HAVE_FINITE@ +HAVE_ISFINITE = @HAVE_ISFINITE@ +HAVE_VFORK = @HAVE_VFORK@ +HOST_GLIB_COMPILE_RESOURCES = @HOST_GLIB_COMPILE_RESOURCES@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_REQUIRED_VERSION = @INTLTOOL_REQUIRED_VERSION@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +ISO_CODES_LOCALEDIR = @ISO_CODES_LOCALEDIR@ +ISO_CODES_LOCATION = @ISO_CODES_LOCATION@ +JPEG_LIBS = @JPEG_LIBS@ +JSON_GLIB_CFLAGS = @JSON_GLIB_CFLAGS@ +JSON_GLIB_LIBS = @JSON_GLIB_LIBS@ +LCMS_CFLAGS = @LCMS_CFLAGS@ +LCMS_LIBS = @LCMS_LIBS@ +LCMS_REQUIRED_VERSION = @LCMS_REQUIRED_VERSION@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ +LIBBACKTRACE_LIBS = @LIBBACKTRACE_LIBS@ +LIBHEIF_CFLAGS = @LIBHEIF_CFLAGS@ +LIBHEIF_LIBS = @LIBHEIF_LIBS@ +LIBHEIF_REQUIRED_VERSION = @LIBHEIF_REQUIRED_VERSION@ +LIBLZMA_REQUIRED_VERSION = @LIBLZMA_REQUIRED_VERSION@ +LIBMYPAINT_CFLAGS = @LIBMYPAINT_CFLAGS@ +LIBMYPAINT_LIBS = @LIBMYPAINT_LIBS@ +LIBMYPAINT_REQUIRED_VERSION = @LIBMYPAINT_REQUIRED_VERSION@ +LIBOBJS = @LIBOBJS@ +LIBPNG_REQUIRED_VERSION = @LIBPNG_REQUIRED_VERSION@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ +LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ +LIBUNWIND_REQUIRED_VERSION = @LIBUNWIND_REQUIRED_VERSION@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CURRENT_MINUS_AGE = @LT_CURRENT_MINUS_AGE@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +LT_VERSION_INFO = @LT_VERSION_INFO@ +LZMA_CFLAGS = @LZMA_CFLAGS@ +LZMA_LIBS = @LZMA_LIBS@ +MAIL = @MAIL@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MIME_INFO_CFLAGS = @MIME_INFO_CFLAGS@ +MIME_INFO_LIBS = @MIME_INFO_LIBS@ +MIME_TYPES = @MIME_TYPES@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MMX_EXTRA_CFLAGS = @MMX_EXTRA_CFLAGS@ +MNG_CFLAGS = @MNG_CFLAGS@ +MNG_LIBS = @MNG_LIBS@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGMERGE = @MSGMERGE@ +MYPAINT_BRUSHES_CFLAGS = @MYPAINT_BRUSHES_CFLAGS@ +MYPAINT_BRUSHES_LIBS = @MYPAINT_BRUSHES_LIBS@ +NATIVE_GLIB_CFLAGS = @NATIVE_GLIB_CFLAGS@ +NATIVE_GLIB_LIBS = @NATIVE_GLIB_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENEXR_CFLAGS = @OPENEXR_CFLAGS@ +OPENEXR_LIBS = @OPENEXR_LIBS@ +OPENEXR_REQUIRED_VERSION = @OPENEXR_REQUIRED_VERSION@ +OPENJPEG_CFLAGS = @OPENJPEG_CFLAGS@ +OPENJPEG_LIBS = @OPENJPEG_LIBS@ +OPENJPEG_REQUIRED_VERSION = @OPENJPEG_REQUIRED_VERSION@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PANGOCAIRO_CFLAGS = @PANGOCAIRO_CFLAGS@ +PANGOCAIRO_LIBS = @PANGOCAIRO_LIBS@ +PANGOCAIRO_REQUIRED_VERSION = @PANGOCAIRO_REQUIRED_VERSION@ +PATHSEP = @PATHSEP@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PERL_REQUIRED_VERSION = @PERL_REQUIRED_VERSION@ +PERL_VERSION = @PERL_VERSION@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PNG_CFLAGS = @PNG_CFLAGS@ +PNG_LIBS = @PNG_LIBS@ +POFILES = @POFILES@ +POPPLER_CFLAGS = @POPPLER_CFLAGS@ +POPPLER_DATA_CFLAGS = @POPPLER_DATA_CFLAGS@ +POPPLER_DATA_LIBS = @POPPLER_DATA_LIBS@ +POPPLER_DATA_REQUIRED_VERSION = @POPPLER_DATA_REQUIRED_VERSION@ +POPPLER_LIBS = @POPPLER_LIBS@ +POPPLER_REQUIRED_VERSION = @POPPLER_REQUIRED_VERSION@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +PYBIN_PATH = @PYBIN_PATH@ +PYCAIRO_CFLAGS = @PYCAIRO_CFLAGS@ +PYCAIRO_LIBS = @PYCAIRO_LIBS@ +PYGIMP_EXTRA_CFLAGS = @PYGIMP_EXTRA_CFLAGS@ +PYGTK_CFLAGS = @PYGTK_CFLAGS@ +PYGTK_CODEGEN = @PYGTK_CODEGEN@ +PYGTK_DEFSDIR = @PYGTK_DEFSDIR@ +PYGTK_LIBS = @PYGTK_LIBS@ +PYLINK_LIBS = @PYLINK_LIBS@ +PYTHON = @PYTHON@ +PYTHON2_REQUIRED_VERSION = @PYTHON2_REQUIRED_VERSION@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_INCLUDES = @PYTHON_INCLUDES@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +RSVG_REQUIRED_VERSION = @RSVG_REQUIRED_VERSION@ +RT_LIBS = @RT_LIBS@ +SCREENSHOT_LIBS = @SCREENSHOT_LIBS@ +SED = @SED@ +SENDMAIL = @SENDMAIL@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKET_LIBS = @SOCKET_LIBS@ +SSE2_EXTRA_CFLAGS = @SSE2_EXTRA_CFLAGS@ +SSE4_1_EXTRA_CFLAGS = @SSE4_1_EXTRA_CFLAGS@ +SSE_EXTRA_CFLAGS = @SSE_EXTRA_CFLAGS@ +STRIP = @STRIP@ +SVG_CFLAGS = @SVG_CFLAGS@ +SVG_LIBS = @SVG_LIBS@ +SYMPREFIX = @SYMPREFIX@ +TIFF_LIBS = @TIFF_LIBS@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WEBKIT_CFLAGS = @WEBKIT_CFLAGS@ +WEBKIT_LIBS = @WEBKIT_LIBS@ +WEBKIT_REQUIRED_VERSION = @WEBKIT_REQUIRED_VERSION@ +WEBPDEMUX_CFLAGS = @WEBPDEMUX_CFLAGS@ +WEBPDEMUX_LIBS = @WEBPDEMUX_LIBS@ +WEBPMUX_CFLAGS = @WEBPMUX_CFLAGS@ +WEBPMUX_LIBS = @WEBPMUX_LIBS@ +WEBP_CFLAGS = @WEBP_CFLAGS@ +WEBP_LIBS = @WEBP_LIBS@ +WEBP_REQUIRED_VERSION = @WEBP_REQUIRED_VERSION@ +WEB_PAGE = @WEB_PAGE@ +WIN32_LARGE_ADDRESS_AWARE = @WIN32_LARGE_ADDRESS_AWARE@ +WINDRES = @WINDRES@ +WMF_CFLAGS = @WMF_CFLAGS@ +WMF_CONFIG = @WMF_CONFIG@ +WMF_LIBS = @WMF_LIBS@ +WMF_REQUIRED_VERSION = @WMF_REQUIRED_VERSION@ +XDG_EMAIL = @XDG_EMAIL@ +XFIXES_CFLAGS = @XFIXES_CFLAGS@ +XFIXES_LIBS = @XFIXES_LIBS@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_REQUIRED_VERSION = @XGETTEXT_REQUIRED_VERSION@ +XMC_CFLAGS = @XMC_CFLAGS@ +XMC_LIBS = @XMC_LIBS@ +XMKMF = @XMKMF@ +XMLLINT = @XMLLINT@ +XMU_LIBS = @XMU_LIBS@ +XPM_LIBS = @XPM_LIBS@ +XSLTPROC = @XSLTPROC@ +XVFB_RUN = @XVFB_RUN@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +Z_LIBS = @Z_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CC_FOR_BUILD = @ac_ct_CC_FOR_BUILD@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gimpdatadir = @gimpdatadir@ +gimpdir = @gimpdir@ +gimplocaledir = @gimplocaledir@ +gimpplugindir = @gimpplugindir@ +gimpsysconfdir = @gimpsysconfdir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ +libdir = @libdir@ +libexecdir = $(gimpplugindir)/plug-ins/file-webp +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +manpage_gimpdir = @manpage_gimpdir@ +mkdir_p = @mkdir_p@ +ms_librarian = @ms_librarian@ +mypaint_brushes_dir = @mypaint_brushes_dir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +libgimpui = $(top_builddir)/libgimp/libgimpui-$(GIMP_API_VERSION).la +libgimpconfig = $(top_builddir)/libgimpconfig/libgimpconfig-$(GIMP_API_VERSION).la +libgimpwidgets = $(top_builddir)/libgimpwidgets/libgimpwidgets-$(GIMP_API_VERSION).la +libgimp = $(top_builddir)/libgimp/libgimp-$(GIMP_API_VERSION).la +libgimpcolor = $(top_builddir)/libgimpcolor/libgimpcolor-$(GIMP_API_VERSION).la +libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la +libgimpmath = $(top_builddir)/libgimpmath/libgimpmath-$(GIMP_API_VERSION).la +@OS_WIN32_TRUE@mwindows = -mwindows +@HAVE_WINDRES_TRUE@GIMPPLUGINRC = $(top_builddir)/build/windows/gimp-plug-ins.rc +@HAVE_WINDRES_TRUE@file_webp_RC = file-webp.rc.o +AM_LDFLAGS = $(mwindows) +AM_CPPFLAGS = \ + -I$(top_srcdir) \ + $(GTK_CFLAGS) \ + $(EXIF_CFLAGS) \ + $(GEGL_CFLAGS) \ + $(GEXIV2_CFLAGS) \ + $(WEBP_CFLAGS) \ + $(WEBPMUX_CFLAGS) \ + $(WEBPDEMUX_CFLAGS) \ + -I$(includedir) + +file_webp_SOURCES = \ + file-webp.c \ + file-webp.h \ + file-webp-dialog.c \ + file-webp-dialog.h \ + file-webp-load.c \ + file-webp-load.h \ + file-webp-save.c \ + file-webp-save.h + +file_webp_LDADD = \ + $(libgimpui) \ + $(libgimpwidgets) \ + $(libgimpconfig) \ + $(libgimp) \ + $(libgimpcolor) \ + $(libgimpmath) \ + $(libgimpbase) \ + $(webp_LIBS) \ + $(GTK_LIBS) \ + $(GEGL_LIBS) \ + $(GEXIV2_LIBS) \ + $(WEBP_LIBS) \ + $(WEBPMUX_LIBS) \ + $(WEBPDEMUX_LIBS) \ + $(RT_LIBS) \ + $(INTLLIBS) \ + $(file_webp_RC) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/build/windows/gimprc-plug-ins.rule $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu plug-ins/file-webp/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plug-ins/file-webp/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/build/windows/gimprc-plug-ins.rule $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libexecPROGRAMS: $(libexec_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libexecdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libexecdir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-libexecPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(libexecdir)" && rm -f $$files + +clean-libexecPROGRAMS: + @list='$(libexec_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +file-webp$(EXEEXT): $(file_webp_OBJECTS) $(file_webp_DEPENDENCIES) $(EXTRA_file_webp_DEPENDENCIES) + @rm -f file-webp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(file_webp_OBJECTS) $(file_webp_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file-webp-dialog.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file-webp-load.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file-webp-save.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file-webp.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(libexecdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libexecPROGRAMS clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/file-webp-dialog.Po + -rm -f ./$(DEPDIR)/file-webp-load.Po + -rm -f ./$(DEPDIR)/file-webp-save.Po + -rm -f ./$(DEPDIR)/file-webp.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libexecPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/file-webp-dialog.Po + -rm -f ./$(DEPDIR)/file-webp-load.Po + -rm -f ./$(DEPDIR)/file-webp-save.Po + -rm -f ./$(DEPDIR)/file-webp.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libexecPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libexecPROGRAMS clean-libtool \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-libexecPROGRAMS \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-libexecPROGRAMS + +.PRECIOUS: Makefile + + +# `windres` seems a very stupid tool and it breaks with double shlashes +# in parameter paths. Strengthen the rule a little. +@HAVE_WINDRES_TRUE@%.rc.o: +@HAVE_WINDRES_TRUE@ $(WINDRES) --define ORIGINALFILENAME_STR="$*$(EXEEXT)" \ +@HAVE_WINDRES_TRUE@ --define INTERNALNAME_STR="$*" \ +@HAVE_WINDRES_TRUE@ --define TOP_SRCDIR="`echo $(top_srcdir) | sed 's*//*/*'`" \ +@HAVE_WINDRES_TRUE@ -I"`echo $(top_srcdir)/app | sed 's%/\+%/%'`" \ +@HAVE_WINDRES_TRUE@ -I"`echo $(top_builddir)/app | sed 's%/\+%/%'`"\ +@HAVE_WINDRES_TRUE@ -I"`echo $(top_builddir) | sed 's%/\+%/%'`"\ +@HAVE_WINDRES_TRUE@ $(GIMPPLUGINRC) $@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/plug-ins/file-webp/file-webp-dialog.c b/plug-ins/file-webp/file-webp-dialog.c new file mode 100644 index 0000000..fb4f97f --- /dev/null +++ b/plug-ins/file-webp/file-webp-dialog.c @@ -0,0 +1,403 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * file-webp - WebP file format plug-in for the GIMP + * Copyright (C) 2015 Nathan Osman + * Copyright (C) 2016 Ben Touchette + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <libgimp/gimp.h> +#include <libgimp/gimpui.h> + +#include <webp/encode.h> + +#include "file-webp.h" +#include "file-webp-dialog.h" + +#include "libgimp/stdplugins-intl.h" + + +static void save_dialog_toggle_scale (GtkWidget *widget, + gpointer data); + +static void save_dialog_toggle_minsize (GtkWidget *widget, + gpointer data); + +static void show_maxkeyframe_hints (GtkAdjustment *adj, + GtkLabel *label); + + +static void +save_dialog_toggle_scale (GtkWidget *widget, + gpointer data) +{ + gimp_scale_entry_set_sensitive (GTK_OBJECT (data), + ! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))); +} + +static void +save_dialog_toggle_minsize (GtkWidget *widget, + gpointer data) +{ + gtk_widget_set_sensitive (GTK_WIDGET (data), + ! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))); +} + +static void +show_maxkeyframe_hints (GtkAdjustment *adj, + GtkLabel *label) +{ + gint kmax; + + kmax = (gint) gtk_adjustment_get_value (adj); + if (kmax == 0) + { + gtk_label_set_text (label, _("(no keyframes)")); + } + else if (kmax == 1) + { + gtk_label_set_text (label, _("(all frames are keyframes)")); + } + else + { + gtk_label_set_text (label, ""); + } +} + +gboolean +save_dialog (WebPSaveParams *params, + gint32 image_ID) +{ + GtkWidget *dialog; + GtkWidget *vbox; + GtkWidget *table; + GtkWidget *expander; + GtkWidget *frame; + GtkWidget *vbox2; + GtkWidget *label; + GtkWidget *toggle; + GtkWidget *toggle_minsize; + GtkWidget *combo; + GtkObject *quality_scale; + GtkObject *alpha_quality_scale; + gint32 nlayers; + gboolean animation_supported = FALSE; + gboolean run; + gchar *text; + gint row = 0; + + g_free (gimp_image_get_layers (image_ID, &nlayers)); + animation_supported = nlayers > 1; + + /* Create the dialog */ + dialog = gimp_export_dialog_new (_("WebP"), PLUG_IN_BINARY, SAVE_PROC); + + /* Create the vbox */ + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 12); + gtk_box_pack_start (GTK_BOX (gimp_export_dialog_get_content_area (dialog)), + vbox, FALSE, FALSE, 0); + gtk_widget_show (vbox); + + /* Create the table */ + table = gtk_table_new (4, 3, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); + gtk_widget_show (table); + + /* Create the lossless checkbox */ + toggle = gtk_check_button_new_with_mnemonic (_("_Lossless")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), + params->lossless); + gtk_table_attach (GTK_TABLE (table), toggle, + 0, 3, row, row + 1, + GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show (toggle); + row++; + + g_signal_connect (toggle, "toggled", + G_CALLBACK (gimp_toggle_button_update), + ¶ms->lossless); + + /* Create the slider for image quality */ + quality_scale = gimp_scale_entry_new (GTK_TABLE (table), + 0, row++, + _("Image _quality:"), + 125, + 0, + params->quality, + 0.0, 100.0, + 1.0, 10.0, + 0, TRUE, + 0.0, 0.0, + _("Image quality"), + NULL); + gimp_scale_entry_set_sensitive (quality_scale, ! params->lossless); + + g_signal_connect (quality_scale, "value-changed", + G_CALLBACK (gimp_float_adjustment_update), + ¶ms->quality); + + /* Create the slider for alpha channel quality */ + alpha_quality_scale = gimp_scale_entry_new (GTK_TABLE (table), + 0, row++, + _("Alpha q_uality:"), + 125, + 0, + params->alpha_quality, + 0.0, 100.0, + 1.0, 10.0, + 0, TRUE, + 0.0, 0.0, + _("Alpha channel quality"), + NULL); + gimp_scale_entry_set_sensitive (alpha_quality_scale, ! params->lossless); + + g_signal_connect (alpha_quality_scale, "value-changed", + G_CALLBACK (gimp_float_adjustment_update), + ¶ms->alpha_quality); + + /* Enable and disable the sliders when the lossless option is selected */ + g_signal_connect (toggle, "toggled", + G_CALLBACK (save_dialog_toggle_scale), + quality_scale); + g_signal_connect (toggle, "toggled", + G_CALLBACK (save_dialog_toggle_scale), + alpha_quality_scale); + + /* Create the combobox containing the presets */ + combo = gimp_int_combo_box_new ("Default", WEBP_PRESET_DEFAULT, + "Picture", WEBP_PRESET_PICTURE, + "Photo", WEBP_PRESET_PHOTO, + "Drawing", WEBP_PRESET_DRAWING, + "Icon", WEBP_PRESET_ICON, + "Text", WEBP_PRESET_TEXT, + NULL); + label = gimp_table_attach_aligned (GTK_TABLE (table), 0, row++, + _("Source _type:"), 0.0, 0.5, + combo, 2, FALSE); + gimp_help_set_help_data (label, + _("WebP encoder \"preset\""), + NULL); + + gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo), + params->preset, + G_CALLBACK (gimp_int_combo_box_get_active), + ¶ms->preset); + + if (animation_supported) + { + GtkWidget *animation_box; + GtkAdjustment *adj; + GtkWidget *delay; + GtkWidget *hbox; + GtkWidget *label_kf; + GtkAdjustment *adj_kf; + GtkWidget *kf_distance; + GtkWidget *hbox_kf; + PangoAttrList *attrs; + PangoAttribute *attr; + + vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4); + gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0); + gtk_widget_show (vbox2); + + text = g_strdup_printf ("<b>%s</b>", _("_Advanced Options")); + expander = gtk_expander_new_with_mnemonic (text); + gtk_expander_set_use_markup (GTK_EXPANDER (expander), TRUE); + g_free (text); + + + /* Create the top-level animation checkbox expander */ + text = g_strdup_printf ("<b>%s</b>", _("As A_nimation")); + toggle = gtk_check_button_new_with_mnemonic (text); + g_free (text); + + gtk_label_set_use_markup (GTK_LABEL (gtk_bin_get_child (GTK_BIN (toggle))), + TRUE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), + params->animation); + gtk_box_pack_start (GTK_BOX (vbox2), toggle, TRUE, TRUE, 0); + gtk_widget_show (toggle); + + g_signal_connect (toggle, "toggled", + G_CALLBACK (gimp_toggle_button_update), + ¶ms->animation); + + frame = gimp_frame_new ("<expander>"); + gtk_box_pack_start (GTK_BOX (vbox2), frame, TRUE, TRUE, 0); + gtk_widget_show (frame); + + g_object_bind_property (toggle, "active", + frame, "visible", + G_BINDING_SYNC_CREATE); + + /* animation options box */ + animation_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_container_add (GTK_CONTAINER (frame), animation_box); + gtk_widget_show (animation_box); + + /* loop animation checkbox */ + toggle = gtk_check_button_new_with_mnemonic (_("Loop _forever")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), params->loop); + gtk_box_pack_start (GTK_BOX (animation_box), toggle, + FALSE, FALSE, 0); + gtk_widget_show (toggle); + + g_signal_connect (toggle, "toggled", + G_CALLBACK (gimp_toggle_button_update), + ¶ms->loop); + + /* create a hbox for 'max key-frame distance */ + hbox_kf = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_box_pack_start (GTK_BOX (animation_box), hbox_kf, FALSE, FALSE, 0); + gtk_widget_set_sensitive (hbox_kf, TRUE); + gtk_widget_show (hbox_kf); + + /* label for 'max key-frame distance' adjustment */ + label_kf = gtk_label_new (_("Max distance between key-frames:")); + gtk_label_set_xalign (GTK_LABEL (label_kf), 0.2); + gtk_box_pack_start (GTK_BOX (hbox_kf), label_kf, FALSE, FALSE, 0); + gtk_widget_show (label_kf); + + /* key-frame distance entry */ + adj_kf = (GtkAdjustment *) gtk_adjustment_new (params->kf_distance, + 0.0, 10000.0, + 1.0, 10.0, 0.0); + kf_distance = gimp_spin_button_new (adj_kf, 1, 0); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (kf_distance), TRUE); + gtk_box_pack_start (GTK_BOX (hbox_kf), kf_distance, FALSE, FALSE, 0); + gtk_widget_show (kf_distance); + + g_signal_connect (adj_kf, "value-changed", + G_CALLBACK (gimp_int_adjustment_update), + ¶ms->kf_distance); + + /* Add some hinting text for special values of key-frame distance. */ + label_kf = gtk_label_new (NULL); + gtk_box_pack_start (GTK_BOX (hbox_kf), label_kf, FALSE, FALSE, 0); + gtk_widget_show (label_kf); + + attrs = pango_attr_list_new (); + attr = pango_attr_style_new (PANGO_STYLE_ITALIC); + pango_attr_list_insert (attrs, attr); + gtk_label_set_attributes (GTK_LABEL (label_kf), attrs); + pango_attr_list_unref (attrs); + + g_signal_connect (adj_kf, "value-changed", + G_CALLBACK (show_maxkeyframe_hints), + label_kf); + show_maxkeyframe_hints (adj_kf, GTK_LABEL (label_kf)); + + /* minimize-size checkbox */ + toggle_minsize = gtk_check_button_new_with_mnemonic (_("_Minimize output size (slower)")); + + gtk_box_pack_start (GTK_BOX (animation_box), toggle_minsize, + FALSE, FALSE, 0); + gtk_widget_show (toggle_minsize); + + g_signal_connect (toggle_minsize, "toggled", + G_CALLBACK (gimp_toggle_button_update), + ¶ms->minimize_size); + + + /* Enable and disable the kf-distance box when the 'minimize size' option is selected */ + g_signal_connect (toggle_minsize, "toggled", + G_CALLBACK (save_dialog_toggle_minsize), + hbox_kf); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_minsize), params->minimize_size); + + /* create a hbox for delay */ + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_box_pack_start (GTK_BOX (animation_box), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + /* label for 'delay' adjustment */ + label = gtk_label_new (_("Delay between frames where unspecified:")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + + /* default delay */ + adj = (GtkAdjustment *) gtk_adjustment_new (params->delay, + 1, 10000, 1, 10, 0); + delay = gimp_spin_button_new (adj, 1, 0); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (delay), TRUE); + gtk_box_pack_start (GTK_BOX (hbox), delay, FALSE, FALSE, 0); + gtk_widget_show (delay); + + g_signal_connect (adj, "value-changed", + G_CALLBACK (gimp_int_adjustment_update), + ¶ms->delay); + + /* label for 'ms' adjustment */ + label = gtk_label_new (_("milliseconds")); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + + /* Create the force-delay checkbox */ + toggle = gtk_check_button_new_with_mnemonic (_("Use _delay entered above for all frames")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), + params->force_delay); + gtk_box_pack_start (GTK_BOX (animation_box), toggle, FALSE, FALSE, 0); + gtk_widget_show (toggle); + + g_signal_connect (toggle, "toggled", + G_CALLBACK (gimp_toggle_button_update), + ¶ms->force_delay); + } + + /* Save EXIF data */ + toggle = gtk_check_button_new_with_mnemonic (_("_Save Exif data")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), params->exif); + gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0); + gtk_widget_show (toggle); + + g_signal_connect (toggle, "toggled", + G_CALLBACK (gimp_toggle_button_update), + ¶ms->exif); + + /* XMP metadata */ + toggle = gtk_check_button_new_with_mnemonic (_("Save _XMP data")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), params->xmp); + gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0); + gtk_widget_show (toggle); + + g_signal_connect (toggle, "toggled", + G_CALLBACK (gimp_toggle_button_update), + ¶ms->xmp); + + /* Color profile */ + toggle = gtk_check_button_new_with_mnemonic (_("Save color _profile")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), params->profile); + gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0); + gtk_widget_show (toggle); + + g_signal_connect (toggle, "toggled", + G_CALLBACK (gimp_toggle_button_update), + ¶ms->profile); + + gtk_widget_show (dialog); + + run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK); + + gtk_widget_destroy (dialog); + + return run; +} diff --git a/plug-ins/file-webp/file-webp-dialog.h b/plug-ins/file-webp/file-webp-dialog.h new file mode 100644 index 0000000..b5c85ad --- /dev/null +++ b/plug-ins/file-webp/file-webp-dialog.h @@ -0,0 +1,33 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * file-webp - WebP file format plug-in for the GIMP + * Copyright (C) 2015 Nathan Osman + * Copyright (C) 2016 Ben Touchette + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#ifndef __WEBP_DIALOG_H__ +#define __WEBP_DIALOG_H__ + + +#include "file-webp-save.h" + + +gboolean save_dialog (WebPSaveParams *params, + gint32 image_ID); + + +#endif /* __WEBP_DIALOG_H__ */ diff --git a/plug-ins/file-webp/file-webp-load.c b/plug-ins/file-webp/file-webp-load.c new file mode 100644 index 0000000..1f49784 --- /dev/null +++ b/plug-ins/file-webp/file-webp-load.c @@ -0,0 +1,294 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * file-webp - WebP file format plug-in for the GIMP + * Copyright (C) 2015 Nathan Osman + * Copyright (C) 2016 Ben Touchette + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +#include <webp/decode.h> +#include <webp/demux.h> +#include <webp/mux.h> + +#include <gegl.h> + +#include <libgimp/gimp.h> +#include <libgimp/gimpui.h> + +#include "file-webp-load.h" + +#include "libgimp/stdplugins-intl.h" + + +static void +create_layer (gint32 image_ID, + uint8_t *layer_data, + gint32 position, + gchar *name, + gint width, + gint height) +{ + gint32 layer_ID; + GeglBuffer *buffer; + GeglRectangle extent; + + layer_ID = gimp_layer_new (image_ID, name, + width, height, + GIMP_RGBA_IMAGE, + 100, + gimp_image_get_default_new_layer_mode (image_ID)); + + gimp_image_insert_layer (image_ID, layer_ID, -1, position); + + /* Retrieve the buffer for the layer */ + buffer = gimp_drawable_get_buffer (layer_ID); + + /* Copy the image data to the region */ + gegl_rectangle_set (&extent, 0, 0, width, height); + gegl_buffer_set (buffer, &extent, 0, NULL, layer_data, + GEGL_AUTO_ROWSTRIDE); + + /* Flush the drawable and detach */ + gegl_buffer_flush (buffer); + g_object_unref (buffer); +} + +gint32 +load_image (const gchar *filename, + gboolean interactive, + GError **error) +{ + uint8_t *indata = NULL; + gsize indatalen; + gint width; + gint height; + gint32 image_ID; + WebPMux *mux; + WebPData wp_data; + GimpColorProfile *profile = NULL; + uint32_t flags; + gboolean animation = FALSE; + gboolean icc = FALSE; + gboolean exif = FALSE; + gboolean xmp = FALSE; + + /* Attempt to read the file contents from disk */ + if (! g_file_get_contents (filename, + (gchar **) &indata, + &indatalen, + error)) + { + return -1; + } + + /* Validate WebP data */ + if (! WebPGetInfo (indata, indatalen, &width, &height)) + { + g_set_error (error, G_FILE_ERROR, 0, + _("Invalid WebP file '%s'"), + gimp_filename_to_utf8 (filename)); + return -1; + } + + wp_data.bytes = indata; + wp_data.size = indatalen; + + mux = WebPMuxCreate (&wp_data, 1); + if (! mux) + return -1; + + WebPMuxGetFeatures (mux, &flags); + + if (flags & ANIMATION_FLAG) + animation = TRUE; + + if (flags & ICCP_FLAG) + icc = TRUE; + + if (flags & EXIF_FLAG) + exif = TRUE; + + if (flags & XMP_FLAG) + xmp = TRUE; + + /* TODO: decode the image in "chunks" or "tiles" */ + /* TODO: check if an alpha channel is present */ + + /* Create the new image and associated layer */ + image_ID = gimp_image_new (width, height, GIMP_RGB); + + if (icc) + { + WebPData icc_profile; + + WebPMuxGetChunk (mux, "ICCP", &icc_profile); + profile = gimp_color_profile_new_from_icc_profile (icc_profile.bytes, + icc_profile.size, NULL); + if (profile) + gimp_image_set_color_profile (image_ID, profile); + } + + if (! animation) + { + uint8_t *outdata; + + /* Attempt to decode the data as a WebP image */ + outdata = WebPDecodeRGBA (indata, indatalen, &width, &height); + + /* Check to ensure the image data was loaded correctly */ + if (! outdata) + { + WebPMuxDelete (mux); + return -1; + } + + create_layer (image_ID, outdata, 0, _("Background"), + width, height); + + /* Free the image data */ + free (outdata); + } + else + { + WebPAnimDecoder *dec = NULL; + WebPAnimInfo anim_info; + WebPAnimDecoderOptions dec_options; + gint frame_num = 1; + WebPDemuxer *demux = NULL; + WebPIterator iter = { 0, }; + + if (! WebPAnimDecoderOptionsInit (&dec_options)) + { + error: + if (dec) + WebPAnimDecoderDelete (dec); + + if (demux) + { + WebPDemuxReleaseIterator (&iter); + WebPDemuxDelete (demux); + } + + WebPMuxDelete (mux); + return -1; + } + + /* dec_options.color_mode is MODE_RGBA by default here */ + dec = WebPAnimDecoderNew (&wp_data, &dec_options); + if (! dec) + { + g_set_error (error, G_FILE_ERROR, 0, + _("Failed to decode animated WebP file '%s'"), + gimp_filename_to_utf8 (filename)); + goto error; + } + + if (! WebPAnimDecoderGetInfo (dec, &anim_info)) + { + g_set_error (error, G_FILE_ERROR, 0, + _("Failed to decode animated WebP information from '%s'"), + gimp_filename_to_utf8 (filename)); + goto error; + } + + demux = WebPDemux (&wp_data); + if (! demux || ! WebPDemuxGetFrame (demux, 1, &iter)) + goto error; + + /* Attempt to decode the data as a WebP animation image */ + while (WebPAnimDecoderHasMoreFrames (dec)) + { + uint8_t *outdata; + int timestamp; + gchar *name; + + if (! WebPAnimDecoderGetNext (dec, &outdata, ×tamp)) + { + g_set_error (error, G_FILE_ERROR, 0, + _("Failed to decode animated WebP frame from '%s'"), + gimp_filename_to_utf8 (filename)); + goto error; + } + + name = g_strdup_printf (_("Frame %d (%dms)"), frame_num, iter.duration); + create_layer (image_ID, outdata, 0, name, width, height); + g_free (name); + + frame_num++; + WebPDemuxNextFrame (&iter); + } + + WebPAnimDecoderDelete (dec); + WebPDemuxReleaseIterator (&iter); + WebPDemuxDelete (demux); + } + + /* Free the original compressed data */ + g_free (indata); + + if (exif || xmp) + { + GimpMetadata *metadata; + GFile *file; + + if (exif) + { + WebPData exif; + + WebPMuxGetChunk (mux, "EXIF", &exif); + } + + if (xmp) + { + WebPData xmp; + + WebPMuxGetChunk (mux, "XMP ", &xmp); + } + + file = g_file_new_for_path (filename); + metadata = gimp_image_metadata_load_prepare (image_ID, "image/webp", + file, NULL); + if (metadata) + { + GimpMetadataLoadFlags flags = GIMP_METADATA_LOAD_ALL; + + if (profile) + flags &= ~GIMP_METADATA_LOAD_COLORSPACE; + + gimp_image_metadata_load_finish (image_ID, "image/webp", + metadata, flags, + interactive); + g_object_unref (metadata); + } + + g_object_unref (file); + } + + WebPMuxDelete (mux); + + gimp_image_set_filename (image_ID, filename); + + if (profile) + g_object_unref (profile); + + return image_ID; +} diff --git a/plug-ins/file-webp/file-webp-load.h b/plug-ins/file-webp/file-webp-load.h new file mode 100644 index 0000000..9025f24 --- /dev/null +++ b/plug-ins/file-webp/file-webp-load.h @@ -0,0 +1,31 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * file-webp - WebP file format plug-in for the GIMP + * Copyright (C) 2015 Nathan Osman + * Copyright (C) 2016 Ben Touchette + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#ifndef __WEBP_LOAD_H__ +#define __WEBP_LOAD_H__ + + +gint32 load_image (const gchar *filename, + gboolean interactive, + GError **error); + + +#endif /* __WEBP_LOAD_H__ */ diff --git a/plug-ins/file-webp/file-webp-save.c b/plug-ins/file-webp/file-webp-save.c new file mode 100644 index 0000000..d3bc647 --- /dev/null +++ b/plug-ins/file-webp/file-webp-save.c @@ -0,0 +1,889 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * file-webp - WebP file format plug-in for the GIMP + * Copyright (C) 2015 Nathan Osman + * Copyright (C) 2016 Ben Touchette + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <errno.h> +#include <glib/gstdio.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> + +#include <gegl.h> + +#include <libgimp/gimp.h> +#include <libgimp/gimpui.h> + +#include <webp/encode.h> +#include <webp/mux.h> + +#include "file-webp-save.h" + +#include "libgimp/stdplugins-intl.h" + + +int webp_anim_file_writer (FILE *outfile, + const uint8_t *data, + size_t data_size); +int webp_file_writer (const uint8_t *data, + size_t data_size, + const WebPPicture *picture); +int webp_file_progress (int percent, + const WebPPicture *picture); +const gchar * webp_error_string (WebPEncodingError error_code); + +gboolean save_layer (const gchar *filename, + gint32 nLayers, + gint32 image_ID, + gint32 drawable_ID, + WebPSaveParams *params, + GError **error); + +gboolean save_animation (const gchar *filename, + gint32 nLayers, + gint32 *allLayers, + gint32 image_ID, + gint32 drawable_ID, + WebPSaveParams *params, + GError **error); + +static void webp_decide_output (gint32 image_ID, + WebPSaveParams *params, + GimpColorProfile **profile, + gboolean *out_linear); + +int +webp_anim_file_writer (FILE *outfile, + const uint8_t *data, + size_t data_size) +{ + int ok = 0; + + if (data == NULL) + return 0; + + ok = (fwrite (data, data_size, 1, outfile) == 1); + + return ok; +} + +int +webp_file_writer (const uint8_t *data, + size_t data_size, + const WebPPicture *picture) +{ + FILE *outfile; + + /* Obtain the FILE* and write the data to the file */ + outfile = (FILE *) picture->custom_ptr; + + return fwrite (data, sizeof (uint8_t), data_size, outfile) == data_size; +} + +int +webp_file_progress (int percent, + const WebPPicture *picture) +{ + return gimp_progress_update (percent / 100.0); +} + +const gchar * +webp_error_string (WebPEncodingError error_code) +{ + switch (error_code) + { + case VP8_ENC_ERROR_OUT_OF_MEMORY: + return _("out of memory"); + case VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY: + return _("not enough memory to flush bits"); + case VP8_ENC_ERROR_NULL_PARAMETER: + return _("NULL parameter"); + case VP8_ENC_ERROR_INVALID_CONFIGURATION: + return _("invalid configuration"); + case VP8_ENC_ERROR_BAD_DIMENSION: + return _("bad image dimensions"); + case VP8_ENC_ERROR_PARTITION0_OVERFLOW: + return _("partition is bigger than 512K"); + case VP8_ENC_ERROR_PARTITION_OVERFLOW: + return _("partition is bigger than 16M"); + case VP8_ENC_ERROR_BAD_WRITE: + return _("unable to flush bytes"); + case VP8_ENC_ERROR_FILE_TOO_BIG: + return _("file is larger than 4GiB"); + case VP8_ENC_ERROR_USER_ABORT: + return _("user aborted encoding"); + case VP8_ENC_ERROR_LAST: + return _("list terminator"); + default: + return _("unknown error"); + } +} + +gboolean +save_layer (const gchar *filename, + gint32 nLayers, + gint32 image_ID, + gint32 drawable_ID, + WebPSaveParams *params, + GError **error) +{ + gboolean status = FALSE; + FILE *outfile = NULL; + WebPConfig config = {0}; + WebPPicture picture = {0}; + guchar *buffer = NULL; + gint w, h; + gboolean has_alpha; + const Babl *format; + gint bpp; + GimpColorProfile *profile = NULL; + GeglBuffer *geglbuffer = NULL; + GeglRectangle extent; + gchar *indata; + gsize indatalen; + struct stat stsz; + int fd_outfile; + WebPData chunk; + gboolean out_linear = FALSE; + int res; + + webp_decide_output (image_ID, params, &profile, &out_linear); + + /* The do...while() loop is a neat little trick that makes it easier + * to jump to error handling code while still ensuring proper + * cleanup + */ + + do + { + /* Begin displaying export progress */ + gimp_progress_init_printf (_("Saving '%s'"), + gimp_filename_to_utf8(filename)); + + /* Attempt to open the output file */ + if ((outfile = g_fopen (filename, "w+b")) == NULL) + { + g_set_error (error, G_FILE_ERROR, + g_file_error_from_errno (errno), + _("Unable to open '%s' for writing: %s"), + gimp_filename_to_utf8 (filename), + g_strerror (errno)); + break; + } + + /* Obtain the drawable type */ + has_alpha = gimp_drawable_has_alpha (drawable_ID); + + if (has_alpha) + { + if (out_linear) + format = babl_format ("RGBA u8"); + else + format = babl_format ("R'G'B'A u8"); + } + else + { + if (out_linear) + format = babl_format ("RGB u8"); + else + format = babl_format ("R'G'B' u8"); + } + + bpp = babl_format_get_bytes_per_pixel (format); + + /* Retrieve the buffer for the layer */ + geglbuffer = gimp_drawable_get_buffer (drawable_ID); + extent = *gegl_buffer_get_extent (geglbuffer); + w = extent.width; + h = extent.height; + + /* Initialize the WebP configuration with a preset and fill in the + * remaining values */ + WebPConfigPreset (&config, params->preset, params->quality); + + config.lossless = params->lossless; + config.method = 6; /* better quality */ + config.alpha_quality = params->alpha_quality; + + /* Prepare the WebP structure */ + WebPPictureInit (&picture); + picture.use_argb = 1; + picture.width = w; + picture.height = h; + picture.writer = webp_file_writer; + picture.custom_ptr = outfile; + picture.progress_hook = webp_file_progress; + + /* Attempt to allocate a buffer of the appropriate size */ + buffer = g_try_malloc (w * h * bpp); + if (! buffer) + break; + + /* Read the region into the buffer */ + gegl_buffer_get (geglbuffer, &extent, 1.0, format, buffer, + GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); + + /* Use the appropriate function to import the data from the buffer */ + if (! has_alpha) + { + status = WebPPictureImportRGB (&picture, buffer, w * bpp); + } + else + { + status = WebPPictureImportRGBA (&picture, buffer, w * bpp); + } + + g_free (buffer); + if (! status) + { + g_printerr ("%s: memory error in WebPPictureImportRGB(A)().", + G_STRFUNC); + break; + } + + /* Perform the actual encode */ + if (! WebPEncode (&config, &picture)) + { + g_printerr ("WebP error: '%s'", + webp_error_string (picture.error_code)); + g_set_error (error, G_FILE_ERROR, + picture.error_code, + _("WebP error: '%s'"), + webp_error_string (picture.error_code)); + status = FALSE; + break; + } + + /* The cleanup stuff still needs to run but indicate that everything + * completed successfully + */ + status = TRUE; + + } + while (0); + + /* Flush the drawable and detach */ + if (geglbuffer) + { + g_object_unref (geglbuffer); + } + + fflush (outfile); + fd_outfile = fileno (outfile); + fstat (fd_outfile, &stsz); + indatalen = stsz.st_size; + if (indatalen > 0) + { + indata = (gchar*) g_malloc (indatalen); + rewind (outfile); + res = fread (indata, 1, indatalen, outfile); + if (res > 0) + { + WebPMux *mux; + WebPData wp_data; + + wp_data.bytes = (uint8_t*) indata; + wp_data.size = indatalen; + mux = WebPMuxCreate (&wp_data, 1); + + if (mux) + { + /* Save ICC data */ + if (profile) + { + const guint8 *icc_data; + gsize icc_data_size; + + icc_data = gimp_color_profile_get_icc_profile (profile, + &icc_data_size); + chunk.bytes = icc_data; + chunk.size = icc_data_size; + WebPMuxSetChunk(mux, "ICCP", &chunk, 1); + + WebPMuxAssemble (mux, &wp_data); + rewind (outfile); + webp_anim_file_writer (outfile, wp_data.bytes, wp_data.size); + } + + WebPMuxDelete (mux); + } + else + { + g_printerr ("ERROR: Cannot create mux. Can't save features update.\n"); + } + + WebPDataClear (&wp_data); + } + else + { + g_printerr ("ERROR: No data read for features. Can't save features update.\n"); + } + } + else + { + g_printerr ("ERROR: No data for features. Can't save features update.\n"); + } + + /* Free any resources */ + if (outfile) + fclose (outfile); + + WebPPictureFree (&picture); + g_clear_object (&profile); + + return status; +} + +static gint +parse_ms_tag (const gchar *str) +{ + gint sum = 0; + gint offset = 0; + gint length; + + length = strlen (str); + + find_another_bra: + + while ((offset < length) && (str[offset] != '(')) + offset++; + + if (offset >= length) + return -1; + + if (! g_ascii_isdigit (str[++offset])) + goto find_another_bra; + + do + { + sum *= 10; + sum += str[offset] - '0'; + offset++; + } + while ((offset < length) && (g_ascii_isdigit (str[offset]))); + + if (length - offset <= 2) + return -3; + + if ((g_ascii_toupper (str[offset]) != 'M') || + (g_ascii_toupper (str[offset + 1]) != 'S')) + return -4; + + return sum; +} + +static gint +get_layer_delay (gint32 layer) +{ + gchar *layer_name; + gint delay_ms; + + layer_name = gimp_item_get_name (layer); + delay_ms = parse_ms_tag (layer_name); + g_free (layer_name); + + return delay_ms; +} + +static gboolean +parse_combine (const char* str) +{ + gint offset = 0; + gint length = strlen (str); + + while ((offset + 9) <= length) + { + if (strncmp (&str[offset], "(combine)", 9) == 0) + return TRUE; + + if (strncmp (&str[offset], "(replace)", 9) == 0) + return FALSE; + + offset++; + } + + return FALSE; +} + +static gint +get_layer_needs_combine (gint32 layer) +{ + gchar *layer_name; + gboolean needs_combine; + + layer_name = gimp_item_get_name (layer); + needs_combine = parse_combine (layer_name); + g_free (layer_name); + + return needs_combine; +} + +static GeglBuffer* +combine_buffers (GeglBuffer *layer_buffer, + GeglBuffer *prev_frame_buffer) +{ + GeglBuffer *buffer; + GeglNode *graph; + GeglNode *source; + GeglNode *backdrop; + GeglNode *over; + GeglNode *target; + + graph = gegl_node_new (); + buffer = gegl_buffer_new (gegl_buffer_get_extent (prev_frame_buffer), + gegl_buffer_get_format (prev_frame_buffer)); + + source = gegl_node_new_child (graph, + "operation", "gegl:buffer-source", + "buffer", layer_buffer, + NULL); + backdrop = gegl_node_new_child (graph, + "operation", "gegl:buffer-source", + "buffer", prev_frame_buffer, + NULL); + + over = gegl_node_new_child (graph, + "operation", "gegl:over", + NULL); + target = gegl_node_new_child (graph, + "operation", "gegl:write-buffer", + "buffer", buffer, + NULL); + gegl_node_link_many (backdrop, over, target, NULL); + gegl_node_connect_to (source, "output", + over, "aux"); + gegl_node_process (target); + g_object_unref (graph); + + return buffer; +} + +gboolean +save_animation (const gchar *filename, + gint32 nLayers, + gint32 *allLayers, + gint32 image_ID, + gint32 drawable_ID, + WebPSaveParams *params, + GError **error) +{ + gboolean status = TRUE; + FILE *outfile = NULL; + guchar *buffer = NULL; + gint buffer_size = 0; + gint w, h; + gint bpp; + gboolean has_alpha; + const Babl *format; + GimpColorProfile *profile = NULL; + WebPAnimEncoderOptions enc_options; + WebPData webp_data; + int frame_timestamp = 0; + WebPAnimEncoder *enc = NULL; + GeglBuffer *prev_frame = NULL; + gboolean out_linear = FALSE; + + if (nLayers < 1) + return FALSE; + + webp_decide_output (image_ID, params, &profile, &out_linear); + + gimp_image_undo_freeze (image_ID); + + WebPDataInit (&webp_data); + + do + { + gint loop; + gint default_delay = params->delay; + gboolean force_delay = params->force_delay; + + /* Begin displaying export progress */ + gimp_progress_init_printf (_("Saving '%s'"), + gimp_filename_to_utf8 (filename)); + + /* Attempt to open the output file */ + if ((outfile = g_fopen (filename, "wb")) == NULL) + { + g_set_error (error, G_FILE_ERROR, + g_file_error_from_errno (errno), + _("Unable to open '%s' for writing: %s"), + gimp_filename_to_utf8 (filename), + g_strerror (errno)); + status = FALSE; + break; + } + + if (! WebPAnimEncoderOptionsInit (&enc_options)) + { + g_printerr ("ERROR: version mismatch\n"); + status = FALSE; + break; + } + + enc_options.anim_params.loop_count = 0; + if (! params->loop) + enc_options.anim_params.loop_count = 1; + + enc_options.allow_mixed = params->lossless ? 0 : 1; + enc_options.minimize_size = params->minimize_size ? 1 : 0; + if (! params->minimize_size) + { + enc_options.kmax = params->kf_distance; + /* explicitly force minimum key-frame distance too, for good measure */ + enc_options.kmin = params->kf_distance - 1; + } + + for (loop = 0; loop < nLayers; loop++) + { + GeglBuffer *geglbuffer; + GeglBuffer *current_frame; + GeglRectangle extent; + WebPConfig config; + WebPPicture picture; + WebPMemoryWriter mw = { 0 }; + gint32 drawable = allLayers[nLayers - 1 - loop]; + gint delay = get_layer_delay (drawable); + gboolean needs_combine = get_layer_needs_combine (drawable); + + /* Obtain the drawable type */ + has_alpha = gimp_drawable_has_alpha (drawable); + + if (has_alpha) + { + if (out_linear) + format = babl_format ("RGBA u8"); + else + format = babl_format ("R'G'B'A u8"); + } + else + { + if (out_linear) + format = babl_format ("RGB u8"); + else + format = babl_format ("R'G'B' u8"); + } + + bpp = babl_format_get_bytes_per_pixel (format); + + /* fix layers to avoid offset errors */ + gimp_layer_resize_to_image_size (drawable); + + /* Retrieve the buffer for the layer */ + geglbuffer = gimp_drawable_get_buffer (drawable); + extent = *gegl_buffer_get_extent (geglbuffer); + w = extent.width; + h = extent.height; + + if (loop == 0) + { + enc = WebPAnimEncoderNew (w, h, &enc_options); + if (! enc) + { + g_printerr ("ERROR: enc == null\n"); + status = FALSE; + break; + } + } + + /* Attempt to allocate a buffer of the appropriate size */ + if (! buffer || buffer_size < w * h * bpp) + { + buffer = g_try_realloc (buffer, w * h * bpp); + + if (! buffer) + { + g_printerr ("Buffer error: 'buffer null'\n"); + status = FALSE; + break; + } + else + { + buffer_size = w * h * bpp; + } + } + + WebPConfigPreset (&config, params->preset, params->quality); + + config.lossless = params->lossless; + config.method = 6; /* better quality */ + config.alpha_quality = params->alpha_quality; + config.exact = 1; + + WebPMemoryWriterInit (&mw); + + /* Prepare the WebP structure */ + WebPPictureInit (&picture); + picture.use_argb = 1; + picture.argb_stride = w * bpp; + picture.width = w; + picture.height = h; + picture.custom_ptr = &mw; + picture.writer = WebPMemoryWrite; + + if (loop == 0 || ! needs_combine) + { + g_clear_object (&prev_frame); + current_frame = geglbuffer; + } + else + { + current_frame = combine_buffers (geglbuffer, prev_frame); + + /* release resources. */ + g_object_unref (geglbuffer); + g_clear_object (&prev_frame); + } + prev_frame = current_frame; + + /* Read the region into the buffer */ + gegl_buffer_get (current_frame, &extent, 1.0, format, buffer, + GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); + + /* Use the appropriate function to import the data from the buffer */ + if (! has_alpha) + { + status = WebPPictureImportRGB (&picture, buffer, w * bpp); + } + else + { + status = WebPPictureImportRGBA (&picture, buffer, w * bpp); + } + + if (! status) + { + g_printerr ("%s: memory error in WebPPictureImportRGB(A)().", + G_STRFUNC); + } + /* Perform the actual encode */ + else if (! WebPAnimEncoderAdd (enc, &picture, frame_timestamp, &config)) + { + g_printerr ("ERROR[%d]: %s\n", + picture.error_code, + webp_error_string (picture.error_code)); + status = FALSE; + } + + WebPMemoryWriterClear (&mw); + WebPPictureFree (&picture); + + if (status == FALSE) + break; + + gimp_progress_update ((loop + 1.0) / nLayers); + frame_timestamp += (delay <= 0 || force_delay) ? default_delay : delay; + } + g_free (buffer); + + if (status == FALSE) + break; + + WebPAnimEncoderAdd (enc, NULL, frame_timestamp, NULL); + + if (! WebPAnimEncoderAssemble (enc, &webp_data)) + { + g_printerr ("ERROR: %s\n", + WebPAnimEncoderGetError (enc)); + status = FALSE; + break; + } + + /* Create a mux object if profile is present */ + if (profile) + { + WebPMux *mux; + WebPData chunk; + const guint8 *icc_data; + gsize icc_data_size; + + mux = WebPMuxCreate (&webp_data, 1); + if (mux == NULL) + { + g_printerr ("ERROR: could not extract muxing object\n"); + status = FALSE; + break; + } + + /* Save ICC data */ + icc_data = gimp_color_profile_get_icc_profile (profile, &icc_data_size); + chunk.bytes = icc_data; + chunk.size = icc_data_size; + WebPMuxSetChunk (mux, "ICCP", &chunk, 1); + + WebPDataClear (&webp_data); + if (WebPMuxAssemble (mux, &webp_data) != WEBP_MUX_OK) + { + g_printerr ("ERROR: could not assemble final bytestream\n"); + status = FALSE; + break; + } + } + + webp_anim_file_writer (outfile, webp_data.bytes, webp_data.size); + } + while (0); + + /* Free any resources */ + WebPDataClear (&webp_data); + WebPAnimEncoderDelete (enc); + g_clear_object (&profile); + + if (prev_frame != NULL) + { + g_object_unref (prev_frame); + } + + if (outfile) + fclose (outfile); + + return status; +} + + +gboolean +save_image (const gchar *filename, + gint32 image_ID, + gint32 drawable_ID, + GimpMetadata *metadata, + GimpMetadataSaveFlags metadata_flags, + WebPSaveParams *params, + GError **error) +{ + GFile *file; + gboolean status = FALSE; + gint32 *layers; + gint nlayers; + + layers = gimp_image_get_layers (image_ID, &nlayers); + + if (nlayers == 0) + { + g_free (layers); + return FALSE; + } + + g_printerr ("Saving WebP file %s\n", filename); + + if (params->animation) + { + status = save_animation (filename, + nlayers, layers, image_ID, drawable_ID, params, + error); + } + else + { + status = save_layer (filename, + nlayers, image_ID, drawable_ID, params, error); + } + + g_free (layers); + + if (metadata) + { + gimp_metadata_set_bits_per_sample (metadata, 8); + + if (params->exif) + metadata_flags |= GIMP_METADATA_SAVE_EXIF; + else + metadata_flags &= ~GIMP_METADATA_SAVE_EXIF; + + /* WebP doesn't support iptc natively and + sets it via xmp */ + if (params->xmp) + { + metadata_flags |= GIMP_METADATA_SAVE_XMP; + metadata_flags |= GIMP_METADATA_SAVE_IPTC; + } + else + { + metadata_flags &= ~GIMP_METADATA_SAVE_XMP; + metadata_flags &= ~GIMP_METADATA_SAVE_IPTC; + } + + if (params->profile) + metadata_flags |= GIMP_METADATA_SAVE_COLOR_PROFILE; + else + metadata_flags &= ~GIMP_METADATA_SAVE_COLOR_PROFILE; + + file = g_file_new_for_path (filename); + gimp_image_metadata_save_finish (image_ID, + "image/webp", + metadata, metadata_flags, + file, NULL); + g_object_unref (file); + } + + /* Return the status */ + return status; +} + +static void +webp_decide_output (gint32 image_ID, + WebPSaveParams *params, + GimpColorProfile **profile, + gboolean *out_linear) +{ + g_return_if_fail (profile && *profile == NULL); + + *out_linear = FALSE; + if (params->profile) + { + *profile = gimp_image_get_color_profile (image_ID); + + /* If a profile is explicitly set, follow its TRC, whatever the + * storage format. + */ + if (*profile && gimp_color_profile_is_linear (*profile)) + *out_linear = TRUE; + + /* When no profile was explicitly set, since WebP is apparently + * 8-bit max, we export it as sRGB to avoid shadow posterization + * (we don't care about storage TRC). + * We do an exception for 8-bit linear work image to avoid + * conversion loss while the precision is the same. + */ + if (! *profile) + { + /* There is always an effective profile. */ + *profile = gimp_image_get_effective_color_profile (image_ID); + + if (gimp_color_profile_is_linear (*profile)) + { + if (gimp_image_get_precision (image_ID) != GIMP_PRECISION_U8_LINEAR) + { + /* If stored data was linear, let's convert the profile. */ + GimpColorProfile *saved_profile; + + saved_profile = gimp_color_profile_new_srgb_trc_from_color_profile (*profile); + g_clear_object (profile); + *profile = saved_profile; + } + else + { + /* Keep linear profile as-is for 8-bit linear image. */ + *out_linear = TRUE; + } + } + } + } +} diff --git a/plug-ins/file-webp/file-webp-save.h b/plug-ins/file-webp/file-webp-save.h new file mode 100644 index 0000000..3d4b425 --- /dev/null +++ b/plug-ins/file-webp/file-webp-save.h @@ -0,0 +1,54 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * file-webp - WebP file format plug-in for the GIMP + * Copyright (C) 2015 Nathan Osman + * Copyright (C) 2016 Ben Touchette + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#ifndef __WEBP_SAVE_H__ +#define __WEBP_SAVE_H__ + + +typedef struct +{ + WebPPreset preset; + gboolean lossless; + gboolean animation; + gboolean loop; + gboolean minimize_size; + gint kf_distance; + gfloat quality; + gfloat alpha_quality; + gboolean exif; + gboolean iptc; + gboolean xmp; + gboolean profile; + gint delay; + gboolean force_delay; +} WebPSaveParams; + + +gboolean save_image (const gchar *filename, + gint32 image_ID, + gint32 drawable_ID, + GimpMetadata *metadata, + GimpMetadataSaveFlags metadata_flags, + WebPSaveParams *params, + GError **error); + + +#endif /* __WEBP_SAVE_H__ */ diff --git a/plug-ins/file-webp/file-webp.c b/plug-ins/file-webp/file-webp.c new file mode 100644 index 0000000..a734c92 --- /dev/null +++ b/plug-ins/file-webp/file-webp.c @@ -0,0 +1,320 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * file-webp - WebP file format plug-in for the GIMP + * Copyright (C) 2015 Nathan Osman + * Copyright (C) 2016 Ben Touchette + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <string.h> + +#include <libgimp/gimp.h> +#include <libgimp/gimpui.h> + +#include <webp/encode.h> + +#include "file-webp-dialog.h" +#include "file-webp-load.h" +#include "file-webp-save.h" +#include "file-webp.h" + +#include "libgimp/stdplugins-intl.h" + + +static void query (void); +static void run (const gchar *name, + gint nparams, + const GimpParam *param, + gint *nreturn_vals, + GimpParam **return_vals); + + +const GimpPlugInInfo PLUG_IN_INFO = +{ + NULL, + NULL, + query, + run +}; + + +MAIN() + +static void +query (void) +{ + static const GimpParamDef load_arguments[] = + { + { GIMP_PDB_INT32, "run-mode", "Interactive, non-interactive" }, + { GIMP_PDB_STRING, "filename", "The name of the file to load" }, + { GIMP_PDB_STRING, "raw-filename", "The name entered" } + }; + + static const GimpParamDef load_return_values[] = + { + { GIMP_PDB_IMAGE, "image", "Output image" } + }; + + static const GimpParamDef save_arguments[] = + { + { GIMP_PDB_INT32, "run-mode", "Interactive, non-interactive" }, + { GIMP_PDB_IMAGE, "image", "Input image" }, + { GIMP_PDB_DRAWABLE, "drawable", "Drawable to save" }, + { GIMP_PDB_STRING, "filename", "The name of the file to save the image to" }, + { GIMP_PDB_STRING, "raw-filename", "The name entered" }, + { GIMP_PDB_INT32, "preset", "preset (Default=0, Picture=1, Photo=2, Drawing=3, Icon=4, Text=5)" }, + { GIMP_PDB_INT32, "lossless", "Use lossless encoding (0/1)" }, + { GIMP_PDB_FLOAT, "quality", "Quality of the image (0 <= quality <= 100)" }, + { GIMP_PDB_FLOAT, "alpha-quality", "Quality of the image's alpha channel (0 <= alpha-quality <= 100)" }, + { GIMP_PDB_INT32, "animation", "Use layers for animation (0/1)" }, + { GIMP_PDB_INT32, "anim-loop", "Loop animation infinitely (0/1)" }, + { GIMP_PDB_INT32, "minimize-size", "Minimize animation size (0/1)" }, + { GIMP_PDB_INT32, "kf-distance", "Maximum distance between key-frames (>=0)" }, + { GIMP_PDB_INT32, "exif", "Toggle saving exif data (0/1)" }, + { GIMP_PDB_INT32, "iptc", "Toggle saving iptc data (0/1)" }, + { GIMP_PDB_INT32, "xmp", "Toggle saving xmp data (0/1)" }, + { GIMP_PDB_INT32, "delay", "Delay to use when timestamps are not available or forced" }, + { GIMP_PDB_INT32, "force-delay", "Force delay on all frames" } + }; + + gimp_install_procedure (LOAD_PROC, + "Loads images in the WebP file format", + "Loads images in the WebP file format", + "Nathan Osman, Ben Touchette", + "(C) 2015-2016 Nathan Osman, (C) 2016 Ben Touchette", + "2015,2016", + N_("WebP image"), + NULL, + GIMP_PLUGIN, + G_N_ELEMENTS (load_arguments), + G_N_ELEMENTS (load_return_values), + load_arguments, + load_return_values); + + gimp_register_file_handler_mime (LOAD_PROC, "image/webp"); + gimp_register_load_handler (LOAD_PROC, "webp", ""); + gimp_register_magic_load_handler (LOAD_PROC, + "webp", + "", + "8,string,WEBP"); + + gimp_install_procedure (SAVE_PROC, + "Saves files in the WebP image format", + "Saves files in the WebP image format", + "Nathan Osman, Ben Touchette", + "(C) 2015-2016 Nathan Osman, (C) 2016 Ben Touchette", + "2015,2016", + N_("WebP image"), + "RGB*, GRAY*, INDEXED*", + GIMP_PLUGIN, + G_N_ELEMENTS (save_arguments), + 0, + save_arguments, + NULL); + + gimp_register_file_handler_mime (SAVE_PROC, "image/webp"); + gimp_register_save_handler (SAVE_PROC, "webp", ""); +} + +static void +run (const gchar *name, + gint nparams, + const GimpParam *param, + gint *nreturn_vals, + GimpParam **return_vals) +{ + static GimpParam values[2]; + GimpRunMode run_mode; + GimpPDBStatusType status = GIMP_PDB_SUCCESS; + gint32 image_ID; + gint32 drawable_ID; + GError *error = NULL; + + INIT_I18N (); + gegl_init (NULL, NULL); + + run_mode = param[0].data.d_int32; + + *nreturn_vals = 1; + *return_vals = values; + + values[0].type = GIMP_PDB_STATUS; + values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR; + + if (! strcmp (name, LOAD_PROC)) + { + image_ID = load_image (param[1].data.d_string, FALSE, &error); + + if (image_ID != -1) + { + /* Return the new image that was loaded */ + *nreturn_vals = 2; + values[1].type = GIMP_PDB_IMAGE; + values[1].data.d_image = image_ID; + } + else + { + status = GIMP_PDB_EXECUTION_ERROR; + } + } + else if (! strcmp (name, SAVE_PROC)) + { + GimpMetadata *metadata = NULL; + GimpMetadataSaveFlags metadata_flags; + WebPSaveParams params; + GimpExportReturn export = GIMP_EXPORT_CANCEL; + + if (run_mode == GIMP_RUN_INTERACTIVE || + run_mode == GIMP_RUN_WITH_LAST_VALS) + gimp_ui_init (PLUG_IN_BINARY, FALSE); + + image_ID = param[1].data.d_int32; + drawable_ID = param[2].data.d_int32; + + /* Default settings */ + params.preset = WEBP_PRESET_DEFAULT; + params.lossless = FALSE; + params.animation = FALSE; + params.loop = TRUE; + params.minimize_size = TRUE; + params.kf_distance = 50; + params.quality = 90.0f; + params.alpha_quality = 100.0f; + params.exif = FALSE; + params.iptc = FALSE; + params.xmp = FALSE; + params.delay = 200; + params.force_delay = FALSE; + + /* Override the defaults with preferences. */ + metadata = gimp_image_metadata_save_prepare (image_ID, + "image/webp", + &metadata_flags); + params.exif = (metadata_flags & GIMP_METADATA_SAVE_EXIF) != 0; + params.xmp = (metadata_flags & GIMP_METADATA_SAVE_XMP) != 0; + params.iptc = (metadata_flags & GIMP_METADATA_SAVE_IPTC) != 0; + params.profile = (metadata_flags & GIMP_METADATA_SAVE_COLOR_PROFILE) != 0; + + switch (run_mode) + { + case GIMP_RUN_WITH_LAST_VALS: + /* Possibly override with session data */ + gimp_get_data (SAVE_PROC, ¶ms); + break; + + case GIMP_RUN_INTERACTIVE: + /* Possibly override with session data */ + gimp_get_data (SAVE_PROC, ¶ms); + + if (! save_dialog (¶ms, image_ID)) + { + status = GIMP_PDB_CANCEL; + } + break; + + case GIMP_RUN_NONINTERACTIVE: + if (nparams != 18) + { + status = GIMP_PDB_CALLING_ERROR; + } + else + { + if (param[5].data.d_int32 < WEBP_PRESET_DEFAULT || + param[5].data.d_int32 > WEBP_PRESET_TEXT) + params.preset = WEBP_PRESET_DEFAULT; + else + params.preset = param[5].data.d_int32; + + params.lossless = param[6].data.d_int32; + params.quality = param[7].data.d_float; + params.alpha_quality = param[8].data.d_float; + params.animation = param[9].data.d_int32; + params.loop = param[10].data.d_int32; + params.minimize_size = param[11].data.d_int32; + params.kf_distance = param[12].data.d_int32; + params.exif = param[13].data.d_int32; + params.iptc = param[14].data.d_int32; + params.xmp = param[15].data.d_int32; + params.delay = param[16].data.d_int32; + params.force_delay = param[17].data.d_int32; + } + break; + + default: + break; + } + + if (status == GIMP_PDB_SUCCESS && (run_mode == GIMP_RUN_INTERACTIVE || + run_mode == GIMP_RUN_WITH_LAST_VALS)) + { + GimpExportCapabilities capabilities = + GIMP_EXPORT_CAN_HANDLE_RGB | + GIMP_EXPORT_CAN_HANDLE_GRAY | + GIMP_EXPORT_CAN_HANDLE_INDEXED | + GIMP_EXPORT_CAN_HANDLE_ALPHA; + + if (params.animation) + capabilities |= GIMP_EXPORT_CAN_HANDLE_LAYERS_AS_ANIMATION; + + export = gimp_export_image (&image_ID, &drawable_ID, "WebP", + capabilities); + + if (export == GIMP_EXPORT_CANCEL) + { + values[0].data.d_status = GIMP_PDB_CANCEL; + status = GIMP_PDB_CANCEL; + } + } + + if (status == GIMP_PDB_SUCCESS) + { + if (! save_image (param[3].data.d_string, + image_ID, + drawable_ID, + metadata, metadata_flags, + ¶ms, + &error)) + { + status = GIMP_PDB_EXECUTION_ERROR; + } + } + + + if (export == GIMP_EXPORT_EXPORT) + gimp_image_delete (image_ID); + + if (metadata) + g_object_unref (metadata); + + if (status == GIMP_PDB_SUCCESS) + { + /* save parameters for later */ + gimp_set_data (SAVE_PROC, ¶ms, sizeof (params)); + } + } + + /* If an error was supplied, include it in the return values */ + if (status != GIMP_PDB_SUCCESS && error) + { + *nreturn_vals = 2; + values[1].type = GIMP_PDB_STRING; + values[1].data.d_string = error->message; + } + + values[0].data.d_status = status; +} diff --git a/plug-ins/file-webp/file-webp.h b/plug-ins/file-webp/file-webp.h new file mode 100644 index 0000000..a64ff96 --- /dev/null +++ b/plug-ins/file-webp/file-webp.h @@ -0,0 +1,32 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * file-webp - WebP file format plug-in for the GIMP + * Copyright (C) 2015 Nathan Osman + * Copyright (C) 2016 Ben Touchette + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#ifndef __FILE_WEBP_H__ +#define __FILE_WEBP_H__ + + +#define LOAD_PROC "file-webp-load" +#define SAVE_PROC "file-webp-save" +#define PLUG_IN_BINARY "file-webp" +#define PLUG_IN_ROLE "gimp-file-webp" + + +#endif /* __FILE_WEBP_H__ */ |